1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.fileupload;
18
19 import static java.lang.String.format;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.nio.charset.StandardCharsets;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Locale;
29 import java.util.Map;
30 import java.util.NoSuchElementException;
31 import java.util.Objects;
32
33 import javax.servlet.http.HttpServletRequest;
34
35 import org.apache.commons.fileupload.MultipartStream.ItemInputStream;
36 import org.apache.commons.fileupload.servlet.ServletFileUpload;
37 import org.apache.commons.fileupload.servlet.ServletRequestContext;
38 import org.apache.commons.fileupload.util.Closeable;
39 import org.apache.commons.fileupload.util.FileItemHeadersImpl;
40 import org.apache.commons.fileupload.util.LimitedInputStream;
41 import org.apache.commons.fileupload.util.Streams;
42 import org.apache.commons.io.IOUtils;
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 public abstract class FileUploadBase {
58
59
60
61
62
63 private class FileItemIteratorImpl implements FileItemIterator {
64
65
66
67
68 private final class FileItemStreamImpl implements FileItemStream {
69
70
71
72
73 private final String contentType;
74
75
76
77
78 private final String fieldName;
79
80
81
82
83 private final String name;
84
85
86
87
88 private final boolean formField;
89
90
91
92
93 private final InputStream inputStream;
94
95
96
97
98 private FileItemHeaders headers;
99
100
101
102
103
104
105
106
107
108
109
110 FileItemStreamImpl(final String name, final String fieldName, final String contentType, final boolean formField, final long contentLength)
111 throws IOException {
112 this.name = name;
113 this.fieldName = fieldName;
114 this.contentType = contentType;
115 this.formField = formField;
116
117 if (fileSizeMax != -1 && contentLength != -1 && contentLength > fileSizeMax) {
118 final FileSizeLimitExceededException e = new FileSizeLimitExceededException(
119 format("The field %s exceeds its maximum permitted size of %s bytes.", fieldName, Long.valueOf(fileSizeMax)), contentLength,
120 fileSizeMax);
121 e.setFileName(name);
122 e.setFieldName(fieldName);
123 throw new FileUploadIOException(e);
124 }
125
126 final ItemInputStream itemStream = multi.newInputStream();
127 InputStream istream = itemStream;
128 if (fileSizeMax != -1) {
129 istream = new LimitedInputStream(istream, fileSizeMax) {
130
131 @Override
132 protected void raiseError(final long sizeMax, final long count) throws IOException {
133 itemStream.close(true);
134 final FileSizeLimitExceededException e = new FileSizeLimitExceededException(
135 format("The field %s exceeds its maximum permitted size of %s bytes.", fieldName, Long.valueOf(sizeMax)), count, sizeMax);
136 e.setFieldName(fieldName);
137 e.setFileName(name);
138 throw new FileUploadIOException(e);
139 }
140 };
141 }
142 inputStream = istream;
143 }
144
145
146
147
148
149
150 void close() throws IOException {
151 inputStream.close();
152 }
153
154
155
156
157
158
159 @Override
160 public String getContentType() {
161 return contentType;
162 }
163
164
165
166
167
168
169 @Override
170 public String getFieldName() {
171 return fieldName;
172 }
173
174
175
176
177
178
179 @Override
180 public FileItemHeaders getHeaders() {
181 return headers;
182 }
183
184
185
186
187
188
189
190
191
192
193 @Override
194 public String getName() {
195 return Streams.checkFileName(name);
196 }
197
198
199
200
201
202
203
204 @Override
205 public boolean isFormField() {
206 return formField;
207 }
208
209
210
211
212
213
214
215
216 @Override
217 public InputStream openStream() throws IOException {
218 if (((Closeable) inputStream).isClosed()) {
219 throw new FileItemStream.ItemSkippedException();
220 }
221 return inputStream;
222 }
223
224
225
226
227
228
229 @Override
230 public void setHeaders(final FileItemHeaders headers) {
231 this.headers = headers;
232 }
233
234 }
235
236
237
238
239 private final MultipartStream multi;
240
241
242
243
244
245 private final MultipartStream.ProgressNotifier notifier;
246
247
248
249
250 private final byte[] boundary;
251
252
253
254
255 private FileItemStreamImpl currentItem;
256
257
258
259
260 private String currentFieldName;
261
262
263
264
265 private boolean skipPreamble;
266
267
268
269
270 private boolean itemValid;
271
272
273
274
275 private boolean eof;
276
277
278
279
280 private final boolean multipartRelated;
281
282
283
284
285
286
287
288
289
290 FileItemIteratorImpl(final RequestContext ctx) throws FileUploadException, IOException {
291 Objects.requireNonNull(ctx, "ctx");
292 final String contentType = ctx.getContentType();
293 if (null == contentType || !contentType.toLowerCase(Locale.ROOT).startsWith(MULTIPART)) {
294 throw new InvalidContentTypeException(format("the request neither contains a %s nor a %s nor a %s stream, content type header is %s",
295 MULTIPART_FORM_DATA, MULTIPART_MIXED, MULTIPART_RELATED, contentType));
296 }
297 multipartRelated = contentType.toLowerCase(Locale.ROOT).startsWith(MULTIPART_RELATED);
298 @SuppressWarnings("deprecation")
299 final int contentLengthInt = ctx.getContentLength();
300 final long requestSize = UploadContext.class.isAssignableFrom(ctx.getClass())
301
302 ? ((UploadContext) ctx).contentLength()
303 : contentLengthInt;
304
305 final InputStream input;
306 if (sizeMax >= 0) {
307 if (requestSize != -1 && requestSize > sizeMax) {
308 throw new SizeLimitExceededException(format("the request was rejected because its size (%s) exceeds the configured maximum (%s)",
309 Long.valueOf(requestSize), Long.valueOf(sizeMax)), requestSize, sizeMax);
310 }
311
312 input = new LimitedInputStream(ctx.getInputStream(), sizeMax) {
313
314 @Override
315 protected void raiseError(final long sizeMax, final long count) throws IOException {
316 final FileUploadException ex = new SizeLimitExceededException(
317 format("the request was rejected because its size (%s) exceeds the configured maximum (%s)", Long.valueOf(count),
318 Long.valueOf(sizeMax)),
319 count, sizeMax);
320 throw new FileUploadIOException(ex);
321 }
322 };
323 } else {
324 input = ctx.getInputStream();
325 }
326 String charEncoding = headerEncoding;
327 if (charEncoding == null) {
328 charEncoding = ctx.getCharacterEncoding();
329 }
330 boundary = getBoundary(contentType);
331 if (boundary == null) {
332 IOUtils.closeQuietly(input);
333 throw new FileUploadException("the request was rejected because no multipart boundary was found");
334 }
335 notifier = new MultipartStream.ProgressNotifier(listener, requestSize);
336 try {
337 multi = new MultipartStream(input, boundary, notifier);
338 } catch (final IllegalArgumentException iae) {
339 IOUtils.closeQuietly(input);
340 throw new InvalidContentTypeException(format("The boundary specified in the %s header is too long", CONTENT_TYPE), iae);
341 }
342 multi.setHeaderEncoding(charEncoding);
343 multi.setPartHeaderSizeMax(getPartHeaderSizeMax());
344 skipPreamble = true;
345 findNextItem();
346 }
347
348
349
350
351
352
353
354 private boolean findNextItem() throws IOException {
355 if (eof) {
356 return false;
357 }
358 if (currentItem != null) {
359 currentItem.close();
360 currentItem = null;
361 }
362 for (;;) {
363 final boolean nextPart;
364 if (skipPreamble) {
365 nextPart = multi.skipPreamble();
366 } else {
367 nextPart = multi.readBoundary();
368 }
369 if (!nextPart) {
370 if (currentFieldName == null) {
371
372 eof = true;
373 return false;
374 }
375
376 multi.setBoundary(boundary);
377 currentFieldName = null;
378 continue;
379 }
380 final FileItemHeaders headers = getParsedHeaders(multi.readHeaders());
381 if (multipartRelated) {
382 currentFieldName = "";
383 currentItem = new FileItemStreamImpl(null, null, headers.getHeader(CONTENT_TYPE), false, getContentLength(headers));
384 currentItem.setHeaders(headers);
385 notifier.noteItem();
386 itemValid = true;
387 return true;
388 }
389 if (currentFieldName == null) {
390
391 final String fieldName = getFieldName(headers);
392 if (fieldName != null) {
393 final String subContentType = headers.getHeader(CONTENT_TYPE);
394 if (subContentType != null && subContentType.toLowerCase(Locale.ROOT).startsWith(MULTIPART_MIXED)) {
395 currentFieldName = fieldName;
396
397 final byte[] subBoundary = getBoundary(subContentType);
398 multi.setBoundary(subBoundary);
399 skipPreamble = true;
400 continue;
401 }
402 final String fileName = getFileName(headers);
403 currentItem = new FileItemStreamImpl(fileName, fieldName, headers.getHeader(CONTENT_TYPE), fileName == null, getContentLength(headers));
404 currentItem.setHeaders(headers);
405 notifier.noteItem();
406 itemValid = true;
407 return true;
408 }
409 } else {
410 final String fileName = getFileName(headers);
411 if (fileName != null) {
412 currentItem = new FileItemStreamImpl(fileName, currentFieldName, headers.getHeader(CONTENT_TYPE), false, getContentLength(headers));
413 currentItem.setHeaders(headers);
414 notifier.noteItem();
415 itemValid = true;
416 return true;
417 }
418 }
419 multi.discardBodyData();
420 }
421 }
422
423 private long getContentLength(final FileItemHeaders headers) {
424 try {
425 return Long.parseLong(headers.getHeader(CONTENT_LENGTH));
426 } catch (final Exception e) {
427 return -1;
428 }
429 }
430
431
432
433
434
435
436
437
438
439
440
441 @Override
442 public boolean hasNext() throws FileUploadException, IOException {
443 if (eof) {
444 return false;
445 }
446 if (itemValid) {
447 return true;
448 }
449 try {
450 return findNextItem();
451 } catch (final FileUploadIOException e) {
452
453 throw (FileUploadException) e.getCause();
454 }
455 }
456
457
458
459
460
461
462
463
464
465
466
467
468 @Override
469 public FileItemStream next() throws FileUploadException, IOException {
470 if (eof || !itemValid && !hasNext()) {
471 throw new NoSuchElementException();
472 }
473 itemValid = false;
474 return currentItem;
475 }
476
477 }
478
479
480
481
482 public static class FileSizeLimitExceededException
483 extends SizeException {
484
485
486
487
488 private static final long serialVersionUID = 8150776562029630058L;
489
490
491
492
493 private String fileName;
494
495
496
497
498 private String fieldName;
499
500
501
502
503
504
505
506
507
508 public FileSizeLimitExceededException(final String message, final long actual,
509 final long permitted) {
510 super(message, actual, permitted);
511 }
512
513
514
515
516
517
518
519 public String getFieldName() {
520 return fieldName;
521 }
522
523
524
525
526
527
528
529 public String getFileName() {
530 return fileName;
531 }
532
533
534
535
536
537
538
539
540 public void setFieldName(final String fieldName) {
541 this.fieldName = fieldName;
542 }
543
544
545
546
547
548
549
550 public void setFileName(final String fileName) {
551 this.fileName = fileName;
552 }
553
554 }
555
556
557
558
559
560
561
562 public static class FileUploadIOException extends IOException {
563
564
565
566
567 private static final long serialVersionUID = -7047616958165584154L;
568
569
570
571
572
573
574 public FileUploadIOException(final FileUploadException cause) {
575 super(cause);
576 }
577 }
578
579
580
581
582 public static class InvalidContentTypeException
583 extends FileUploadException {
584
585
586
587
588 private static final long serialVersionUID = -9073026332015646668L;
589
590
591
592
593
594 public InvalidContentTypeException() {
595 }
596
597
598
599
600
601
602
603 public InvalidContentTypeException(final String message) {
604 super(message);
605 }
606
607
608
609
610
611
612
613
614
615 public InvalidContentTypeException(final String message, final Throwable cause) {
616 super(message, cause);
617 }
618 }
619
620
621
622
623 public static class IOFileUploadException extends FileUploadException {
624
625
626
627
628 private static final long serialVersionUID = 1749796615868477269L;
629
630
631
632
633
634
635
636 public IOFileUploadException(final String message, final IOException cause) {
637 super(message, cause);
638 }
639
640 }
641
642
643
644
645
646 protected abstract static class SizeException extends FileUploadException {
647
648
649
650
651 private static final long serialVersionUID = -8776225574705254126L;
652
653
654
655
656 private final long actual;
657
658
659
660
661 private final long permitted;
662
663
664
665
666
667
668
669
670 protected SizeException(final String message, final long actual, final long permitted) {
671 super(message);
672 this.actual = actual;
673 this.permitted = permitted;
674 }
675
676
677
678
679
680
681
682 public long getActualSize() {
683 return actual;
684 }
685
686
687
688
689
690
691
692 public long getPermittedSize() {
693 return permitted;
694 }
695
696 }
697
698
699
700
701 public static class SizeLimitExceededException
702 extends SizeException {
703
704
705
706
707 private static final long serialVersionUID = -2474893167098052828L;
708
709
710
711
712
713 @Deprecated
714 public SizeLimitExceededException() {
715 this(null, 0, 0);
716 }
717
718
719
720
721
722
723 @Deprecated
724 public SizeLimitExceededException(final String message) {
725 this(message, 0, 0);
726 }
727
728
729
730
731
732
733
734
735
736 public SizeLimitExceededException(final String message, final long actual,
737 final long permitted) {
738 super(message, actual, permitted);
739 }
740
741 }
742
743
744
745
746
747
748
749
750
751 @Deprecated
752 public static class UnknownSizeException extends FileUploadException {
753
754
755
756
757 private static final long serialVersionUID = 7062279004812015273L;
758
759
760
761
762
763 public UnknownSizeException() {
764 }
765
766
767
768
769
770
771
772 public UnknownSizeException(final String message) {
773 super(message);
774 }
775
776 }
777
778
779
780
781 private static final char LF = '\n';
782
783
784
785
786 private static final char CR = '\r';
787
788
789
790
791 public static final String CONTENT_TYPE = "Content-type";
792
793
794
795
796 public static final String CONTENT_DISPOSITION = "Content-disposition";
797
798
799
800
801 public static final String CONTENT_LENGTH = "Content-length";
802
803
804
805
806 public static final String FORM_DATA = "form-data";
807
808
809
810
811 public static final String ATTACHMENT = "attachment";
812
813
814
815
816 public static final String MULTIPART = "multipart/";
817
818
819
820
821 public static final String MULTIPART_FORM_DATA = "multipart/form-data";
822
823
824
825
826 public static final String MULTIPART_MIXED = "multipart/mixed";
827
828
829
830
831
832
833 public static final String MULTIPART_RELATED = "multipart/related";
834
835
836
837
838
839
840
841
842 @Deprecated
843 public static final int MAX_HEADER_SIZE = 1024;
844
845
846
847
848
849
850 public static final int DEFAULT_PART_HEADER_SIZE_MAX = 512;
851
852
853
854
855
856
857
858
859
860
861
862
863 @Deprecated
864 public static boolean isMultipartContent(final HttpServletRequest req) {
865 return ServletFileUpload.isMultipartContent(req);
866 }
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881 public static final boolean isMultipartContent(final RequestContext ctx) {
882 final String contentType = ctx.getContentType();
883 if (contentType == null) {
884 return false;
885 }
886 return contentType.toLowerCase(Locale.ROOT).startsWith(MULTIPART);
887 }
888
889
890
891
892
893 private long sizeMax = -1;
894
895
896
897
898
899 private long fileSizeMax = -1;
900
901
902
903
904
905 private long fileCountMax = -1;
906
907
908
909
910 private int partHeaderSizeMax = DEFAULT_PART_HEADER_SIZE_MAX;
911
912
913
914
915 private String headerEncoding;
916
917
918
919
920 private ProgressListener listener;
921
922
923
924
925 public FileUploadBase() {
926
927 }
928
929
930
931
932
933
934
935
936
937
938
939
940
941 @Deprecated
942 protected FileItem createItem(final Map<String, String> headers, final boolean isFormField) {
943 return getFileItemFactory().createItem(getFieldName(headers), getHeader(headers, CONTENT_TYPE), isFormField, getFileName(headers));
944 }
945
946
947
948
949
950
951
952
953
954 protected byte[] getBoundary(final String contentType) {
955 final ParameterParser parser = new ParameterParser();
956 parser.setLowerCaseNames(true);
957
958 final Map<String, String> params = parser.parse(contentType, new char[] { ';', ',' });
959 final String boundaryStr = params.get("boundary");
960 if (boundaryStr == null) {
961 return null;
962 }
963 return boundaryStr.getBytes(StandardCharsets.ISO_8859_1);
964 }
965
966
967
968
969
970
971
972
973 protected String getFieldName(final FileItemHeaders headers) {
974 return getFieldName(headers.getHeader(CONTENT_DISPOSITION));
975 }
976
977
978
979
980
981
982
983
984
985 @Deprecated
986 protected String getFieldName(final Map<String, String> headers) {
987 return getFieldName(getHeader(headers, CONTENT_DISPOSITION));
988 }
989
990
991
992
993
994
995
996 private String getFieldName(final String contentDisposition) {
997 String fieldName = null;
998 if (contentDisposition != null && contentDisposition.toLowerCase(Locale.ROOT).startsWith(FORM_DATA)) {
999 final ParameterParser parser = new ParameterParser();
1000 parser.setLowerCaseNames(true);
1001
1002 final Map<String, String> params = parser.parse(contentDisposition, ';');
1003 fieldName = params.get("name");
1004 if (fieldName != null) {
1005 fieldName = fieldName.trim();
1006 }
1007 }
1008 return fieldName;
1009 }
1010
1011
1012
1013
1014
1015
1016 public long getFileCountMax() {
1017 return fileCountMax;
1018 }
1019
1020
1021
1022
1023
1024
1025 public abstract FileItemFactory getFileItemFactory();
1026
1027
1028
1029
1030
1031
1032
1033
1034 protected String getFileName(final FileItemHeaders headers) {
1035 return getFileName(headers.getHeader(CONTENT_DISPOSITION));
1036 }
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046 @Deprecated
1047 protected String getFileName(final Map<String, String> headers) {
1048 return getFileName(getHeader(headers, CONTENT_DISPOSITION));
1049 }
1050
1051
1052
1053
1054
1055
1056 private String getFileName(final String contentDisposition) {
1057 String fileName = null;
1058 if (contentDisposition != null) {
1059 final String cdl = contentDisposition.toLowerCase(Locale.ROOT);
1060 if (cdl.startsWith(FORM_DATA) || cdl.startsWith(ATTACHMENT)) {
1061 final ParameterParser parser = new ParameterParser();
1062 parser.setLowerCaseNames(true);
1063
1064 final Map<String, String> params = parser.parse(contentDisposition, ';');
1065 if (params.containsKey("filename")) {
1066 fileName = params.get("filename");
1067 if (fileName != null) {
1068 fileName = fileName.trim();
1069 } else {
1070
1071
1072
1073 fileName = "";
1074 }
1075 }
1076 }
1077 }
1078 return fileName;
1079 }
1080
1081
1082
1083
1084
1085
1086
1087
1088 public long getFileSizeMax() {
1089 return fileSizeMax;
1090 }
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102 @Deprecated
1103 protected final String getHeader(final Map<String, String> headers,
1104 final String name) {
1105 return headers.get(name.toLowerCase(Locale.ROOT));
1106 }
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116 public String getHeaderEncoding() {
1117 return headerEncoding;
1118 }
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135 public FileItemIterator getItemIterator(final RequestContext ctx)
1136 throws FileUploadException, IOException {
1137 try {
1138 return new FileItemIteratorImpl(ctx);
1139 } catch (final FileUploadIOException e) {
1140
1141 throw (FileUploadException) e.getCause();
1142 }
1143 }
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157 protected FileItemHeaders getParsedHeaders(final String headerPart) {
1158 final int len = headerPart.length();
1159 final FileItemHeadersImpl headers = newFileItemHeaders();
1160 int start = 0;
1161 for (;;) {
1162 int end = parseEndOfLine(headerPart, start);
1163 if (start == end) {
1164 break;
1165 }
1166 final StringBuilder header = new StringBuilder(headerPart.substring(start, end));
1167 start = end + 2;
1168 while (start < len) {
1169 int nonWs = start;
1170 while (nonWs < len) {
1171 final char c = headerPart.charAt(nonWs);
1172 if (c != ' ' && c != '\t') {
1173 break;
1174 }
1175 ++nonWs;
1176 }
1177 if (nonWs == start) {
1178 break;
1179 }
1180
1181 end = parseEndOfLine(headerPart, nonWs);
1182 header.append(' ').append(headerPart, nonWs, end);
1183 start = end + 2;
1184 }
1185 parseHeaderLine(headers, header.toString());
1186 }
1187 return headers;
1188 }
1189
1190
1191
1192
1193
1194
1195
1196
1197 public int getPartHeaderSizeMax() {
1198 return partHeaderSizeMax;
1199 }
1200
1201
1202
1203
1204
1205
1206 public ProgressListener getProgressListener() {
1207 return listener;
1208 }
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220 public long getSizeMax() {
1221 return sizeMax;
1222 }
1223
1224
1225
1226
1227
1228 protected FileItemHeadersImpl newFileItemHeaders() {
1229 return new FileItemHeadersImpl();
1230 }
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240 private int parseEndOfLine(final String headerPart, final int end) {
1241 int index = end;
1242 for (;;) {
1243 final int offset = headerPart.indexOf(CR, index);
1244 if (offset == -1 || offset + 1 >= headerPart.length()) {
1245 throw new IllegalStateException(
1246 "Expected headers to be terminated by an empty line.");
1247 }
1248 if (headerPart.charAt(offset + 1) == LF) {
1249 return offset;
1250 }
1251 index = offset + 1;
1252 }
1253 }
1254
1255
1256
1257
1258
1259
1260 private void parseHeaderLine(final FileItemHeadersImpl headers, final String header) {
1261 final int colonOffset = header.indexOf(':');
1262 if (colonOffset == -1) {
1263
1264 return;
1265 }
1266 final String headerName = header.substring(0, colonOffset).trim();
1267 final String headerValue = header.substring(colonOffset + 1).trim();
1268 headers.addHeader(headerName, headerValue);
1269 }
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284 @Deprecated
1285 protected Map<String, String> parseHeaders(final String headerPart) {
1286 final FileItemHeaders headers = getParsedHeaders(headerPart);
1287 final Map<String, String> result = new HashMap<>();
1288 for (final Iterator<String> iter = headers.getHeaderNames(); iter.hasNext();) {
1289 final String headerName = iter.next();
1290 final Iterator<String> iter2 = headers.getHeaders(headerName);
1291 final StringBuilder headerValue = new StringBuilder(iter2.next());
1292 while (iter2.hasNext()) {
1293 headerValue.append(",").append(iter2.next());
1294 }
1295 result.put(headerName, headerValue.toString());
1296 }
1297 return result;
1298 }
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311 public Map<String, List<FileItem>> parseParameterMap(final RequestContext ctx) throws FileUploadException {
1312 final List<FileItem> items = parseRequest(ctx);
1313 final Map<String, List<FileItem>> itemsMap = new HashMap<>(items.size());
1314 for (final FileItem fileItem : items) {
1315 final String fieldName = fileItem.getFieldName();
1316 List<FileItem> mappedItems = itemsMap.get(fieldName);
1317 if (mappedItems == null) {
1318 mappedItems = new ArrayList<>();
1319 itemsMap.put(fieldName, mappedItems);
1320 }
1321 mappedItems.add(fileItem);
1322 }
1323 return itemsMap;
1324 }
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339 @Deprecated
1340 public List<FileItem> parseRequest(final HttpServletRequest req)
1341 throws FileUploadException {
1342 return parseRequest(new ServletRequestContext(req));
1343 }
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356 public List<FileItem> parseRequest(final RequestContext ctx) throws FileUploadException {
1357 final List<FileItem> items = new ArrayList<>();
1358 boolean successful = false;
1359 try {
1360 final FileItemIterator iter = getItemIterator(ctx);
1361 final FileItemFactory fileItemFactory = getFileItemFactory();
1362 Objects.requireNonNull(fileItemFactory, "getFileItemFactory()");
1363 final byte[] buffer = new byte[Streams.DEFAULT_BUFFER_SIZE];
1364 while (iter.hasNext()) {
1365 if (items.size() == fileCountMax) {
1366
1367 throw new FileCountLimitExceededException(ATTACHMENT, getFileCountMax());
1368 }
1369 final FileItemStream item = iter.next();
1370
1371 final String fileName = ((FileItemIteratorImpl.FileItemStreamImpl) item).name;
1372 final FileItem fileItem = fileItemFactory.createItem(item.getFieldName(), item.getContentType(), item.isFormField(), fileName);
1373 items.add(fileItem);
1374 try {
1375 Streams.copy(item.openStream(), fileItem.getOutputStream(), true, buffer);
1376 } catch (final FileUploadIOException e) {
1377 throw (FileUploadException) e.getCause();
1378 } catch (final IOException e) {
1379 throw new IOFileUploadException(format("Processing of %s request failed. %s", MULTIPART_FORM_DATA, e.getMessage()), e);
1380 }
1381 final FileItemHeaders fih = item.getHeaders();
1382 fileItem.setHeaders(fih);
1383 }
1384 successful = true;
1385 return items;
1386 } catch (final FileUploadIOException e) {
1387 throw (FileUploadException) e.getCause();
1388 } catch (final IOException e) {
1389 throw new FileUploadException(e.getMessage(), e);
1390 } finally {
1391 if (!successful) {
1392 for (final FileItem fileItem : items) {
1393 try {
1394 fileItem.delete();
1395 } catch (final Exception ignored) {
1396
1397 }
1398 }
1399 }
1400 }
1401 }
1402
1403
1404
1405
1406
1407
1408 public void setFileCountMax(final long fileCountMax) {
1409 this.fileCountMax = fileCountMax;
1410 }
1411
1412
1413
1414
1415
1416
1417 public abstract void setFileItemFactory(FileItemFactory factory);
1418
1419
1420
1421
1422
1423
1424
1425
1426 public void setFileSizeMax(final long fileSizeMax) {
1427 this.fileSizeMax = fileSizeMax;
1428 }
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438 public void setHeaderEncoding(final String encoding) {
1439 headerEncoding = encoding;
1440 }
1441
1442
1443
1444
1445
1446
1447
1448
1449 public void setPartHeaderSizeMax(final int partHeaderSizeMax) {
1450 this.partHeaderSizeMax = partHeaderSizeMax;
1451 }
1452
1453
1454
1455
1456
1457
1458 public void setProgressListener(final ProgressListener listener) {
1459 this.listener = listener;
1460 }
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472 public void setSizeMax(final long sizeMax) {
1473 this.sizeMax = sizeMax;
1474 }
1475
1476 }