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 }