Bug 536708 - Multipart request responded with 302 under Jetty

Change-Id: I1434aa0eb991ced8c20dab264e5735cfce7c8666
Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
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 de740d4..fe0f8cc 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
@@ -3309,6 +3309,98 @@
 	}
 
 	@Test
+	public void test_getRequestURI_trailingSlash1() throws Exception {
+		try {
+			stopJetty();
+			System.setProperty("org.eclipse.equinox.http.jetty.context.path", "/foo");
+		}
+		finally {
+			startJetty();
+		}
+
+		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
+		try {
+			final AtomicReference<String> getRequestURI = new AtomicReference<String>();
+
+			Servlet servletA = new HttpServlet() {
+				private static final long serialVersionUID = 1L;
+				@Override
+				protected void service(HttpServletRequest req, HttpServletResponse resp)
+					throws IOException, ServletException {
+					getRequestURI.set(req.getRequestURI());
+				}
+			};
+
+			Dictionary<String, Object> props = new Hashtable<String, Object>();
+			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "SA");
+			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/*");
+			registrations.add(getBundleContext().registerService(Servlet.class, servletA, props));
+			props = new Hashtable<String, Object>();
+
+			requestAdvisor.request("a/b/c/");
+			Assert.assertEquals("/foo/a/b/c/", getRequestURI.get());
+			requestAdvisor.request("a/b/");
+			Assert.assertEquals("/foo/a/b/", getRequestURI.get());
+			requestAdvisor.request("a/");
+			Assert.assertEquals("/foo/a/", getRequestURI.get());
+			requestAdvisor.request("/");
+			Assert.assertEquals("/foo/", getRequestURI.get());
+		}
+		finally {
+			for (ServiceRegistration<?> registration : registrations) {
+				registration.unregister();
+			}
+			try {
+				stopJetty();
+				System.setProperty("org.eclipse.equinox.http.jetty.context.path", "");
+			}
+			finally {
+				startJetty();
+			}
+		}
+	}
+
+	@Test
+	public void test_getRequestURI_trailingSlash2() throws Exception {
+		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
+		try {
+			final AtomicReference<String> getRequestURI = new AtomicReference<String>();
+
+			Servlet servletA = new HttpServlet() {
+				private static final long serialVersionUID = 1L;
+				@Override
+				protected void service(HttpServletRequest req, HttpServletResponse resp)
+					throws IOException, ServletException {
+					getRequestURI.set(req.getRequestURI());
+				}
+			};
+
+			Dictionary<String, Object> props = new Hashtable<String, Object>();
+			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "SA");
+			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/*");
+			registrations.add(getBundleContext().registerService(Servlet.class, servletA, props));
+			props = new Hashtable<String, Object>();
+
+			requestAdvisor.request("a/b/c/");
+			Assert.assertEquals("/a/b/c/", getRequestURI.get());
+			requestAdvisor.request("a/b/");
+			Assert.assertEquals("/a/b/", getRequestURI.get());
+			requestAdvisor.request("a/");
+			Assert.assertEquals("/a/", getRequestURI.get());
+			// Note using empty string here because of the way requestAdvisor works
+			// by appending a slash first.
+			requestAdvisor.request("");
+			Assert.assertEquals("/", getRequestURI.get());
+		}
+		finally {
+			for (ServiceRegistration<?> registration : registrations) {
+				registration.unregister();
+			}
+		}
+	}
+
+
+	@Test
 	public void test_Listener1() throws Exception {
 		BaseServletContextListener scl1 =
 			new BaseServletContextListener();
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 805aaf4..db26e9d 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
@@ -67,6 +67,7 @@
 		}
 		String requestUri = HttpServletRequestWrapperImpl.getDispatchRequestURI(request);
 		
+		// NOTE split does not include trailing empty strings for paths that end in SLASH
 		String[] pathInfoSegments = pathInfo.split(Const.SLASH);
 		String[] requestUriSegments = requestUri.split(Const.SLASH);
 		
@@ -78,6 +79,10 @@
 		for(int i=(requestUriSegments.length - pathInfoSegments.length + 1);i<requestUriSegments.length;i++) {
 			aliasBuilder.append(Const.SLASH).append(requestUriSegments[i]);
 		}
+		// if the original request ends in '/' then be sure to append a '/'
+		if (requestUri.endsWith(Const.SLASH)) {
+			aliasBuilder.append(Const.SLASH);
+		}
 		return aliasBuilder.toString();
 	}