Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Auge2016-07-18 16:00:46 +0000
committerThomas Watson2016-07-18 18:57:14 +0000
commit57395de0973cb0e0638525746aaaeb8aac03b352 (patch)
tree6989e9299892c4572147fdaf40c7eba0dee0567c
parent62a50bbac77fb5b15d47bb6acec67e27716dff0e (diff)
downloadrt.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
-rw-r--r--bundles/org.eclipse.equinox.http.jetty9/META-INF/MANIFEST.MF4
-rw-r--r--bundles/org.eclipse.equinox.http.jetty9/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.http.jetty9/src/org/eclipse/equinox/http/jetty/JettyConstants.java8
-rw-r--r--bundles/org.eclipse.equinox.http.jetty9/src/org/eclipse/equinox/http/jetty/internal/HttpServerManager.java56
-rw-r--r--bundles/org.eclipse.equinox.http.servlet.tests/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/ServletTest.java226
-rw-r--r--bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/resource1.txt4
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/META-INF/MANIFEST.MF14
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/META-INF/services/org.eclipse.equinox.http.servlet.internal.multipart.MultipartSupportFactory1
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/HttpServiceMultipartServlet.java36
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/dto/ExtendedFailedServletDTO.java47
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/dto/ExtendedServletDTO.java47
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceImpl.java16
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java17
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ContextController.java41
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextResourceTrackerCustomizer.java4
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextServletTrackerCustomizer.java27
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/dto/ExtendedServletDTO.java18
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupport.java23
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportFactory.java20
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportFactoryImpl.java27
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportImpl.java111
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportPart.java116
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/EndpointRegistration.java7
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ServletRegistration.java52
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpServletRequestWrapperImpl.java47
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyMultipartServlet.java54
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyServlet.java26
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/Const.java6
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/DTOUtil.java18
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/Throw.java24
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 99da1ed3..76a5c658 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 e1f9f5c3..c38ebeeb 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 f4fae3cc..e9483bfe 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 4170a62e..3e9cb6a3 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 b9e033ef..a67b23de 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 09913040..254440b6 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 2e65efe2..d16f7afb 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 fd1c5c07..2ec3648a 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 00000000..28ed86ba
--- /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 ff19811a..4ac97a86 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 67dbd6c1..b9a4529f 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>
- * &lt;servlet>
- * &lt;servlet-name>Equinox Http Service Servlet&lt;/servlet-name>
- * &lt;servlet-class>org.eclipse.equinox.http.servlet.HttpServiceServlet&lt;/servlet-class>
- * &lt;init-param>
- * &lt;param-name>multipart.servlet.name&lt;/param-name>
- * &lt;param-value>Equinox Http Service Multipart Servlet&lt;/param-value>
- * &lt;/init-param>
- * &lt;load-on-startup>0&lt;/load-on-startup>
- * &lt;/servlet>
- * &lt;servlet>
- * &lt;servlet-name>Equinox Http Service Multipart Servlet&lt;/servlet-name>
- * &lt;servlet-class>org.eclipse.equinox.http.servlet.HttpServiceMultipartServlet&lt;/servlet-class>
- * &lt;load-on-startup>1&lt;/load-on-startup>
- * &lt;multipart-config>
- * &lt;location>&lt;/location>
- * &lt;max-file-size>-1&lt;/max-file-size>
- * &lt;max-request-size>-1&lt;/max-request-size>
- * &lt;file-size-threshold>0&lt;/file-size-threshold>
- * &lt;/multipart-config>
- * &lt;/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 00000000..1aa43409
--- /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 00000000..982966a0
--- /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 78a139ff..cfd00e1a 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 6e5c7e40..9d39f3e9 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 8b731bf7..9af775c6 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 59e405c4..33df57cd 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 388352af..6fb80e2c 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 88dccf5d..00000000
--- 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 00000000..a45c43ae
--- /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 00000000..60c61c95
--- /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 00000000..bb54ca08
--- /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 00000000..e235758d
--- /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 00000000..1902a8ff
--- /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 b16bb745..067a04fc 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 127330bc..63267f9e 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 6bcb869f..30f03be2 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 7ad41de9..00000000
--- 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 302dec12..08ec8f16 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 651e527e..d577c056 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 883d715c..5667c9f0 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 00000000..85206d13
--- /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

Back to the top