Package com.bj58.argo.thirdparty.jetty

Source Code of com.bj58.argo.thirdparty.jetty.JettyMultiPartRequestWrapper

/*
*  Copyright Beijing 58 Information Technology Co.,Ltd.
*
*  Licensed to the Apache Software Foundation (ASF) under one
*  or more contributor license agreements.  See the NOTICE file
*  distributed with this work for additional information
*  regarding copyright ownership.  The ASF licenses this file
*  to you under the Apache License, Version 2.0 (the
*  "License"); you may not use this file except in compliance
*  with the License.  You may obtain a copy of the License at
*
*        http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing,
*  software distributed under the License is distributed on an
*  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
*  KIND, either express or implied.  See the License for the
*  specific language governing permissions and limitations
*  under the License.
*/
package com.bj58.argo.thirdparty.jetty;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.Part;
import java.io.*;
import java.util.*;

/**
* source: org.eclipse.jetty.servlets.MultiPartFilter
* Multipart Form Data Filter.
* <p>
* This class decodes the multipart/form-data stream sent by a HTML form that uses a file input
* item.  Any files sent are stored to a temporary file and a File object added to the request
* as an attribute.  All other values are made available via the normal getParameter API and
* the setCharacterEncoding mechanism is respected when converting bytes to Strings.
* <p>
* If the init parameter "delete" is set to "true", any files created will be deleted when the
* current request returns.
* <p>
* The init parameter maxFormKeys sets the maximum number of keys that may be present in a
* form (default set by system property org.eclipse.jetty.server.Request.maxFormKeys or 1000) to protect
* against DOS attacks by bad hash keys.
* <p>
* The init parameter deleteFiles controls if uploaded files are automatically deleted after the request
* completes.
*
* Use init parameter "maxFileSize" to set the max size file that can be uploaded.
*
* Use init parameter "maxRequestSize" to limit the size of the multipart request.
*
*/
public class JettyMultiPartRequestWrapper {

    public final static String CONTENT_TYPE_SUFFIX=".org.eclipse.jetty.servlet.contentType";
    private final static String MULTIPART = "org.eclipse.jetty.servlet.MultiPartFile.multiPartInputStream";


    private File tempdir;
    private boolean _deleteFiles;
    private ServletContext _context;
    private int _fileOutputBuffer = 0;
    private long _maxFileSize = -1L;
    private long _maxRequestSize = -1L;
    private int _maxFormKeys = Integer.getInteger("org.eclipse.jetty.server.Request.maxFormKeys", 1000);


    public final static String __UTF8="UTF-8";

    public static int bufferSize = 64*1024;



    public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)
            throws IOException, ServletException
    {
        HttpServletRequest srequest=(HttpServletRequest)request;

        // guard clause
        if(srequest.getContentType()==null||!srequest.getContentType().startsWith("multipart/form-data"))
        {
            return;
        }

        InputStream in = new BufferedInputStream(request.getInputStream());
        String content_type=srequest.getContentType();

        //Get current parameters so we can merge into them
        MultiMap params = new MultiMap();
        for (Map.Entry<String, String[]> entry : request.getParameterMap().entrySet())
        {
            Object value = entry.getValue();
            if (value instanceof String[])
                params.addValues(entry.getKey(), (String[])value);
            else
                params.add(entry.getKey(), value);
        }

        MultipartConfigElement config = new MultipartConfigElement(tempdir.getCanonicalPath(), _maxFileSize, _maxRequestSize, _fileOutputBuffer);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(in, content_type, config, tempdir);
        mpis.setDeleteOnExit(_deleteFiles);
        request.setAttribute(MULTIPART, mpis);
        try
        {
            Collection<Part> parts = mpis.getParts();
            if (parts != null)
            {
                Iterator<Part> itor = parts.iterator();
                while (itor.hasNext() && params.size() < _maxFormKeys)
                {
                    Part p = itor.next();
                    MultiPartInputStreamParser.MultiPart mp = (MultiPartInputStreamParser.MultiPart)p;
                    if (mp.getFile() != null)
                    {
                        request.setAttribute(mp.getName(),mp.getFile());
                        if (mp.getContentDispositionFilename() != null)
                        {
                            params.add(mp.getName(), mp.getContentDispositionFilename());
                            if (mp.getContentType() != null)
                                params.add(mp.getName()+CONTENT_TYPE_SUFFIX, mp.getContentType());
                        }
                    }
                    else
                    {
                        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
                        IoCopy(p.getInputStream(), bytes);
                        params.add(p.getName(), bytes.toByteArray());
                        if (p.getContentType() != null)
                            params.add(p.getName()+CONTENT_TYPE_SUFFIX, p.getContentType());
                    }
                }
            }

            // handle request
            chain.doFilter(new Wrapper(srequest,params),response);
        }
        finally
        {
            deleteFiles(request);
        }
    }

    private void deleteFiles(ServletRequest request)
    {
        if (!_deleteFiles)
            return;

        MultiPartInputStreamParser mpis = (MultiPartInputStreamParser)request.getAttribute(MULTIPART);
        if (mpis != null)
        {
            try
            {
                mpis.deleteParts();
            }
            catch (Exception e)
            {
                _context.log("Error deleting multipart tmp files", e);
            }
        }
        request.removeAttribute(MULTIPART);
    }

        /* ------------------------------------------------------------------- */
    /** Copy Stream in to Stream out until EOF or exception.
     */
    public static void IoCopy(InputStream in, OutputStream out)
            throws IOException
    {
        IoCopy(in, out, -1);
    }

        /* ------------------------------------------------------------------- */
    /** Copy Stream in to Stream for byteCount bytes or until EOF or exception.
     */
    public static void IoCopy(InputStream in,
                            OutputStream out,
                            long byteCount)
            throws IOException
    {
        byte buffer[] = new byte[bufferSize];
        int len=bufferSize;

        if (byteCount>=0)
        {
            while (byteCount>0)
            {
                int max = byteCount<bufferSize?(int)byteCount:bufferSize;
                len=in.read(buffer,0,max);

                if (len==-1)
                    break;

                byteCount -= len;
                out.write(buffer,0,len);
            }
        }
        else
        {
            while (true)
            {
                len=in.read(buffer,0,bufferSize);
                if (len<0 )
                    break;
                out.write(buffer,0,len);
            }
        }
    }

    /* ------------------------------------------------------------------------------- */
    /* ------------------------------------------------------------------------------- */
    private static class Wrapper extends HttpServletRequestWrapper
    {
        String _encoding=__UTF8;
        MultiMap<Object> _params;

        /* ------------------------------------------------------------------------------- */
        /** Constructor.
         * @param request
         */
        public Wrapper(HttpServletRequest request, MultiMap map)
        {
            super(request);
            this._params=map;
        }

        /* ------------------------------------------------------------------------------- */
        /**
         * @see javax.servlet.ServletRequest#getContentLength()
         */
        @Override
        public int getContentLength()
        {
            return 0;
        }

        /* ------------------------------------------------------------------------------- */
        /**
         * @see javax.servlet.ServletRequest#getParameter(java.lang.String)
         */
        @Override
        public String getParameter(String name)
        {
            Object o=_params.get(name);
            if (!(o instanceof byte[]) && LazyList.size(o)>0)
                o=LazyList.get(o,0);

            if (o instanceof byte[])
            {
                try
                {
                    return new String((byte[])o,_encoding);
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
            }
            else if (o!=null)
                return String.valueOf(o);
            return null;
        }

        /* ------------------------------------------------------------------------------- */
        /**
         * @see javax.servlet.ServletRequest#getParameterMap()
         */
        @Override
        public Map<String, String[]> getParameterMap()
        {
            Map<String, String[]> cmap = new HashMap<String,String[]>();

            for ( Object key : _params.keySet() )
            {
                String[] a = LazyList.toStringArray(getParameter((String)key));
                cmap.put((String)key,a);

            }

            return Collections.unmodifiableMap(cmap);
        }

        /* ------------------------------------------------------------------------------- */
        /**
         * @see javax.servlet.ServletRequest#getParameterNames()
         */
        @Override
        public Enumeration<String> getParameterNames()
        {
            return Collections.enumeration(_params.keySet());
        }

        /* ------------------------------------------------------------------------------- */
        /**
         * @see javax.servlet.ServletRequest#getParameterValues(java.lang.String)
         */
        @Override
        public String[] getParameterValues(String name)
        {
            List l=_params.getValues(name);
            if (l==null || l.size()==0)
                return new String[0];
            String[] v = new String[l.size()];
            for (int i=0;i<l.size();i++)
            {
                Object o=l.get(i);
                if (o instanceof byte[])
                {
                    try
                    {
                        v[i]=new String((byte[])o,_encoding);
                    }
                    catch(Exception e)
                    {
                        throw new RuntimeException(e);
                    }
                }
                else if (o instanceof String)
                    v[i]=(String)o;
            }
            return v;
        }

        /* ------------------------------------------------------------------------------- */
        /**
         * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String)
         */
        @Override
        public void setCharacterEncoding(String enc)
                throws UnsupportedEncodingException
        {
            _encoding=enc;
        }
    }
}
TOP

Related Classes of com.bj58.argo.thirdparty.jetty.JettyMultiPartRequestWrapper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.