001
014
015 package com.liferay.portal.upload;
016
017 import com.liferay.portal.kernel.io.ByteArrayFileInputStream;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.upload.FileItem;
021 import com.liferay.portal.kernel.upload.UploadException;
022 import com.liferay.portal.kernel.upload.UploadServletRequest;
023 import com.liferay.portal.kernel.util.ArrayUtil;
024 import com.liferay.portal.kernel.util.FileUtil;
025 import com.liferay.portal.kernel.util.ProgressTracker;
026 import com.liferay.portal.kernel.util.PropsKeys;
027 import com.liferay.portal.kernel.util.StringBundler;
028 import com.liferay.portal.kernel.util.SystemProperties;
029 import com.liferay.portal.kernel.util.Validator;
030 import com.liferay.portal.kernel.util.WebKeys;
031 import com.liferay.portal.util.PrefsPropsUtil;
032
033 import java.io.File;
034 import java.io.IOException;
035 import java.io.InputStream;
036
037 import java.util.ArrayList;
038 import java.util.Collections;
039 import java.util.Enumeration;
040 import java.util.HashMap;
041 import java.util.LinkedHashMap;
042 import java.util.LinkedHashSet;
043 import java.util.List;
044 import java.util.Map;
045 import java.util.Set;
046 import java.util.TreeSet;
047
048 import javax.servlet.ServletInputStream;
049 import javax.servlet.http.HttpServletRequest;
050 import javax.servlet.http.HttpServletRequestWrapper;
051 import javax.servlet.http.HttpSession;
052
053 import org.apache.commons.fileupload.FileUploadBase;
054 import org.apache.commons.fileupload.servlet.ServletFileUpload;
055
056
062 public class UploadServletRequestImpl
063 extends HttpServletRequestWrapper implements UploadServletRequest {
064
065 public static File getTempDir() {
066 if (_tempDir == null) {
067 _tempDir = new File(
068 PrefsPropsUtil.getString(
069 PropsKeys.UPLOAD_SERVLET_REQUEST_IMPL_TEMP_DIR,
070 SystemProperties.get(SystemProperties.TMP_DIR)));
071 }
072
073 return _tempDir;
074 }
075
076 public static void setTempDir(File tempDir) {
077 _tempDir = tempDir;
078 }
079
080 public UploadServletRequestImpl(HttpServletRequest request) {
081 super(request);
082
083 _fileParameters = new LinkedHashMap<>();
084 _regularParameters = new LinkedHashMap<>();
085
086 LiferayServletRequest liferayServletRequest = null;
087
088 try {
089 HttpSession session = request.getSession();
090
091 session.removeAttribute(ProgressTracker.PERCENT);
092
093 ServletFileUpload servletFileUpload = new ServletFileUpload(
094 new LiferayFileItemFactory(getTempDir()));
095
096 liferayServletRequest = new LiferayServletRequest(request);
097
098 List<org.apache.commons.fileupload.FileItem> fileItems =
099 servletFileUpload.parseRequest(liferayServletRequest);
100
101 liferayServletRequest.setFinishedReadingOriginalStream(true);
102
103 long uploadServletRequestImplMaxSize = PrefsPropsUtil.getLong(
104 PropsKeys.UPLOAD_SERVLET_REQUEST_IMPL_MAX_SIZE);
105 long uploadServletRequestImplSize = 0;
106
107 int contentLength = request.getContentLength();
108
109 if ((uploadServletRequestImplMaxSize > 0) &&
110 ((contentLength == -1) ||
111 (contentLength > uploadServletRequestImplMaxSize))) {
112
113 fileItems = sort(fileItems);
114 }
115
116 for (org.apache.commons.fileupload.FileItem fileItem : fileItems) {
117 LiferayFileItem liferayFileItem = (LiferayFileItem)fileItem;
118
119 if (uploadServletRequestImplMaxSize > 0) {
120 long itemSize = liferayFileItem.getItemSize();
121
122 if ((uploadServletRequestImplSize + itemSize) >
123 uploadServletRequestImplMaxSize) {
124
125 StringBundler sb = new StringBundler(3);
126
127 sb.append(
128 "Request reached the maximum permitted size of ");
129 sb.append(uploadServletRequestImplMaxSize);
130 sb.append(" bytes");
131
132 UploadException uploadException = new UploadException(
133 sb.toString());
134
135 uploadException.setExceededUploadRequestSizeLimit(true);
136
137 request.setAttribute(
138 WebKeys.UPLOAD_EXCEPTION, uploadException);
139
140 continue;
141 }
142
143 uploadServletRequestImplSize += itemSize;
144 }
145
146 if (liferayFileItem.isFormField()) {
147 liferayFileItem.setString(request.getCharacterEncoding());
148
149 String fieldName = liferayFileItem.getFieldName();
150
151 if (!_regularParameters.containsKey(fieldName)) {
152 _regularParameters.put(
153 fieldName, new ArrayList<String>());
154 }
155
156 List<String> values = _regularParameters.get(fieldName);
157
158 if (liferayFileItem.getSize() >
159 LiferayFileItem.THRESHOLD_SIZE) {
160
161 StringBundler sb = new StringBundler(5);
162
163 sb.append("The field ");
164 sb.append(fieldName);
165 sb.append(" exceeds its maximum permitted size of ");
166 sb.append(LiferayFileItem.THRESHOLD_SIZE);
167 sb.append(" bytes");
168
169 UploadException uploadException = new UploadException(
170 sb.toString());
171
172 uploadException.setExceededLiferayFileItemSizeLimit(
173 true);
174
175 request.setAttribute(
176 WebKeys.UPLOAD_EXCEPTION, uploadException);
177 }
178
179 values.add(liferayFileItem.getEncodedString());
180
181 continue;
182 }
183
184 FileItem[] liferayFileItems = _fileParameters.get(
185 liferayFileItem.getFieldName());
186
187 if (liferayFileItems == null) {
188 liferayFileItems = new LiferayFileItem[] {liferayFileItem};
189 }
190 else {
191 LiferayFileItem[] newLiferayFileItems =
192 new LiferayFileItem[liferayFileItems.length + 1];
193
194 System.arraycopy(
195 liferayFileItems, 0, newLiferayFileItems, 0,
196 liferayFileItems.length);
197
198 newLiferayFileItems[newLiferayFileItems.length - 1] =
199 liferayFileItem;
200
201 liferayFileItems = newLiferayFileItems;
202 }
203
204 _fileParameters.put(
205 liferayFileItem.getFieldName(), liferayFileItems);
206 }
207 }
208 catch (Exception e) {
209 UploadException uploadException = new UploadException(e);
210
211 if (e instanceof FileUploadBase.FileSizeLimitExceededException) {
212 uploadException.setExceededFileSizeLimit(true);
213 }
214 else if (e instanceof FileUploadBase.SizeLimitExceededException ) {
215 uploadException.setExceededUploadRequestSizeLimit(true);
216 }
217
218 request.setAttribute(WebKeys.UPLOAD_EXCEPTION, uploadException);
219
220 if (_log.isDebugEnabled()) {
221 _log.debug(e, e);
222 }
223 }
224
225 _liferayServletRequest = liferayServletRequest;
226 }
227
228 public UploadServletRequestImpl(
229 HttpServletRequest request, Map<String, FileItem[]> fileParameters,
230 Map<String, List<String>> regularParameters) {
231
232 super(request);
233
234 _fileParameters = new LinkedHashMap<>();
235 _regularParameters = new LinkedHashMap<>();
236
237 if (fileParameters != null) {
238 _fileParameters.putAll(fileParameters);
239 }
240
241 if (regularParameters != null) {
242 _regularParameters.putAll(regularParameters);
243 }
244
245 _liferayServletRequest = null;
246 }
247
248 @Override
249 public void cleanUp() {
250 if ((_fileParameters != null) && !_fileParameters.isEmpty()) {
251 for (FileItem[] liferayFileItems : _fileParameters.values()) {
252 for (FileItem liferayFileItem : liferayFileItems) {
253 liferayFileItem.delete();
254 }
255 }
256 }
257
258 if (_liferayServletRequest != null) {
259 _liferayServletRequest.cleanUp();
260 }
261 }
262
263 @Override
264 public String getContentType(String name) {
265 FileItem[] liferayFileItems = _fileParameters.get(name);
266
267 if (ArrayUtil.isNotEmpty(liferayFileItems)) {
268 FileItem liferayFileItem = liferayFileItems[0];
269
270 return liferayFileItem.getContentType();
271 }
272
273 return null;
274 }
275
276 @Override
277 public File getFile(String name) {
278 return getFile(name, false);
279 }
280
281 @Override
282 public File getFile(String name, boolean forceCreate) {
283 if (getFileName(name) == null) {
284 return null;
285 }
286
287 FileItem[] liferayFileItems = _fileParameters.get(name);
288
289 if (ArrayUtil.isEmpty(liferayFileItems)) {
290 return null;
291 }
292
293 FileItem liferayFileItem = liferayFileItems[0];
294
295 long size = liferayFileItem.getSize();
296
297 if ((size > 0) && (size <= liferayFileItem.getSizeThreshold())) {
298 forceCreate = true;
299 }
300
301 File file = liferayFileItem.getStoreLocation();
302
303 if (liferayFileItem.isInMemory() && forceCreate) {
304 try {
305 FileUtil.write(file, liferayFileItem.getInputStream());
306 }
307 catch (IOException ioe) {
308 if (_log.isWarnEnabled()) {
309 _log.warn(
310 "Unable to write temporary file " +
311 file.getAbsolutePath(),
312 ioe);
313 }
314 }
315 }
316
317 return file;
318 }
319
320 @Override
321 public InputStream getFileAsStream(String name) throws IOException {
322 return getFileAsStream(name, true);
323 }
324
325 @Override
326 public InputStream getFileAsStream(String name, boolean deleteOnClose)
327 throws IOException {
328
329 if (getFileName(name) == null) {
330 return null;
331 }
332
333 InputStream inputStream = null;
334
335 FileItem[] liferayFileItems = _fileParameters.get(name);
336
337 if (ArrayUtil.isNotEmpty(liferayFileItems)) {
338 FileItem liferayFileItem = liferayFileItems[0];
339
340 inputStream = getInputStream(liferayFileItem, deleteOnClose);
341 }
342
343 return inputStream;
344 }
345
346 @Override
347 public String getFileName(String name) {
348 FileItem[] liferayFileItems = _fileParameters.get(name);
349
350 if (ArrayUtil.isNotEmpty(liferayFileItems)) {
351 FileItem liferayFileItem = liferayFileItems[0];
352
353 return liferayFileItem.getFileName();
354 }
355
356 return null;
357 }
358
359 @Override
360 public String[] getFileNames(String name) {
361 FileItem[] liferayFileItems = _fileParameters.get(name);
362
363 if (ArrayUtil.isNotEmpty(liferayFileItems)) {
364 String[] fileNames = new String[liferayFileItems.length];
365
366 for (int i = 0; i < liferayFileItems.length; i++) {
367 FileItem liferayFileItem = liferayFileItems[i];
368
369 fileNames[i] = liferayFileItem.getFileName();
370 }
371
372 return fileNames;
373 }
374
375 return null;
376 }
377
378 @Override
379 public File[] getFiles(String name) {
380 String[] fileNames = getFileNames(name);
381
382 if (fileNames == null) {
383 return null;
384 }
385
386 FileItem[] liferayFileItems = _fileParameters.get(name);
387
388 if (ArrayUtil.isNotEmpty(liferayFileItems)) {
389 File[] files = new File[liferayFileItems.length];
390
391 for (int i = 0; i < liferayFileItems.length; i++) {
392 FileItem liferayFileItem = liferayFileItems[i];
393
394 if (Validator.isNotNull(liferayFileItem.getFileName())) {
395 files[i] = liferayFileItem.getStoreLocation();
396 }
397 }
398
399 return files;
400 }
401
402 return null;
403 }
404
405 @Override
406 public InputStream[] getFilesAsStream(String name) throws IOException {
407 return getFilesAsStream(name, true);
408 }
409
410 @Override
411 public InputStream[] getFilesAsStream(String name, boolean deleteOnClose)
412 throws IOException {
413
414 String[] fileNames = getFileNames(name);
415
416 if (fileNames == null) {
417 return null;
418 }
419
420 InputStream[] inputStreams = null;
421
422 FileItem[] liferayFileItems = _fileParameters.get(name);
423
424 if (ArrayUtil.isNotEmpty(liferayFileItems)) {
425 inputStreams = new InputStream[liferayFileItems.length];
426
427 for (int i = 0; i < liferayFileItems.length; i++) {
428 FileItem liferayFileItem = liferayFileItems[i];
429
430 if (Validator.isNotNull(liferayFileItem.getFileName())) {
431 inputStreams[i] = getInputStream(
432 liferayFileItem, deleteOnClose);
433 }
434 }
435 }
436
437 return inputStreams;
438 }
439
440 @Override
441 public String getFullFileName(String name) {
442 FileItem[] liferayFileItems = _fileParameters.get(name);
443
444 if (ArrayUtil.isNotEmpty(liferayFileItems)) {
445 FileItem liferayFileItem = liferayFileItems[0];
446
447 return liferayFileItem.getFullFileName();
448 }
449
450 return null;
451 }
452
453 @Override
454 public ServletInputStream getInputStream() throws IOException {
455 if (_liferayServletRequest != null) {
456 return _liferayServletRequest.getInputStream();
457 }
458
459 return super.getInputStream();
460 }
461
462 @Override
463 public Map<String, FileItem[]> getMultipartParameterMap() {
464 return _fileParameters;
465 }
466
467 @Override
468 public String getParameter(String name) {
469 List<String> values = _regularParameters.get(name);
470
471 if ((values != null) && !values.isEmpty()) {
472 return values.get(0);
473 }
474
475 return super.getParameter(name);
476 }
477
478 @Override
479 public Map<String, String[]> getParameterMap() {
480 Map<String, String[]> map = new HashMap<>();
481
482 Enumeration<String> enu = getParameterNames();
483
484 while (enu.hasMoreElements()) {
485 String name = enu.nextElement();
486
487 String[] values = getParameterValues(name);
488
489 if (values != null) {
490 map.put(name, values);
491 }
492 }
493
494 return map;
495 }
496
497 @Override
498 public Enumeration<String> getParameterNames() {
499 Set<String> parameterNames = new LinkedHashSet<>();
500
501 Enumeration<String> enu = super.getParameterNames();
502
503 while (enu.hasMoreElements()) {
504 parameterNames.add(enu.nextElement());
505 }
506
507 parameterNames.addAll(_regularParameters.keySet());
508 parameterNames.addAll(_fileParameters.keySet());
509
510 return Collections.enumeration(parameterNames);
511 }
512
513 @Override
514 public String[] getParameterValues(String name) {
515 String[] parameterValues = null;
516
517 List<String> values = _regularParameters.get(name);
518
519 if (values != null) {
520 parameterValues = values.toArray(new String[values.size()]);
521 }
522
523 String[] parentParameterValues = super.getParameterValues(name);
524
525 if (parameterValues == null) {
526 return parentParameterValues;
527 }
528 else if (parentParameterValues == null) {
529 return parameterValues;
530 }
531
532 return ArrayUtil.append(parameterValues, parentParameterValues);
533 }
534
535 @Override
536 public Map<String, List<String>> getRegularParameterMap() {
537 return _regularParameters;
538 }
539
540 @Override
541 public Long getSize(String name) {
542 FileItem[] liferayFileItems = _fileParameters.get(name);
543
544 if (ArrayUtil.isNotEmpty(liferayFileItems)) {
545 FileItem liferayFileItem = liferayFileItems[0];
546
547 return Long.valueOf(liferayFileItem.getSize());
548 }
549
550 return null;
551 }
552
553 @Override
554 public Boolean isFormField(String name) {
555 FileItem[] liferayFileItems = _fileParameters.get(name);
556
557 if (ArrayUtil.isNotEmpty(liferayFileItems)) {
558 FileItem liferayFileItem = liferayFileItems[0];
559
560 return liferayFileItem.isFormField();
561 }
562
563 return null;
564 }
565
566 protected InputStream getInputStream(
567 FileItem liferayFileItem, boolean deleteOnClose)
568 throws IOException {
569
570 InputStream inputStream = null;
571
572 if (liferayFileItem.isInMemory() && (liferayFileItem.getSize() > 0)) {
573 inputStream = liferayFileItem.getInputStream();
574 }
575 else if (!liferayFileItem.isInMemory()) {
576 inputStream = new ByteArrayFileInputStream(
577 liferayFileItem.getStoreLocation(),
578 liferayFileItem.getSizeThreshold(), deleteOnClose);
579 }
580
581 return inputStream;
582 }
583
584 protected List<org.apache.commons.fileupload.FileItem> sort(
585 List<org.apache.commons.fileupload.FileItem> fileItems) {
586
587 Map<String, GroupedFileItems> groupedFileItemsMap = new HashMap<>();
588
589 for (org.apache.commons.fileupload.FileItem fileItem : fileItems) {
590 String fieldName = fileItem.getFieldName();
591
592 GroupedFileItems groupedFileItems = groupedFileItemsMap.get(
593 fieldName);
594
595 if (groupedFileItems == null) {
596 groupedFileItems = new GroupedFileItems(fieldName);
597
598 groupedFileItemsMap.put(fieldName, groupedFileItems);
599 }
600
601 groupedFileItems.addFileItem(fileItem);
602 }
603
604 Set<GroupedFileItems> groupedFileItemsList = new TreeSet<>(
605 groupedFileItemsMap.values());
606
607 List<org.apache.commons.fileupload.FileItem> sortedFileItems =
608 new ArrayList<>();
609
610 for (GroupedFileItems groupedFileItems : groupedFileItemsList) {
611 sortedFileItems.addAll(groupedFileItems.getFileItems());
612 }
613
614 return sortedFileItems;
615 }
616
617 private static final Log _log = LogFactoryUtil.getLog(
618 UploadServletRequestImpl.class);
619
620 private static File _tempDir;
621
622 private final Map<String, FileItem[]> _fileParameters;
623 private final LiferayServletRequest _liferayServletRequest;
624 private final Map<String, List<String>> _regularParameters;
625
626 private class GroupedFileItems implements Comparable<GroupedFileItems> {
627
628 public GroupedFileItems(String key) {
629 _key = key;
630 }
631
632 public void addFileItem(
633 org.apache.commons.fileupload.FileItem fileItem) {
634
635 _fileItems.add(fileItem);
636
637 _fileItemsSize += fileItem.getSize();
638 }
639
640 @Override
641 public int compareTo(GroupedFileItems groupedFileItems) {
642 if (groupedFileItems == null) {
643 return 1;
644 }
645
646 if (equals(groupedFileItems)) {
647 return 0;
648 }
649
650 if (_key.equals(groupedFileItems._key)) {
651 return 1;
652 }
653
654 if (getFileItemsSize() >= groupedFileItems.getFileItemsSize()) {
655 return 1;
656 }
657
658 return -1;
659 }
660
661 public List<org.apache.commons.fileupload.FileItem> getFileItems() {
662 return _fileItems;
663 }
664
665 public int getFileItemsSize() {
666 return _fileItemsSize;
667 }
668
669 private final List<org.apache.commons.fileupload.FileItem> _fileItems =
670 new ArrayList<>();
671 private int _fileItemsSize;
672 private final String _key;
673
674 }
675
676 }