1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.util.http;
35
36 import fr.paris.lutece.portal.service.html.EncodingService;
37 import fr.paris.lutece.portal.service.html.XSSSanitizerException;
38 import fr.paris.lutece.portal.service.html.XSSSanitizerService;
39 import fr.paris.lutece.portal.service.util.AppLogService;
40 import fr.paris.lutece.portal.web.upload.MultipartHttpServletRequest;
41 import fr.paris.lutece.portal.web.upload.NormalizeFileItem;
42
43 import org.apache.commons.fileupload.FileItem;
44 import org.apache.commons.fileupload.FileItemIterator;
45 import org.apache.commons.fileupload.FileItemStream;
46 import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
47 import org.apache.commons.fileupload.FileUploadException;
48 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
49 import org.apache.commons.fileupload.servlet.ServletFileUpload;
50 import org.apache.commons.lang3.StringUtils;
51
52 import java.io.UnsupportedEncodingException;
53
54 import java.util.ArrayList;
55 import java.util.HashMap;
56 import java.util.List;
57 import java.util.Map;
58 import java.util.Optional;
59
60 import javax.servlet.http.HttpServletRequest;
61
62
63
64
65
66
67 public final class MultipartUtil
68 {
69
70
71
72 private MultipartUtil( )
73 {
74 }
75
76
77
78
79
80
81
82
83 public static boolean isMultipart( HttpServletRequest request )
84 {
85 return ServletFileUpload.isMultipartContent( request );
86 }
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105 public static MultipartHttpServletRequest convert( int nSizeThreshold, long nRequestSizeMax, boolean bActivateNormalizeFileName,
106 HttpServletRequest request, boolean isXssSanitize ) throws FileUploadException
107 {
108 if ( !isMultipart( request ) )
109 {
110 return null;
111 }
112
113
114 DiskFileItemFactory factory = new DiskFileItemFactory( );
115
116
117 factory.setSizeThreshold( nSizeThreshold );
118
119
120 ServletFileUpload upload = new ServletFileUpload( factory );
121
122
123 upload.setSizeMax( nRequestSizeMax );
124
125
126 String strEncoding = Optional.ofNullable( request.getCharacterEncoding( ) ).orElse( EncodingService.getEncoding( ) );
127
128 Map<String, List<FileItem>> mapFiles = new HashMap<>( );
129 Map<String, String [ ]> mapParameters = new HashMap<>( );
130
131 List<FileItem> listItems;
132
133 try {
134 listItems = upload.parseRequest(request);
135 }
136 catch( SizeLimitExceededException e )
137 {
138 closeInputStream( upload, request );
139 throw e;
140 }
141
142
143 for ( FileItem item : listItems )
144 {
145 processItem( item, strEncoding, bActivateNormalizeFileName, mapFiles, mapParameters, isXssSanitize );
146 }
147
148 return new MultipartHttpServletRequest( request, mapFiles, mapParameters );
149 }
150
151
152
153
154
155
156 private static void closeInputStream( ServletFileUpload upload, HttpServletRequest request)
157 {
158 try {
159 upload.setSizeMax(-1);
160 FileItemIterator fileiterator = upload.getItemIterator(request);
161
162 while (fileiterator.hasNext())
163 {
164 FileItemStream item = fileiterator.next();
165 item.openStream().close();
166 }
167 }
168 catch (Exception e)
169 {
170 AppLogService.error( "error occured during closing the stream" , e);
171 }
172
173 }
174
175 private static void processItem( FileItem item, String strEncoding, boolean bActivateNormalizeFileName, Map<String, List<FileItem>> mapFiles,
176 Map<String, String [ ]> mapParameters, boolean isXssSanitize )
177 {
178 if ( item.isFormField( ) )
179 {
180 String strValue = StringUtils.EMPTY;
181
182 if ( item.getSize( ) > 0 )
183 {
184 try
185 {
186 strValue = item.getString( strEncoding );
187 }
188 catch( UnsupportedEncodingException ex )
189 {
190
191 strValue = item.getString( );
192 }
193 }
194
195 if ( isXssSanitize )
196 {
197 try
198 {
199 strValue = XSSSanitizerService.sanitize( strValue );
200 }
201 catch ( XSSSanitizerException e )
202 {
203 AppLogService.error( "XSS Sanitize Service Error", e );
204 }
205 }
206
207
208 String [ ] curParam = mapParameters.get( item.getFieldName( ) );
209
210 if ( curParam == null )
211 {
212
213 mapParameters.put( item.getFieldName( ), new String [ ] {
214 strValue
215 } );
216 }
217 else
218 {
219
220 String [ ] newArray = new String [ curParam.length + 1];
221 System.arraycopy( curParam, 0, newArray, 0, curParam.length );
222 newArray [curParam.length] = strValue;
223 mapParameters.put( item.getFieldName( ), newArray );
224 }
225 }
226 else
227 {
228
229
230
231 FileItem fileItem = bActivateNormalizeFileName ? new NormalizeFileItem( item ) : item;
232 List<FileItem> listFileItem = mapFiles.get( fileItem.getFieldName( ) );
233
234 if ( listFileItem != null )
235 {
236 listFileItem.add( fileItem );
237 }
238 else
239 {
240 listFileItem = new ArrayList<>( 1 );
241 listFileItem.add( fileItem );
242 mapFiles.put( fileItem.getFieldName( ), listFileItem );
243 }
244 }
245 }
246 }