View Javadoc
1   /*
2    * Copyright (c) 2002-2014, Mairie de Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.util.http;
35  
36  import fr.paris.lutece.portal.service.html.EncodingService;
37  import fr.paris.lutece.portal.web.upload.MultipartHttpServletRequest;
38  import fr.paris.lutece.portal.web.upload.NormalizeFileItem;
39  
40  import org.apache.commons.fileupload.FileItem;
41  import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
42  import org.apache.commons.fileupload.FileUploadException;
43  import org.apache.commons.fileupload.disk.DiskFileItemFactory;
44  import org.apache.commons.fileupload.servlet.ServletFileUpload;
45  import org.apache.commons.lang.StringUtils;
46  
47  import java.io.UnsupportedEncodingException;
48  
49  import java.util.ArrayList;
50  import java.util.HashMap;
51  import java.util.List;
52  import java.util.Map;
53  
54  import javax.servlet.http.HttpServletRequest;
55  
56  
57  /**
58   *
59   * MultipartUtil
60   *
61   */
62  public final class MultipartUtil
63  {
64      /**
65       * Private constructor
66       */
67      private MultipartUtil(  )
68      {
69      }
70  
71      /**
72       * Check if the given HTTP request has multipart content
73       * @param request the HTTP request
74       * @return true if it has multipart content, false otherwise
75       */
76      public static boolean isMultipart( HttpServletRequest request )
77      {
78          return ServletFileUpload.isMultipartContent( request );
79      }
80  
81      /**
82       * Convert a HTTP request to a {@link MultipartHttpServletRequest}
83       * @param nSizeThreshold the size threshold
84       * @param nRequestSizeMax the request size max
85       * @param bActivateNormalizeFileName true if the file name must be normalized, false otherwise
86       * @param request the HTTP request
87       * @return a {@link MultipartHttpServletRequest}, null if the request does not have a multipart content
88       * @throws SizeLimitExceededException exception if the file size is too big
89       * @throws FileUploadException exception if an unknown error has occurred
90       */
91      public static MultipartHttpServletRequest convert( int nSizeThreshold, long nRequestSizeMax,
92          boolean bActivateNormalizeFileName, HttpServletRequest request )
93          throws SizeLimitExceededException, FileUploadException
94      {
95          if ( isMultipart( request ) )
96          {
97              // Create a factory for disk-based file items
98              DiskFileItemFactory factory = new DiskFileItemFactory(  );
99  
100             // Set factory constraints
101             factory.setSizeThreshold( nSizeThreshold );
102 
103             // Create a new file upload handler
104             ServletFileUpload upload = new ServletFileUpload( factory );
105 
106             // Set overall request size constraint
107             upload.setSizeMax( nRequestSizeMax );
108 
109             // get encoding to be used
110             String strEncoding = request.getCharacterEncoding(  );
111 
112             if ( strEncoding == null )
113             {
114                 strEncoding = EncodingService.getEncoding(  );
115             }
116 
117             Map<String, List<FileItem>> mapFiles = new HashMap<String, List<FileItem>>(  );
118             Map<String, String[]> mapParameters = new HashMap<String, String[]>(  );
119 
120             List<FileItem> listItems = upload.parseRequest( request );
121 
122             // Process the uploaded items
123             for ( FileItem item : listItems )
124             {
125                 if ( item.isFormField(  ) )
126                 {
127                     String strValue = StringUtils.EMPTY;
128 
129                     try
130                     {
131                         if ( item.getSize(  ) > 0 )
132                         {
133                             strValue = item.getString( strEncoding );
134                         }
135                     }
136                     catch ( UnsupportedEncodingException ex )
137                     {
138                         if ( item.getSize(  ) > 0 )
139                         {
140                             // if encoding problem, try with system encoding
141                             strValue = item.getString(  );
142                         }
143                     }
144 
145                     // check if item of same name already in map
146                     String[] curParam = mapParameters.get( item.getFieldName(  ) );
147 
148                     if ( curParam == null )
149                     {
150                         // simple form field
151                         mapParameters.put( item.getFieldName(  ), new String[] { strValue } );
152                     }
153                     else
154                     {
155                         // array of simple form fields
156                         String[] newArray = new String[curParam.length + 1];
157                         System.arraycopy( curParam, 0, newArray, 0, curParam.length );
158                         newArray[curParam.length] = strValue;
159                         mapParameters.put( item.getFieldName(  ), newArray );
160                     }
161                 }
162                 else
163                 {
164                     // multipart file field, if the parameter filter ActivateNormalizeFileName is set to true
165                     // all file name will be normalize
166                     FileItem fileItem = bActivateNormalizeFileName ? new NormalizeFileItem( item ) : item;
167                     List<FileItem> listFileItem = mapFiles.get( fileItem.getFieldName(  ) );
168 
169                     if ( listFileItem != null )
170                     {
171                         listFileItem.add( fileItem );
172                     }
173                     else
174                     {
175                         listFileItem = new ArrayList<FileItem>( 1 );
176                         listFileItem.add( fileItem );
177                         mapFiles.put( fileItem.getFieldName(  ), listFileItem );
178                     }
179                 }
180             }
181 
182             return new MultipartHttpServletRequest( request, mapFiles, mapParameters );
183         }
184 
185         return null;
186     }
187 }