1 /******************************************************************************* 2 * Copyright (c) 2016, 2019 Raymond Augé and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * Raymond Augé <raymond.auge@liferay.com> - Bug 497271 13 *******************************************************************************/ 14 package org.eclipse.equinox.http.servlet.internal.multipart; 15 16 import java.io.*; 17 import java.security.AccessControlContext; 18 import java.util.HashMap; 19 import java.util.Map; 20 import javax.servlet.ServletContext; 21 import javax.servlet.ServletException; 22 import javax.servlet.http.HttpServletRequest; 23 import javax.servlet.http.Part; 24 import org.apache.commons.fileupload.FileUploadException; 25 import org.apache.commons.fileupload.disk.DiskFileItem; 26 import org.apache.commons.fileupload.disk.DiskFileItemFactory; 27 import org.apache.commons.fileupload.servlet.ServletFileUpload; 28 import org.osgi.framework.Bundle; 29 import org.osgi.framework.BundleContext; 30 import org.osgi.service.http.runtime.dto.ServletDTO; 31 32 public class MultipartSupportImpl implements MultipartSupport { 33 MultipartSupportImpl(ServletDTO servletDTO, ServletContext servletContext)34 public MultipartSupportImpl(ServletDTO servletDTO, ServletContext servletContext) { 35 this.servletDTO = servletDTO; 36 37 // Must return non-null File. See Servlet 3.1 §4.8.1 38 File baseStorage = (File)servletContext.getAttribute(ServletContext.TEMPDIR); 39 40 if (servletDTO.multipartLocation.length() > 0) { 41 File storage = new File(servletDTO.multipartLocation); 42 43 if (!storage.isAbsolute()) { 44 storage = new File(baseStorage, storage.getPath()); 45 } 46 47 baseStorage = storage; 48 } 49 50 checkPermission(baseStorage, servletContext); 51 52 baseStorage.mkdirs(); 53 54 DiskFileItemFactory factory = new DiskFileItemFactory(); 55 56 factory.setRepository(baseStorage); 57 58 if (servletDTO.multipartFileSizeThreshold > 0) { 59 factory.setSizeThreshold(servletDTO.multipartFileSizeThreshold); 60 } 61 62 upload = new ServletFileUpload(factory); 63 64 if (servletDTO.multipartMaxFileSize > -1L) { 65 upload.setFileSizeMax(servletDTO.multipartMaxFileSize); 66 } 67 68 if (servletDTO.multipartMaxRequestSize > -1L) { 69 upload.setSizeMax(servletDTO.multipartMaxRequestSize); 70 } 71 } 72 checkPermission(File baseStorage, ServletContext servletContext)73 private void checkPermission(File baseStorage, ServletContext servletContext) { 74 BundleContext bundleContext = (BundleContext)servletContext.getAttribute("osgi-bundlecontext"); //$NON-NLS-1$ 75 Bundle bundle = bundleContext.getBundle(); 76 AccessControlContext accessControlContext = bundle.adapt(AccessControlContext.class); 77 if (accessControlContext == null) return; 78 accessControlContext.checkPermission(new FilePermission(baseStorage.getAbsolutePath(), "read,write")); //$NON-NLS-1$ 79 } 80 81 @Override parseRequest(HttpServletRequest request)82 public Map<String, Part> parseRequest(HttpServletRequest request) throws IOException, ServletException { 83 if (upload == null) { 84 throw new IllegalStateException("Servlet was not configured for multipart!"); //$NON-NLS-1$ 85 } 86 87 if (!servletDTO.multipartEnabled) { 88 throw new IllegalStateException("No multipart config on " + servletDTO); //$NON-NLS-1$ 89 } 90 91 if (!ServletFileUpload.isMultipartContent(request)) { 92 throw new ServletException("Not a multipart request!"); //$NON-NLS-1$ 93 } 94 95 Map<String, Part> parts = new HashMap<String, Part>(); 96 97 try { 98 for (Object item : upload.parseRequest(request)) { 99 DiskFileItem diskFileItem = (DiskFileItem)item; 100 101 parts.put(diskFileItem.getFieldName(), new MultipartSupportPart(diskFileItem)); 102 } 103 } 104 catch (FileUploadException fnfe) { 105 throw new IOException(fnfe); 106 } 107 108 return parts; 109 } 110 111 private final ServletDTO servletDTO; 112 private final ServletFileUpload upload; 113 114 115 }