diff options
author | Raymond Auge | 2016-07-18 16:00:46 +0000 |
---|---|---|
committer | Thomas Watson | 2016-07-18 18:57:14 +0000 |
commit | 57395de0973cb0e0638525746aaaeb8aac03b352 (patch) | |
tree | 6989e9299892c4572147fdaf40c7eba0dee0567c | |
parent | 62a50bbac77fb5b15d47bb6acec67e27716dff0e (diff) | |
download | rt.equinox.bundles-57395de0973cb0e0638525746aaaeb8aac03b352.tar.gz rt.equinox.bundles-57395de0973cb0e0638525746aaaeb8aac03b352.tar.xz rt.equinox.bundles-57395de0973cb0e0638525746aaaeb8aac03b352.zip |
Bug 497271 - [http servlet] complete implementation of the multipart APIY20160721-1000
Signed-off-by: Raymond Auge <raymond.auge@liferay.com>
Signed-off-by: Raymond Auge <raymond.auge@liferay.com>
Change-Id: Ic2ff6bd6eda8c77e11b990700acffe974475eb09
32 files changed, 835 insertions, 272 deletions
diff --git a/bundles/org.eclipse.equinox.http.jetty9/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.http.jetty9/META-INF/MANIFEST.MF index 99da1ed3b..76a5c658c 100644 --- a/bundles/org.eclipse.equinox.http.jetty9/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.http.jetty9/META-INF/MANIFEST.MF @@ -4,7 +4,7 @@ Bundle-Name: %bundleName Bundle-Vendor: %providerName Bundle-Localization: plugin Bundle-SymbolicName: org.eclipse.equinox.http.jetty -Bundle-Version: 3.3.100.qualifier +Bundle-Version: 3.4.0.qualifier Bundle-Activator: org.eclipse.equinox.http.jetty.internal.Activator Import-Package: javax.servlet;version="[2.6.0,4.0.0)", javax.servlet.http;version="[2.6.0,4.0.0)", @@ -24,7 +24,7 @@ Import-Package: javax.servlet;version="[2.6.0,4.0.0)", org.osgi.service.cm;version="1.2.0", org.osgi.service.startlevel;version="1.0" Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Export-Package: org.eclipse.equinox.http.jetty;version="1.3.0" +Export-Package: org.eclipse.equinox.http.jetty;version="1.4.0" Comment-Header: Both Eclipse-LazyStart and Bundle-ActivationPolicy are specified for compatibility with 3.2 Eclipse-LazyStart: true Bundle-ActivationPolicy: lazy diff --git a/bundles/org.eclipse.equinox.http.jetty9/pom.xml b/bundles/org.eclipse.equinox.http.jetty9/pom.xml index e1f9f5c3a..c38ebeebb 100644 --- a/bundles/org.eclipse.equinox.http.jetty9/pom.xml +++ b/bundles/org.eclipse.equinox.http.jetty9/pom.xml @@ -5,7 +5,7 @@ are made available under the terms of the Eclipse Distribution License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/org/documents/edl-v10.php - + Contributors: Igor Fedorenko - initial implementation Raymond Augé - bug fixes and enhancements @@ -21,6 +21,6 @@ </parent> <groupId>org.eclipse.equinox</groupId> <artifactId>org.eclipse.equinox.http.jetty</artifactId> - <version>3.3.100-SNAPSHOT</version> + <version>3.4.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/bundles/org.eclipse.equinox.http.jetty9/src/org/eclipse/equinox/http/jetty/JettyConstants.java b/bundles/org.eclipse.equinox.http.jetty9/src/org/eclipse/equinox/http/jetty/JettyConstants.java index f4fae3cc4..e9483bfef 100644 --- a/bundles/org.eclipse.equinox.http.jetty9/src/org/eclipse/equinox/http/jetty/JettyConstants.java +++ b/bundles/org.eclipse.equinox.http.jetty9/src/org/eclipse/equinox/http/jetty/JettyConstants.java @@ -70,25 +70,25 @@ public interface JettyConstants { public static final String HTTP_MINTHREADS = "http.minThreads"; //$NON-NLS-1$ /** - * name="multipart.fileSizeThreshold" type="Integer" (default: 8 -- size threshold after which the file will be written to disk) + * @deprecated * @since 1.3 */ public static final String MULTIPART_FILESIZETHRESHOLD = "multipart.fileSizeThreshold"; //$NON-NLS-1$ /** - * name="multipart.location" type="String" (default: "" -- directory location where files will be stored) + * @deprecated * @since 1.3 */ public static final String MULTIPART_LOCATION = "multipart.location"; //$NON-NLS-1$ /** - * name="multipart.maxFileSize" type="Long" (default: -1L -- maximum size allowed for uploaded files) + * @deprecated * @since 1.3 */ public static final String MULTIPART_MAXFILESIZE = "multipart.maxFileSize"; //$NON-NLS-1$ /** - * name="multipart.maxRequestSize" type="Long" (default: -1L -- maximum size allowed for multipart/form-data requests) + * @deprecated * @since 1.3 */ public static final String MULTIPART_MAXREQUESTSIZE = "multipart.maxRequestSize"; //$NON-NLS-1$ diff --git a/bundles/org.eclipse.equinox.http.jetty9/src/org/eclipse/equinox/http/jetty/internal/HttpServerManager.java b/bundles/org.eclipse.equinox.http.jetty9/src/org/eclipse/equinox/http/jetty/internal/HttpServerManager.java index 4170a62e9..3e9cb6a31 100644 --- a/bundles/org.eclipse.equinox.http.jetty9/src/org/eclipse/equinox/http/jetty/internal/HttpServerManager.java +++ b/bundles/org.eclipse.equinox.http.jetty9/src/org/eclipse/equinox/http/jetty/internal/HttpServerManager.java @@ -23,7 +23,6 @@ import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionIdListener; import org.eclipse.equinox.http.jetty.JettyConstants; import org.eclipse.equinox.http.jetty.JettyCustomizer; -import org.eclipse.equinox.http.servlet.HttpServiceMultipartServlet; import org.eclipse.equinox.http.servlet.HttpServiceServlet; import org.eclipse.jetty.server.*; import org.eclipse.jetty.server.session.HashSessionManager; @@ -140,10 +139,6 @@ public class HttpServerManager implements ManagedServiceFactory { if (null != customizer) httpContext = (ServletContextHandler) customizer.customizeContext(httpContext, dictionary); - ServletHolder multiPartHolder = createMultipartNamedServlet(dictionary, multipartServletName); - // This servlet has no mapping as it's only used from named dispatcher - httpContext.getServletHandler().addServlet(multiPartHolder); - SessionManager sessionManager = httpContext.getSessionHandler().getSessionManager(); try { sessionManager.addEventListener((HttpSessionIdListener) holder.getServlet()); @@ -159,24 +154,6 @@ public class HttpServerManager implements ManagedServiceFactory { servers.put(pid, server); } - private ServletHolder createMultipartNamedServlet(@SuppressWarnings("rawtypes") Dictionary dictionary, String multipartServletName) { - int multipartFileSizeThreshold = Details.getInt(dictionary, JettyConstants.MULTIPART_FILESIZETHRESHOLD, 0); - String multipartLocation = Details.getString(dictionary, JettyConstants.MULTIPART_LOCATION, ""); //$NON-NLS-1$ - long multipartMaxFileSize = Details.getLong(dictionary, JettyConstants.MULTIPART_MAXFILESIZE, -1L); - long multipartMaxRequestSize = Details.getLong(dictionary, JettyConstants.MULTIPART_MAXREQUESTSIZE, -1L); - - ServletHolder holder = new ServletHolder(new InternalHttpServiceMultipartServlet()); - holder.setInitOrder(1); - holder.setName(multipartServletName); - holder.setInitParameter(Constants.SERVICE_VENDOR, "Eclipse.org"); //$NON-NLS-1$ - holder.setInitParameter(Constants.SERVICE_DESCRIPTION, multipartServletName); //$NON-NLS-1$ - - MultipartConfigElement multipartConfigElement = new MultipartConfigElement(multipartLocation, multipartMaxFileSize, multipartMaxRequestSize, multipartFileSizeThreshold); - holder.getRegistration().setMultipartConfig(multipartConfigElement); - - return holder; - } - private ServerConnector createHttpsConnector(@SuppressWarnings("rawtypes") Dictionary dictionary, Server server, HttpConfiguration http_config) { ServerConnector httpsConnector = null; if (Details.getBoolean(dictionary, JettyConstants.HTTPS_ENABLED, false)) { @@ -339,39 +316,6 @@ public class HttpServerManager implements ManagedServiceFactory { } } - public static class InternalHttpServiceMultipartServlet implements Servlet { - private Servlet httpServiceServlet = new HttpServiceMultipartServlet(); - private ClassLoader contextLoader; - - public void init(ServletConfig config) { - ServletContext context = config.getServletContext(); - contextLoader = (ClassLoader) context.getAttribute(INTERNAL_CONTEXT_CLASSLOADER); - } - - public void destroy() { - contextLoader = null; - } - - public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { - Thread thread = Thread.currentThread(); - ClassLoader current = thread.getContextClassLoader(); - thread.setContextClassLoader(contextLoader); - try { - httpServiceServlet.service(req, res); - } finally { - thread.setContextClassLoader(current); - } - } - - public ServletConfig getServletConfig() { - return httpServiceServlet.getServletConfig(); - } - - public String getServletInfo() { - return httpServiceServlet.getServletInfo(); - } - } - // deleteDirectory is a convenience method to recursively delete a directory private static boolean deleteDirectory(File directory) { if (directory.exists() && directory.isDirectory()) { diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/pom.xml b/bundles/org.eclipse.equinox.http.servlet.tests/pom.xml index b9e033efb..a67b23de4 100644 --- a/bundles/org.eclipse.equinox.http.servlet.tests/pom.xml +++ b/bundles/org.eclipse.equinox.http.servlet.tests/pom.xml @@ -46,7 +46,7 @@ <requirement> <type>eclipse-plugin</type> <id>org.eclipse.equinox.http.jetty</id> - <versionRange>3.3.0</versionRange> + <versionRange>3.4.0</versionRange> </requirement> </extraRequirements> </dependency-resolution> diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/ServletTest.java b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/ServletTest.java index 099130400..254440b64 100644 --- a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/ServletTest.java +++ b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/ServletTest.java @@ -17,6 +17,7 @@ import static org.junit.Assert.*; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; import java.io.PrintWriter; import java.lang.reflect.InvocationTargetException; @@ -111,8 +112,8 @@ import org.osgi.service.http.whiteboard.HttpWhiteboardConstants; public class ServletTest extends BaseTest { @Rule public TestName testName = new TestName(); - - + + @Test public void test_ErrorPage1() throws Exception { String expected = "403 ERROR :"; @@ -1910,15 +1911,15 @@ public class ServletTest extends BaseTest { Assert.assertEquals("b", requestAdvisor.request("files/help.txt")); } - private static String getSubmittedFileName(Part part) { - for (String cd : part.getHeader("content-disposition").split(";")) { - if (cd.trim().startsWith("filename")) { - String fileName = cd.substring(cd.indexOf('=') + 1).trim().replace("\"", ""); - return fileName.substring(fileName.lastIndexOf('/') + 1).substring(fileName.lastIndexOf('\\') + 1); // MSIE fix. - } - } - return null; - } +// private static String getSubmittedFileName(Part part) { +// for (String cd : part.getHeader("content-disposition").split(";")) { +// if (cd.trim().startsWith("filename")) { +// String fileName = cd.substring(cd.indexOf('=') + 1).trim().replace("\"", ""); +// return fileName.substring(fileName.lastIndexOf('/') + 1).substring(fileName.lastIndexOf('\\') + 1); // MSIE fix. +// } +// } +// return null; +// } /* * 3.1 file uploads @@ -1961,14 +1962,38 @@ public class ServletTest extends BaseTest { Map<String, List<String>> result = requestAdvisor.upload("Servlet16/do", map); Assert.assertEquals("200", result.get("responseCode").get(0)); - Assert.assertEquals("resource1.txt|text/plain|1", result.get("responseBody").get(0)); + Assert.assertEquals("resource1.txt|text/plain|25", result.get("responseBody").get(0)); + } + + @Test + public void test_Servlet16_notEnabled() throws Exception { + Servlet servlet = new HttpServlet() { + private static final long serialVersionUID = 1L; + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws IOException, ServletException { + + req.getPart("file"); + } + }; + + Dictionary<String, Object> props = new Hashtable<String, Object>(); + props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S16"); + props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/Servlet16/*"); + registrations.add(getBundleContext().registerService(Servlet.class, servlet, props)); + + Map<String, List<Object>> map = new HashMap<String, List<Object>>(); + + map.put("file", Arrays.<Object>asList(getClass().getResource("resource1.txt"))); + + Map<String, List<String>> result = requestAdvisor.upload("Servlet16/do", map); + + Assert.assertEquals("500", result.get("responseCode").get(0)); } - /* - * 3.0 file uploads - */ @Test - public void test_Servlet17() throws Exception { + public void test_Servlet16_fileuploadWithLocation() throws Exception { Servlet servlet = new HttpServlet() { private static final long serialVersionUID = 1L; @@ -1979,16 +2004,22 @@ public class ServletTest extends BaseTest { Part part = req.getPart("file"); Assert.assertNotNull(part); - String submittedFileName = getSubmittedFileName(part); + String submittedFileName = part.getSubmittedFileName(); String contentType = part.getContentType(); long size = part.getSize(); + File tempDir = (File)getServletContext().getAttribute(ServletContext.TEMPDIR); + File location = new File(tempDir, "file-upload-test"); + + File[] listFiles = location.listFiles(); + PrintWriter writer = resp.getWriter(); writer.write(submittedFileName); writer.write("|"); writer.write(contentType); writer.write("|" + size); + writer.write("|" + listFiles.length); } }; @@ -1996,19 +2027,176 @@ public class ServletTest extends BaseTest { props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S16"); props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/Servlet16/*"); props.put("equinox.http.multipartSupported", Boolean.TRUE); + props.put("equinox.http.whiteboard.servlet.multipart.location", "file-upload-test"); registrations.add(getBundleContext().registerService(Servlet.class, servlet, props)); Map<String, List<Object>> map = new HashMap<String, List<Object>>(); - map.put("file", Arrays.<Object>asList(getClass().getResource("blue.png"))); + map.put("file", Arrays.<Object>asList(getClass().getResource("resource1.txt"))); Map<String, List<String>> result = requestAdvisor.upload("Servlet16/do", map); Assert.assertEquals("200", result.get("responseCode").get(0)); - Assert.assertEquals("blue.png|image/png|292", result.get("responseBody").get(0)); + Assert.assertEquals("resource1.txt|text/plain|25|0", result.get("responseBody").get(0)); } @Test + public void test_Servlet16_fileuploadWithLocationAndThreshold() throws Exception { + Servlet servlet = new HttpServlet() { + private static final long serialVersionUID = 1L; + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws IOException, ServletException { + + Part part = req.getPart("file"); + Assert.assertNotNull(part); + + String submittedFileName = part.getSubmittedFileName(); + String contentType = part.getContentType(); + long size = part.getSize(); + + File tempDir = (File)getServletContext().getAttribute(ServletContext.TEMPDIR); + File location = new File(tempDir, "file-upload-test"); + + File[] listFiles = location.listFiles(); + + PrintWriter writer = resp.getWriter(); + + writer.write(submittedFileName); + writer.write("|"); + writer.write(contentType); + writer.write("|" + size); + writer.write("|" + listFiles.length); + } + }; + + Dictionary<String, Object> props = new Hashtable<String, Object>(); + props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S16"); + props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/Servlet16/*"); + props.put("equinox.http.multipartSupported", Boolean.TRUE); + props.put("equinox.http.whiteboard.servlet.multipart.location", "file-upload-test"); + props.put("equinox.http.whiteboard.servlet.multipart.fileSizeThreshold", 10); + registrations.add(getBundleContext().registerService(Servlet.class, servlet, props)); + + Map<String, List<Object>> map = new HashMap<String, List<Object>>(); + + map.put("file", Arrays.<Object>asList(getClass().getResource("resource1.txt"))); + + Map<String, List<String>> result = requestAdvisor.upload("Servlet16/do", map); + + Assert.assertEquals("200", result.get("responseCode").get(0)); + Assert.assertEquals("resource1.txt|text/plain|25|1", result.get("responseBody").get(0)); + } + + @Test + public void test_Servlet16_fileuploadWithLocationMaxFileSize() throws Exception { + Servlet servlet = new HttpServlet() { + private static final long serialVersionUID = 1L; + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws IOException, ServletException { + + req.getPart("file"); + } + }; + + Dictionary<String, Object> props = new Hashtable<String, Object>(); + props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S16"); + props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/Servlet16/*"); + props.put("equinox.http.multipartSupported", Boolean.TRUE); + props.put("equinox.http.whiteboard.servlet.multipart.location", "file-upload-test"); + // Note the actual uploaded file size is 25bytes + props.put("equinox.http.whiteboard.servlet.multipart.maxFileSize", 24L); + registrations.add(getBundleContext().registerService(Servlet.class, servlet, props)); + + Map<String, List<Object>> map = new HashMap<String, List<Object>>(); + + map.put("file", Arrays.<Object>asList(getClass().getResource("resource1.txt"))); + + Map<String, List<String>> result = requestAdvisor.upload("Servlet16/do", map); + + Assert.assertEquals("500", result.get("responseCode").get(0)); + } + + @Test + public void test_Servlet16_fileuploadWithLocationMaxRequestSize() throws Exception { + Servlet servlet = new HttpServlet() { + private static final long serialVersionUID = 1L; + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws IOException, ServletException { + + req.getPart("file"); + } + }; + + Dictionary<String, Object> props = new Hashtable<String, Object>(); + props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S16"); + props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/Servlet16/*"); + props.put("equinox.http.multipartSupported", Boolean.TRUE); + props.put("equinox.http.whiteboard.servlet.multipart.location", "file-upload-test"); + // Note the actual uploaded file size is 25bytes, but you also need room for the rest of the headers + props.put("equinox.http.whiteboard.servlet.multipart.maxRequestSize", 26L); + registrations.add(getBundleContext().registerService(Servlet.class, servlet, props)); + + Map<String, List<Object>> map = new HashMap<String, List<Object>>(); + + map.put("file", Arrays.<Object>asList(getClass().getResource("resource1.txt"))); + + Map<String, List<String>> result = requestAdvisor.upload("Servlet16/do", map); + + Assert.assertEquals("500", result.get("responseCode").get(0)); + } + + /* + * 3.0 file uploads + */ +// This is commented due to a bug in commons-fileupload which was subsequently fixed in later versions. +// @Test +// public void test_Servlet17() throws Exception { +// Servlet servlet = new HttpServlet() { +// private static final long serialVersionUID = 1L; +// +// @Override +// protected void doPost(HttpServletRequest req, HttpServletResponse resp) +// throws IOException, ServletException { +// +// Part part = req.getPart("file"); +// Assert.assertNotNull(part); +// +// String submittedFileName = getSubmittedFileName(part); +// String contentType = part.getContentType(); +// long size = part.getSize(); +// +// PrintWriter writer = resp.getWriter(); +// +// writer.write(submittedFileName); +// writer.write("|"); +// writer.write(contentType); +// writer.write("|" + size); +// } +// }; +// +// Dictionary<String, Object> props = new Hashtable<String, Object>(); +// props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S16"); +// props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/Servlet16/*"); +// props.put("equinox.http.multipartSupported", Boolean.TRUE); +// registrations.add(getBundleContext().registerService(Servlet.class, servlet, props)); +// +// Map<String, List<Object>> map = new HashMap<String, List<Object>>(); +// +// map.put("file", Arrays.<Object>asList(getClass().getResource("blue.png"))); +// +// Map<String, List<String>> result = requestAdvisor.upload("Servlet16/do", map); +// +// Assert.assertEquals("200", result.get("responseCode").get(0)); +// Assert.assertEquals("blue.png|image/png|292", result.get("responseBody").get(0)); +// } + + @Test public void test_commonsFileUpload() throws Exception { Servlet servlet = new HttpServlet() { private static final long serialVersionUID = 1L; diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/resource1.txt b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/resource1.txt index 2e65efe2a..d16f7afbc 100644 --- a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/resource1.txt +++ b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/resource1.txt @@ -1 +1,3 @@ -a
\ No newline at end of file +a + +Do NOT edit this File!
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.http.servlet/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.http.servlet/META-INF/MANIFEST.MF index fd1c5c07a..2ec3648aa 100644 --- a/bundles/org.eclipse.equinox.http.servlet/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.http.servlet/META-INF/MANIFEST.MF @@ -3,15 +3,19 @@ Bundle-ManifestVersion: 2 Bundle-Name: %bundleName Bundle-Vendor: %providerName Bundle-SymbolicName: org.eclipse.equinox.http.servlet -Bundle-Version: 1.3.100.qualifier +Bundle-Version: 1.4.0.qualifier Bundle-Activator: org.eclipse.equinox.http.servlet.internal.Activator Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Export-Package: org.eclipse.equinox.http.servlet;version="1.2.0", - org.eclipse.equinox.http.servlet.context; x-internal:=true;version="1.0.0" -Import-Package: javax.servlet;version="[2.3.0,4.0.0)", - javax.servlet.annotation;version="2.6.0";resolution:=optional, - javax.servlet.descriptor;version="2.6.0";resolution:=optional, + org.eclipse.equinox.http.servlet.context;version="1.0.0";x-internal:=true, + org.eclipse.equinox.http.servlet.dto;version="1.0.0";x-internal:=true +Import-Package: org.apache.commons.fileupload;version="[1.2.2, 2.0.0)";resolution:=optional, + org.apache.commons.fileupload.disk;version="[1.2.2, 2.0.0)";resolution:=optional, + org.apache.commons.fileupload.servlet;version="[1.2.2, 2.0.0)";resolution:=optional, + javax.servlet;version="[2.3.0,4.0.0)", + javax.servlet.annotation;version="[2.6.0,4.0.0)";resolution:=optional, + javax.servlet.descriptor;version="[2.6.0,4.0.0)";resolution:=optional, javax.servlet.http;version="[2.3.0,4.0.0)", org.osgi.dto;version="[1.0.0,2.0)", org.osgi.framework;version="[1.3.0,2.0)", diff --git a/bundles/org.eclipse.equinox.http.servlet/META-INF/services/org.eclipse.equinox.http.servlet.internal.multipart.MultipartSupportFactory b/bundles/org.eclipse.equinox.http.servlet/META-INF/services/org.eclipse.equinox.http.servlet.internal.multipart.MultipartSupportFactory new file mode 100644 index 000000000..28ed86bab --- /dev/null +++ b/bundles/org.eclipse.equinox.http.servlet/META-INF/services/org.eclipse.equinox.http.servlet.internal.multipart.MultipartSupportFactory @@ -0,0 +1 @@ +org.eclipse.equinox.http.servlet.internal.multipart.MultipartSupportFactoryImpl
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.http.servlet/pom.xml b/bundles/org.eclipse.equinox.http.servlet/pom.xml index ff19811a3..4ac97a862 100644 --- a/bundles/org.eclipse.equinox.http.servlet/pom.xml +++ b/bundles/org.eclipse.equinox.http.servlet/pom.xml @@ -5,7 +5,7 @@ are made available under the terms of the Eclipse Distribution License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/org/documents/edl-v10.php - + Contributors: Igor Fedorenko - initial implementation Raymond Augé - bug fixes and enhancements @@ -20,6 +20,6 @@ </parent> <groupId>org.eclipse.equinox</groupId> <artifactId>org.eclipse.equinox.http.servlet</artifactId> - <version>1.3.100-SNAPSHOT</version> + <version>1.4.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/HttpServiceMultipartServlet.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/HttpServiceMultipartServlet.java index 67dbd6c13..b9a4529f6 100644 --- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/HttpServiceMultipartServlet.java +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/HttpServiceMultipartServlet.java @@ -10,43 +10,13 @@ *******************************************************************************/ package org.eclipse.equinox.http.servlet; -import org.eclipse.equinox.http.servlet.internal.servlet.ProxyMultipartServlet; +import javax.servlet.http.HttpServlet; /** - * The HttpServiceMultipartServlet is the "public" side of a Servlet that when registered (and init() called) in a servlet container - * will be used by the OSGi Http Service implementation to handle multipart requests. This servlet must be paired with, - * and initialized after an HttpServiceServlet. The HttpServiceServlet must be told the name of the multipart servlet it is paired with - * using the init-param "multipart.servlet.name". - * <p> - * e.g.<br/> - * <pre> - * <servlet> - * <servlet-name>Equinox Http Service Servlet</servlet-name> - * <servlet-class>org.eclipse.equinox.http.servlet.HttpServiceServlet</servlet-class> - * <init-param> - * <param-name>multipart.servlet.name</param-name> - * <param-value>Equinox Http Service Multipart Servlet</param-value> - * </init-param> - * <load-on-startup>0</load-on-startup> - * </servlet> - * <servlet> - * <servlet-name>Equinox Http Service Multipart Servlet</servlet-name> - * <servlet-class>org.eclipse.equinox.http.servlet.HttpServiceMultipartServlet</servlet-class> - * <load-on-startup>1</load-on-startup> - * <multipart-config> - * <location></location> - * <max-file-size>-1</max-file-size> - * <max-request-size>-1</max-request-size> - * <file-size-threshold>0</file-size-threshold> - * </multipart-config> - * </servlet> - * </pre> - * </p> - * This class is not meant for extending or even using directly and is purely meant for registering - * in a servlet container. * @noextend This class is not intended to be subclassed by clients. + * @deprecated No longer required. * @since 1.3 */ -public class HttpServiceMultipartServlet extends ProxyMultipartServlet { +public class HttpServiceMultipartServlet extends HttpServlet { private static final long serialVersionUID = 2281118780429323631L; } diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/dto/ExtendedFailedServletDTO.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/dto/ExtendedFailedServletDTO.java new file mode 100644 index 000000000..1aa43409b --- /dev/null +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/dto/ExtendedFailedServletDTO.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2016 Raymond Augé and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Raymond Augé <raymond.auge@liferay.com> - Bug 497271 + ******************************************************************************/ + +package org.eclipse.equinox.http.servlet.dto; + +import org.osgi.service.http.runtime.dto.FailedServletDTO; + +/** + * This type may become irrelevant if the properties appear as part of a + * future OSGi Http Whiteboard specification. + */ +public class ExtendedFailedServletDTO extends FailedServletDTO { + + /** + * Specifies whether multipart support is enabled. + */ + public boolean multipartEnabled; + + /** + * Specifies the size threshold after which the file will be written to disk. + */ + public int multipartFileSizeThreshold; + + /** + * Specifies the location where the files can be stored on disk. + */ + public String multipartLocation; + + /** + * Specifies the maximum size of a file being uploaded. + */ + public long multipartMaxFileSize; + + /** + * Specifies the maximum request size. + */ + public long multipartMaxRequestSize; + +}
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/dto/ExtendedServletDTO.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/dto/ExtendedServletDTO.java new file mode 100644 index 000000000..982966a08 --- /dev/null +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/dto/ExtendedServletDTO.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2016 Raymond Augé. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Raymond Augé <raymond.auge@liferay.com> - Bug 497271 + ******************************************************************************/ + +package org.eclipse.equinox.http.servlet.dto; + +import org.osgi.service.http.runtime.dto.ServletDTO; + +/** + * This type may become irrelevant if the properties appear as part of a + * future OSGi Http Whiteboard specification. + */ +public class ExtendedServletDTO extends ServletDTO { + + /** + * Specifies whether multipart support is enabled. + */ + public boolean multipartEnabled; + + /** + * Specifies the size threshold after which the file will be written to disk. + */ + public int multipartFileSizeThreshold; + + /** + * Specifies the location where the files can be stored on disk. + */ + public String multipartLocation; + + /** + * Specifies the maximum size of a file being uploaded. + */ + public long multipartMaxFileSize; + + /** + * Specifies the maximum request size. + */ + public long multipartMaxRequestSize; + +}
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceImpl.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceImpl.java index 78a139ffd..cfd00e1ad 100644 --- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceImpl.java +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceImpl.java @@ -21,6 +21,7 @@ import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.equinox.http.servlet.ExtendedHttpService; +import org.eclipse.equinox.http.servlet.internal.util.Throw; import org.osgi.framework.Bundle; import org.osgi.service.http.*; @@ -99,7 +100,7 @@ public class HttpServiceImpl implements HttpService, ExtendedHttpService { }); } catch (PrivilegedActionException e) { - unchecked(e.getException()); + Throw.unchecked(e.getException()); } } @@ -123,7 +124,7 @@ public class HttpServiceImpl implements HttpService, ExtendedHttpService { } }); } catch (PrivilegedActionException e) { - unchecked(e.getException()); + Throw.unchecked(e.getException()); } } @@ -149,7 +150,7 @@ public class HttpServiceImpl implements HttpService, ExtendedHttpService { } }); } catch (PrivilegedActionException e) { - unchecked(e.getException()); + Throw.unchecked(e.getException()); } } @@ -184,13 +185,4 @@ public class HttpServiceImpl implements HttpService, ExtendedHttpService { "Service instance is already shutdown"); //$NON-NLS-1$ } } - - static <T> T unchecked(Exception exception) { - return HttpServiceImpl.<T, RuntimeException> unchecked0(exception); - } - - @SuppressWarnings("unchecked") - private static <T, E extends Exception> T unchecked0(Exception exception) throws E { - throw (E) exception; - } } diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java index 6e5c7e40b..9d39f3e98 100644 --- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java @@ -22,6 +22,7 @@ import javax.servlet.Filter; import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionListener; import org.eclipse.equinox.http.servlet.context.ContextPathCustomizer; +import org.eclipse.equinox.http.servlet.dto.ExtendedFailedServletDTO; import org.eclipse.equinox.http.servlet.internal.context.*; import org.eclipse.equinox.http.servlet.internal.error.*; import org.eclipse.equinox.http.servlet.internal.servlet.Match; @@ -467,11 +468,11 @@ public class HttpServiceRuntimeImpl } private FailedServletDTO[] getFailedServletDTOs() { - Collection<FailedServletDTO> fsDTOs = failedServletDTOs.values(); + Collection<ExtendedFailedServletDTO> fsDTOs = failedServletDTOs.values(); List<FailedServletDTO> copies = new ArrayList<FailedServletDTO>(); - for (FailedServletDTO failedServletDTO : fsDTOs) { + for (ExtendedFailedServletDTO failedServletDTO : fsDTOs) { copies.add(DTOUtil.clone(failedServletDTO)); } @@ -1019,7 +1020,7 @@ public class HttpServiceRuntimeImpl public void recordFailedServletDTO( ServiceReference<Servlet> serviceReference, - FailedServletDTO failedServletDTO) { + ExtendedFailedServletDTO failedServletDTO) { if (failedServletDTOs.containsKey(serviceReference)) { return; @@ -1092,8 +1093,8 @@ public class HttpServiceRuntimeImpl new ConcurrentHashMap<ServiceReference<Object>, FailedResourceDTO>(); private final ConcurrentMap<ServiceReference<ServletContextHelper>, FailedServletContextDTO> failedServletContextDTOs = new ConcurrentHashMap<ServiceReference<ServletContextHelper>, FailedServletContextDTO>(); - private final ConcurrentMap<ServiceReference<Servlet>, FailedServletDTO> failedServletDTOs = - new ConcurrentHashMap<ServiceReference<Servlet>, FailedServletDTO>(); + private final ConcurrentMap<ServiceReference<Servlet>, ExtendedFailedServletDTO> failedServletDTOs = + new ConcurrentHashMap<ServiceReference<Servlet>, ExtendedFailedServletDTO>(); private AtomicLong legacyIdGenerator = new AtomicLong(0); @@ -1131,7 +1132,7 @@ public class HttpServiceRuntimeImpl public void checkForError() { Exception result = error.get(); if (result != null) { - HttpServiceImpl.unchecked(result); + Throw.unchecked(result); } } } @@ -1169,7 +1170,7 @@ public class HttpServiceRuntimeImpl error.set(null); } catch (Exception e){ error.set(e); - HttpServiceImpl.unchecked(e); + Throw.unchecked(e); } } @@ -1205,7 +1206,7 @@ public class HttpServiceRuntimeImpl error.set(null); } catch (Exception e){ error.set(e); - HttpServiceImpl.unchecked(e); + Throw.unchecked(e); } } diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ContextController.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ContextController.java index 8b731bf7b..9af775c60 100644 --- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ContextController.java +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ContextController.java @@ -21,9 +21,9 @@ import java.util.regex.Pattern; import javax.servlet.*; import javax.servlet.Filter; import javax.servlet.http.*; +import org.eclipse.equinox.http.servlet.dto.ExtendedServletDTO; import org.eclipse.equinox.http.servlet.internal.HttpServiceRuntimeImpl; import org.eclipse.equinox.http.servlet.internal.customizer.*; -import org.eclipse.equinox.http.servlet.internal.dto.ExtendedServletDTO; import org.eclipse.equinox.http.servlet.internal.error.*; import org.eclipse.equinox.http.servlet.internal.registration.*; import org.eclipse.equinox.http.servlet.internal.registration.FilterRegistration; @@ -424,8 +424,10 @@ public class ContextController { try { resourceRegistration.init(servletConfig); } - catch (ServletException e) { - return null; + catch (Throwable t) { + resourceRegistration.destroy(); + + return Throw.unchecked(t); } endpointRegistrations.add(resourceRegistration); @@ -451,6 +453,10 @@ public class ContextController { } } finally { if (registration == null) { + // Always attempt to release here; even though destroy() may have been called + // on the registration while failing to add. There are cases where no + // ServletRegistration may have even been created at all to call destory() on. + // Also, addedRegisteredObject may be false which means we never call doAddServletRegistration servletHolder.release(); if (addedRegisteredObject) { httpServiceRuntime.getRegisteredObjects().remove(servlet); @@ -483,8 +489,16 @@ public class ContextController { String generatedServletName = ServiceProperties.parseName( servletRef.getProperty( HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME), servletHolder.get()); - boolean multipartSupported = ServiceProperties.parseBoolean( - servletRef, Const.EQUINOX_HTTP_MULTIPARTSUPPORTED); + boolean multipartEnabled = ServiceProperties.parseBoolean( + servletRef, Const.EQUINOX_HTTP_MULTIPART_ENABLED); + Integer multipartFileSizeThreshold = (Integer)servletRef.getProperty( + Const.EQUINOX_HTTP_MULTIPART_FILESIZETHRESHOLD); + String multipartLocation = (String)servletRef.getProperty( + Const.EQUINOX_HTTP_MULTIPART_LOCATION); + Long multipartMaxFileSize = (Long)servletRef.getProperty( + Const.EQUINOX_HTTP_MULTIPART_MAXFILESIZE); + Long multipartMaxRequestSize = (Long)servletRef.getProperty( + Const.EQUINOX_HTTP_MULTIPART_MAXREQUESTSIZE); if (((patterns == null) || (patterns.length == 0)) && ((errorPages == null) || errorPages.length == 0) && @@ -512,7 +526,11 @@ public class ContextController { servletDTO.asyncSupported = asyncSupported; servletDTO.initParams = servletInitParams; - servletDTO.multipartSupported = multipartSupported; + servletDTO.multipartEnabled = multipartEnabled; + servletDTO.multipartFileSizeThreshold = (multipartFileSizeThreshold != null ? multipartFileSizeThreshold : 0); + servletDTO.multipartLocation = (multipartLocation != null ? multipartLocation : Const.BLANK); + servletDTO.multipartMaxFileSize = (multipartMaxFileSize != null ? multipartMaxFileSize : -1L); + servletDTO.multipartMaxRequestSize = (multipartMaxRequestSize != null ? multipartMaxRequestSize : -1L); servletDTO.name = generatedServletName; servletDTO.patterns = sort(patterns); servletDTO.serviceId = serviceId; @@ -572,11 +590,18 @@ public class ContextController { servletHolder.getBundle(), curServletContextHelper); ServletRegistration servletRegistration = new ServletRegistration( servletHolder, servletDTO, errorPageDTO, curServletContextHelper, this, - legacyTCCL); + servletContext, legacyTCCL); ServletConfig servletConfig = new ServletConfigImpl( generatedServletName, servletInitParams, servletContext); - servletRegistration.init(servletConfig); + try { + servletRegistration.init(servletConfig); + } + catch (Throwable t) { + servletRegistration.destroy(); + + return Throw.unchecked(t); + } endpointRegistrations.add(servletRegistration); diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextResourceTrackerCustomizer.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextResourceTrackerCustomizer.java index 59e405c44..33df57cdc 100644 --- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextResourceTrackerCustomizer.java +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextResourceTrackerCustomizer.java @@ -57,8 +57,8 @@ public class ContextResourceTrackerCustomizer recordFailedResourceDTO(serviceReference, hwfe.getFailureReason()); } - catch (Exception e) { - httpServiceRuntime.log(e.getMessage(), e); + catch (Throwable t) { + httpServiceRuntime.log(t.getMessage(), t); recordFailedResourceDTO(serviceReference, DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT); } diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextServletTrackerCustomizer.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextServletTrackerCustomizer.java index 388352af5..6fb80e2cb 100644 --- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextServletTrackerCustomizer.java +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextServletTrackerCustomizer.java @@ -13,6 +13,7 @@ package org.eclipse.equinox.http.servlet.internal.customizer; import java.util.concurrent.atomic.AtomicReference; import javax.servlet.Servlet; +import org.eclipse.equinox.http.servlet.dto.ExtendedFailedServletDTO; import org.eclipse.equinox.http.servlet.internal.HttpServiceRuntimeImpl; import org.eclipse.equinox.http.servlet.internal.context.ContextController; import org.eclipse.equinox.http.servlet.internal.error.HttpWhiteboardFailureException; @@ -20,7 +21,6 @@ import org.eclipse.equinox.http.servlet.internal.registration.ServletRegistratio import org.eclipse.equinox.http.servlet.internal.util.*; import org.osgi.framework.*; import org.osgi.service.http.runtime.dto.DTOConstants; -import org.osgi.service.http.runtime.dto.FailedServletDTO; import org.osgi.service.http.whiteboard.HttpWhiteboardConstants; /** @@ -59,8 +59,8 @@ public class ContextServletTrackerCustomizer recordFailedServletDTO(serviceReference, hwfe.getFailureReason()); } - catch (Exception e) { - httpServiceRuntime.log(e.getMessage(), e); + catch (Throwable t) { + httpServiceRuntime.log(t.getMessage(), t); recordFailedServletDTO(serviceReference, DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT); } @@ -94,13 +94,32 @@ public class ContextServletTrackerCustomizer private void recordFailedServletDTO( ServiceReference<Servlet> serviceReference, int failureReason) { - FailedServletDTO failedServletDTO = new FailedServletDTO(); + ExtendedFailedServletDTO failedServletDTO = new ExtendedFailedServletDTO(); failedServletDTO.asyncSupported = BooleanPlus.from( serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ASYNC_SUPPORTED), false); failedServletDTO.failureReason = failureReason; failedServletDTO.initParams = ServiceProperties.parseInitParams( serviceReference, HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX); + failedServletDTO.multipartEnabled = ServiceProperties.parseBoolean( + serviceReference, Const.EQUINOX_HTTP_MULTIPART_ENABLED); + Integer multipartFileSizeThreshold = (Integer)serviceReference.getProperty( + Const.EQUINOX_HTTP_MULTIPART_FILESIZETHRESHOLD); + if (multipartFileSizeThreshold != null) { + failedServletDTO.multipartFileSizeThreshold = multipartFileSizeThreshold; + } + failedServletDTO.multipartLocation = (String)serviceReference.getProperty( + Const.EQUINOX_HTTP_MULTIPART_LOCATION); + Long multipartMaxFileSize = (Long)serviceReference.getProperty( + Const.EQUINOX_HTTP_MULTIPART_MAXFILESIZE); + if (multipartMaxFileSize != null) { + failedServletDTO.multipartMaxFileSize = multipartMaxFileSize; + } + Long multipartMaxRequestSize = (Long)serviceReference.getProperty( + Const.EQUINOX_HTTP_MULTIPART_MAXREQUESTSIZE); + if (multipartMaxRequestSize != null) { + failedServletDTO.multipartMaxRequestSize = multipartMaxRequestSize; + } failedServletDTO.name = (String)serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME); failedServletDTO.patterns = StringPlus.from( serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN)).toArray(new String[0]); diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/dto/ExtendedServletDTO.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/dto/ExtendedServletDTO.java deleted file mode 100644 index 88dccf5d7..000000000 --- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/dto/ExtendedServletDTO.java +++ /dev/null @@ -1,18 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016 Raymond Augé. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Raymond Augé - Initial implementation - ******************************************************************************/ - -package org.eclipse.equinox.http.servlet.internal.dto; - -import org.osgi.service.http.runtime.dto.ServletDTO; - -public class ExtendedServletDTO extends ServletDTO { - public boolean multipartSupported = false; -}
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupport.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupport.java new file mode 100644 index 000000000..a45c43ae9 --- /dev/null +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupport.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2016 Raymond Augé and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Raymond Augé <raymond.auge@liferay.com> - Bug 497271 + *******************************************************************************/ +package org.eclipse.equinox.http.servlet.internal.multipart; + +import java.io.IOException; +import java.util.Map; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.Part; + +public interface MultipartSupport { + + public Map<String, Part> parseRequest(HttpServletRequest request) throws IOException, ServletException; + +}
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportFactory.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportFactory.java new file mode 100644 index 000000000..60c61c955 --- /dev/null +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportFactory.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2016 Raymond Augé and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Raymond Augé <raymond.auge@liferay.com> - Bug 497271 + *******************************************************************************/ +package org.eclipse.equinox.http.servlet.internal.multipart; + +import javax.servlet.ServletContext; +import org.eclipse.equinox.http.servlet.dto.ExtendedServletDTO; + +public interface MultipartSupportFactory { + + MultipartSupport newInstance(ExtendedServletDTO servletDTO, ServletContext servletContext); + +}
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportFactoryImpl.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportFactoryImpl.java new file mode 100644 index 000000000..bb54ca080 --- /dev/null +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportFactoryImpl.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2016 Raymond Augé and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Raymond Augé <raymond.auge@liferay.com> - Bug 497271 + *******************************************************************************/ +package org.eclipse.equinox.http.servlet.internal.multipart; + +import javax.servlet.ServletContext; +import org.apache.commons.fileupload.FileUploadException; +import org.eclipse.equinox.http.servlet.dto.ExtendedServletDTO; + +public class MultipartSupportFactoryImpl + implements MultipartSupportFactory { + + public static final Class<?> FAIL_EARLY = FileUploadException.class; + + @Override + public MultipartSupport newInstance(ExtendedServletDTO servletDTO, ServletContext servletContext) { + return new MultipartSupportImpl(servletDTO, servletContext); + } + +}
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportImpl.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportImpl.java new file mode 100644 index 000000000..e235758d0 --- /dev/null +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportImpl.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright (c) 2016 Raymond Augé and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Raymond Augé <raymond.auge@liferay.com> - Bug 497271 + *******************************************************************************/ +package org.eclipse.equinox.http.servlet.internal.multipart; + +import java.io.*; +import java.security.AccessControlContext; +import java.util.HashMap; +import java.util.Map; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.Part; +import org.apache.commons.fileupload.FileUploadException; +import org.apache.commons.fileupload.disk.DiskFileItem; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.eclipse.equinox.http.servlet.dto.ExtendedServletDTO; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +public class MultipartSupportImpl implements MultipartSupport { + + public MultipartSupportImpl(ExtendedServletDTO servletDTO, ServletContext servletContext) { + this.servletDTO = servletDTO; + + // Must return non-null File. See Servlet 3.1 §4.8.1 + File baseStorage = (File)servletContext.getAttribute(ServletContext.TEMPDIR); + + if (servletDTO.multipartLocation.length() > 0) { + File storage = new File(servletDTO.multipartLocation); + + if (!storage.isAbsolute()) { + storage = new File(baseStorage, storage.getPath()); + } + + baseStorage = storage; + } + + checkPermission(baseStorage, servletContext); + + baseStorage.mkdirs(); + + DiskFileItemFactory factory = new DiskFileItemFactory(); + + factory.setRepository(baseStorage); + + if (servletDTO.multipartFileSizeThreshold > 0) { + factory.setSizeThreshold(servletDTO.multipartFileSizeThreshold); + } + + upload = new ServletFileUpload(factory); + + if (servletDTO.multipartMaxFileSize > -1L) { + upload.setFileSizeMax(servletDTO.multipartMaxFileSize); + } + + if (servletDTO.multipartMaxRequestSize > -1L) { + upload.setSizeMax(servletDTO.multipartMaxRequestSize); + } + } + + private void checkPermission(File baseStorage, ServletContext servletContext) { + BundleContext bundleContext = (BundleContext)servletContext.getAttribute("osgi-bundlecontext"); //$NON-NLS-1$ + Bundle bundle = bundleContext.getBundle(); + AccessControlContext accessControlContext = bundle.adapt(AccessControlContext.class); + if (accessControlContext == null) return; + accessControlContext.checkPermission(new FilePermission(baseStorage.getAbsolutePath(), "read,write")); //$NON-NLS-1$ + } + + public Map<String, Part> parseRequest(HttpServletRequest request) throws IOException, ServletException { + if (upload == null) { + throw new IllegalStateException("Servlet was not configured for multipart!"); //$NON-NLS-1$ + } + + if (!servletDTO.multipartEnabled) { + throw new IllegalStateException("No multipart config on " + servletDTO); //$NON-NLS-1$ + } + + if (!ServletFileUpload.isMultipartContent(request)) { + throw new ServletException("Not a multipart request!"); //$NON-NLS-1$ + } + + Map<String, Part> parts = new HashMap<String, Part>(); + + try { + for (Object item : upload.parseRequest(request)) { + DiskFileItem diskFileItem = (DiskFileItem)item; + + parts.put(diskFileItem.getFieldName(), new MultipartSupportPart(diskFileItem)); + } + } + catch (FileUploadException fnfe) { + throw new IOException(fnfe); + } + + return parts; + } + + private final ExtendedServletDTO servletDTO; + private final ServletFileUpload upload; + + +}
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportPart.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportPart.java new file mode 100644 index 000000000..1902a8ffa --- /dev/null +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportPart.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2016 Raymond Augé and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Raymond Augé <raymond.auge@liferay.com> - Bug 497271 + *******************************************************************************/ +package org.eclipse.equinox.http.servlet.internal.multipart; + +import java.io.*; +import java.util.*; +import javax.servlet.http.Part; +import org.apache.commons.fileupload.FileItemHeaders; +import org.apache.commons.fileupload.disk.DiskFileItem; + +public class MultipartSupportPart implements Part { + + public MultipartSupportPart(DiskFileItem item) { + this.item = item; + this.headers = item.getHeaders(); + } + + @Override + public InputStream getInputStream() throws IOException { + return item.getInputStream(); + } + + @Override + public String getContentType() { + return item.getContentType(); + } + + @Override + public String getName() { + return item.getFieldName(); + } + + @Override + public String getSubmittedFileName() { + return item.getName(); + } + + @Override + public long getSize() { + return item.getSize(); + } + + @Override + public void write(String fileName) throws IOException { + try { + item.write(new File(item.getStoreLocation(), fileName)); + } + catch (Exception e) { + throw new IOException(e); + } + } + + @Override + public void delete() { + item.delete(); + } + + @Override + public String getHeader(String name) { + if (headers == null) { + return null; + } + return headers.getHeader(name); + } + + @Override + public Collection<String> getHeaders(String name) { + if (headers == null) { + return Collections.emptyList(); + } + return new IteratorCollection(headers.getHeaders(name)); + } + + @Override + public Collection<String> getHeaderNames() { + if (headers == null) { + return Collections.emptyList(); + } + return new IteratorCollection(headers.getHeaderNames()); + } + + private final DiskFileItem item; + private final FileItemHeaders headers; + + private class IteratorCollection extends AbstractList<String> { + + public IteratorCollection(Iterator<String> iterator) { + this.collection = new ArrayList<String>(); + while (iterator.hasNext()) { + collection.add(iterator.next()); + } + } + + @Override + public String get(int index) { + return collection.get(index); + } + + @Override + public int size() { + return collection.size(); + } + + private List<String> collection; + + } + +} diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/EndpointRegistration.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/EndpointRegistration.java index b16bb7451..067a04fc8 100644 --- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/EndpointRegistration.java +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/EndpointRegistration.java @@ -47,6 +47,7 @@ public abstract class EndpointRegistration<D extends DTO> } else { classLoader = servletHolder.getBundle().adapt(BundleWiring.class).getClassLoader(); } + createContextAttributes(); } public void destroy() { @@ -86,19 +87,13 @@ public abstract class EndpointRegistration<D extends DTO> //Delegate the init call to the actual servlet public void init(ServletConfig servletConfig) throws ServletException { - boolean initialized = false; ClassLoader original = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(classLoader); - createContextAttributes(); getT().init(servletConfig); - initialized = true; } finally { - if (!initialized) { - destroyContextAttributes(); - } Thread.currentThread().setContextClassLoader(original); } } diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ServletRegistration.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ServletRegistration.java index 127330bc1..63267f9e5 100644 --- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ServletRegistration.java +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ServletRegistration.java @@ -12,10 +12,16 @@ *******************************************************************************/ package org.eclipse.equinox.http.servlet.internal.registration; -import javax.servlet.Servlet; +import java.io.IOException; +import java.util.*; +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.Part; +import org.eclipse.equinox.http.servlet.dto.ExtendedServletDTO; import org.eclipse.equinox.http.servlet.internal.context.ContextController; import org.eclipse.equinox.http.servlet.internal.context.ContextController.ServiceHolder; -import org.eclipse.equinox.http.servlet.internal.dto.ExtendedServletDTO; +import org.eclipse.equinox.http.servlet.internal.multipart.MultipartSupport; +import org.eclipse.equinox.http.servlet.internal.multipart.MultipartSupportFactory; import org.eclipse.equinox.http.servlet.internal.servlet.Match; import org.osgi.service.http.context.ServletContextHelper; import org.osgi.service.http.runtime.dto.ErrorPageDTO; @@ -23,14 +29,43 @@ import org.osgi.service.http.runtime.dto.ErrorPageDTO; //This class wraps the servlet object registered in the HttpService.registerServlet call, to manage the context classloader when handleRequests are being asked. public class ServletRegistration extends EndpointRegistration<ExtendedServletDTO> { + private static MultipartSupportFactory factory; + + static { + ServiceLoader<MultipartSupportFactory> loader = ServiceLoader.load(MultipartSupportFactory.class); + + Iterator<MultipartSupportFactory> iterator = loader.iterator(); + + while (iterator.hasNext()) { + try { + factory = iterator.next(); + break; + } + catch (Throwable t) { + // ignore, it means our optional imports are missing. + } + } + } + public ServletRegistration( ServiceHolder<Servlet> servletHolder, ExtendedServletDTO servletDTO, ErrorPageDTO errorPageDTO, ServletContextHelper servletContextHelper, - ContextController contextController, ClassLoader legacyTCCL) { + ContextController contextController, ServletContext servletContext, ClassLoader legacyTCCL) { super(servletHolder, servletDTO, servletContextHelper, contextController, legacyTCCL); this.errorPageDTO = errorPageDTO; + + if (servletDTO.multipartEnabled) { + if (factory == null) { + throw new IllegalStateException( + "Multipart support not enabled due to missing, optional commons-fileupload dependency!"); //$NON-NLS-1$ + } + multipartSupport = factory.newInstance(servletDTO, servletContext); + } + else { + multipartSupport = null; + } } public ErrorPageDTO getErrorPageDTO() { @@ -74,6 +109,15 @@ public class ServletRegistration extends EndpointRegistration<ExtendedServletDTO return super.match(name, servletPath, pathInfo, extension, match); } - private ErrorPageDTO errorPageDTO; + public Map<String, Part> parseRequest(HttpServletRequest request) throws IOException, ServletException { + if (multipartSupport == null) { + throw new IOException("Servlet not configured for multipart!"); //$NON-NLS-1$ + } + + return multipartSupport.parseRequest(request); + } + + private final ErrorPageDTO errorPageDTO; + private final MultipartSupport multipartSupport; } diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpServletRequestWrapperImpl.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpServletRequestWrapperImpl.java index 6bcb869f4..30f03be2e 100644 --- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpServletRequestWrapperImpl.java +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpServletRequestWrapperImpl.java @@ -12,11 +12,15 @@ *******************************************************************************/ package org.eclipse.equinox.http.servlet.internal.servlet; +import java.io.IOException; import java.util.*; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import javax.servlet.*; import javax.servlet.http.*; import org.eclipse.equinox.http.servlet.internal.context.ContextController; import org.eclipse.equinox.http.servlet.internal.context.DispatchTargets; +import org.eclipse.equinox.http.servlet.internal.registration.EndpointRegistration; import org.eclipse.equinox.http.servlet.internal.util.Const; import org.eclipse.equinox.http.servlet.internal.util.EventListeners; import org.osgi.service.http.HttpContext; @@ -25,6 +29,8 @@ public class HttpServletRequestWrapperImpl extends HttpServletRequestWrapper { private final Stack<DispatchTargets> dispatchTargets = new Stack<DispatchTargets>(); private final HttpServletRequest request; + private Map<String, Part> parts; + private final Lock lock = new ReentrantLock(); private static final String[] dispatcherAttributes = new String[] { RequestDispatcher.ERROR_EXCEPTION, @@ -400,4 +406,45 @@ public class HttpServletRequestWrapperImpl extends HttpServletRequestWrapper { } } + @Override + public Part getPart(String name) throws IOException, ServletException { + return getParts0().get(name); + } + + @Override + public Collection<Part> getParts() throws IOException, ServletException { + return new ArrayList<Part>(getParts0().values()); + } + + private Map<String, Part> getParts0() throws IOException, ServletException { + org.eclipse.equinox.http.servlet.internal.registration.ServletRegistration servletRegistration = getServletRegistration(); + + if (servletRegistration == null) { + throw new ServletException("Not a servlet request!"); //$NON-NLS-1$ + } + + lock.lock(); + + try { + if (parts != null) { + return parts; + } + + return parts = servletRegistration.parseRequest(this); + } + finally { + lock.unlock(); + } + } + + private org.eclipse.equinox.http.servlet.internal.registration.ServletRegistration getServletRegistration() { + EndpointRegistration<?> servletRegistration = dispatchTargets.peek().getServletRegistration(); + + if (servletRegistration instanceof org.eclipse.equinox.http.servlet.internal.registration.ServletRegistration) { + return (org.eclipse.equinox.http.servlet.internal.registration.ServletRegistration)servletRegistration; + } + + return null; + } + }
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyMultipartServlet.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyMultipartServlet.java deleted file mode 100644 index 7ad41de9d..000000000 --- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyMultipartServlet.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016 Raymond Augé and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Raymond Augé - initial implementation - *******************************************************************************/ -package org.eclipse.equinox.http.servlet.internal.servlet; - -import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.*; -import org.eclipse.equinox.http.servlet.internal.context.DispatchTargets; -import org.eclipse.equinox.http.servlet.internal.util.Const; - -/** - * The ProxyMultipartServlet is the private side of a Servlet that when registered (and init() called) in a servlet container - * will handle all multipart requests targeted toward it's associated ProxyServlet. - * This class is not meant for extending or even using directly and is purely meant for registering - * in a servlet container. - */ -public class ProxyMultipartServlet extends HttpServlet { - - private static final long serialVersionUID = -9079427283290998897L; - - protected void service( - HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - - String alias = HttpServletRequestWrapperImpl.getDispatchPathInfo(request); - - if (alias == null) { - alias = Const.SLASH; - } - - DispatchTargets dispatchTargets = (DispatchTargets)request.getAttribute(DispatchTargets.class.getName()); - - if (dispatchTargets != null) { - request.removeAttribute(DispatchTargets.class.getName()); - - dispatchTargets.doDispatch( - request, response, alias, request.getDispatcherType()); - - return; - } - - response.sendError( - HttpServletResponse.SC_NOT_FOUND, "ProxyMultipartServlet: " + alias); //$NON-NLS-1$ - } - -} diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyServlet.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyServlet.java index 302dec12c..08ec8f160 100644 --- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyServlet.java +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyServlet.java @@ -18,8 +18,6 @@ import javax.servlet.http.*; import org.eclipse.equinox.http.servlet.internal.Activator; import org.eclipse.equinox.http.servlet.internal.HttpServiceRuntimeImpl; import org.eclipse.equinox.http.servlet.internal.context.DispatchTargets; -import org.eclipse.equinox.http.servlet.internal.registration.EndpointRegistration; -import org.eclipse.equinox.http.servlet.internal.registration.ServletRegistration; import org.eclipse.equinox.http.servlet.internal.util.Const; /** @@ -31,15 +29,11 @@ import org.eclipse.equinox.http.servlet.internal.util.Const; public class ProxyServlet extends HttpServlet { private static final long serialVersionUID = 4117456123807468871L; - protected static final String MULTIPART_SERVLET_NAME_KEY = "multipart.servlet.name"; //$NON-NLS-1$ private HttpServiceRuntimeImpl httpServiceRuntimeImpl; - private String multipartServletName; public void init(ServletConfig config) throws ServletException { super.init(config); - multipartServletName = getInitParameter(MULTIPART_SERVLET_NAME_KEY); - Activator.addProxyServlet(this); } @@ -76,26 +70,6 @@ public class ProxyServlet extends HttpServlet { DispatchTargets dispatchTargets = httpServiceRuntimeImpl.getDispatchTargets(alias, null); - if ((dispatchTargets != null) && (multipartServletName != null)) { - EndpointRegistration<?> endpointRegistration = dispatchTargets.getServletRegistration(); - - if (endpointRegistration instanceof ServletRegistration) { - ServletRegistration servletRegistration = (ServletRegistration)endpointRegistration; - - if (servletRegistration.getD().multipartSupported) { - RequestDispatcher multipartDispatcher = getServletContext().getNamedDispatcher(multipartServletName); - - if (multipartDispatcher != null) { - request.setAttribute(DispatchTargets.class.getName(), dispatchTargets); - - multipartDispatcher.forward(request, response); - - return; - } - } - } - } - if (dispatchTargets != null) { dispatchTargets.doDispatch( request, response, alias, request.getDispatcherType()); diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/Const.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/Const.java index 651e527ec..d577c056f 100644 --- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/Const.java +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/Const.java @@ -32,7 +32,11 @@ public class Const { public static final String SLASH_STAR = "/*"; //$NON-NLS-1$ public static final String SLASH_STAR_DOT = "/*."; //$NON-NLS-1$ public static final String STAR_DOT = "*."; //$NON-NLS-1$ - public static final String EQUINOX_HTTP_MULTIPARTSUPPORTED = "equinox.http.multipartSupported"; //$NON-NLS-1$ + public static final String EQUINOX_HTTP_MULTIPART_ENABLED = "equinox.http.multipartSupported"; //$NON-NLS-1$ + public static final String EQUINOX_HTTP_MULTIPART_FILESIZETHRESHOLD = "equinox.http.whiteboard.servlet.multipart.fileSizeThreshold"; //$NON-NLS-1$ + public static final String EQUINOX_HTTP_MULTIPART_LOCATION = "equinox.http.whiteboard.servlet.multipart.location"; //$NON-NLS-1$ + public static final String EQUINOX_HTTP_MULTIPART_MAXFILESIZE = "equinox.http.whiteboard.servlet.multipart.maxFileSize"; //$NON-NLS-1$ + public static final String EQUINOX_HTTP_MULTIPART_MAXREQUESTSIZE = "equinox.http.whiteboard.servlet.multipart.maxRequestSize"; //$NON-NLS-1$ public static final String EQUINOX_LEGACY_TCCL_PROP = "equinox.legacy.tccl"; //$NON-NLS-1$ public static final String EQUINOX_LEGACY_CONTEXT_SELECT = "equinox.context.select"; //$NON-NLS-1$ public static final String EQUINOX_LEGACY_CONTEXT_HELPER = "equinox.legacy.context.helper"; //$NON-NLS-1$ diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/DTOUtil.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/DTOUtil.java index 883d715c8..5667c9f06 100644 --- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/DTOUtil.java +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/DTOUtil.java @@ -13,7 +13,8 @@ package org.eclipse.equinox.http.servlet.internal.util; import java.lang.reflect.Array; import java.util.*; -import org.eclipse.equinox.http.servlet.internal.dto.ExtendedServletDTO; +import org.eclipse.equinox.http.servlet.dto.ExtendedFailedServletDTO; +import org.eclipse.equinox.http.servlet.dto.ExtendedServletDTO; import org.osgi.dto.DTO; import org.osgi.service.http.runtime.dto.*; @@ -95,12 +96,17 @@ public class DTOUtil { return clone; } - public static FailedServletDTO clone(FailedServletDTO original) { - FailedServletDTO clone = new FailedServletDTO(); + public static ExtendedFailedServletDTO clone(ExtendedFailedServletDTO original) { + ExtendedFailedServletDTO clone = new ExtendedFailedServletDTO(); clone.asyncSupported = copy(original.asyncSupported); clone.failureReason = copy(original.failureReason); clone.initParams = copyStringMap(clone.initParams); + clone.multipartEnabled = copy(original.multipartEnabled); + clone.multipartFileSizeThreshold = copy(original.multipartFileSizeThreshold); + clone.multipartLocation = copy(original.multipartLocation); + clone.multipartMaxFileSize = copy(original.multipartMaxFileSize); + clone.multipartMaxRequestSize = copy(original.multipartMaxRequestSize); clone.name = copy(original.name); clone.patterns = copy(original.patterns); clone.serviceId = copy(original.serviceId); @@ -152,7 +158,11 @@ public class DTOUtil { clone.asyncSupported = copy(original.asyncSupported); clone.initParams = copyStringMap(original.initParams); - clone.multipartSupported = copy(original.multipartSupported); + clone.multipartEnabled = copy(original.multipartEnabled); + clone.multipartFileSizeThreshold = copy(original.multipartFileSizeThreshold); + clone.multipartLocation = copy(original.multipartLocation); + clone.multipartMaxFileSize = copy(original.multipartMaxFileSize); + clone.multipartMaxRequestSize = copy(original.multipartMaxRequestSize); clone.name = copy(original.name); clone.patterns = copy(original.patterns); clone.serviceId = copy(original.serviceId); diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/Throw.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/Throw.java new file mode 100644 index 000000000..85206d131 --- /dev/null +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/Throw.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2016 Raymond Augé and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Raymond Augé <raymond.auge@liferay.com> - Bug 497271 + *******************************************************************************/ +package org.eclipse.equinox.http.servlet.internal.util; + +public class Throw { + + public static <T> T unchecked(Throwable throwable) { + return Throw.<T, RuntimeException>unchecked0(throwable); + } + + @SuppressWarnings("unchecked") + private static <T, E extends Throwable> T unchecked0(Throwable throwable) throws E { + throw (E) throwable; + } + +}
\ No newline at end of file |