Bug 510038 - [http] Tests failing on linux.gtk.x86_64 for M-builds

Signed-off-by: Raymond Auge <raymond.auge@liferay.com>
diff --git a/bundles/org.eclipse.equinox.http.jetty/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.http.jetty/META-INF/MANIFEST.MF
index 20ec86b..556c13d 100644
--- a/bundles/org.eclipse.equinox.http.jetty/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.http.jetty/META-INF/MANIFEST.MF
@@ -4,7 +4,7 @@
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Bundle-SymbolicName: org.eclipse.equinox.http.jetty
-Bundle-Version: 3.5.0.qualifier
+Bundle-Version: 3.6.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)",
diff --git a/bundles/org.eclipse.equinox.http.jetty/pom.xml b/bundles/org.eclipse.equinox.http.jetty/pom.xml
index ace398f..5ecf1b1 100644
--- a/bundles/org.eclipse.equinox.http.jetty/pom.xml
+++ b/bundles/org.eclipse.equinox.http.jetty/pom.xml
@@ -21,6 +21,6 @@
   </parent>
   <groupId>org.eclipse.equinox</groupId>
   <artifactId>org.eclipse.equinox.http.jetty</artifactId>
-  <version>3.5.0-SNAPSHOT</version>
+  <version>3.6.0-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 </project>
diff --git a/bundles/org.eclipse.equinox.http.jetty/src/org/eclipse/equinox/http/jetty/internal/HttpServerManager.java b/bundles/org.eclipse.equinox.http.jetty/src/org/eclipse/equinox/http/jetty/internal/HttpServerManager.java
index c830b30..3d4e58f 100644
--- a/bundles/org.eclipse.equinox.http.jetty/src/org/eclipse/equinox/http/jetty/internal/HttpServerManager.java
+++ b/bundles/org.eclipse.equinox.http.jetty/src/org/eclipse/equinox/http/jetty/internal/HttpServerManager.java
@@ -122,18 +122,25 @@
 			if (port == -1)
 				port = httpConnector.getPort();
 			holder.setInitParameter(JettyConstants.HTTP_PORT, Integer.toString(port));
+			String host = httpConnector.getHost();
+			if (host != null)
+				holder.setInitParameter(JettyConstants.HTTP_HOST, host);
 		}
 		if (httpsConnector != null) {
 			int port = httpsConnector.getLocalPort();
 			if (port == -1)
 				port = httpsConnector.getPort();
 			holder.setInitParameter(JettyConstants.HTTPS_PORT, Integer.toString(port));
+			String host = httpConnector.getHost();
+			if (host != null)
+				holder.setInitParameter(JettyConstants.HTTPS_HOST, host);
 		}
 		String otherInfo = Details.getString(dictionary, JettyConstants.OTHER_INFO, null);
 		if (otherInfo != null)
 			holder.setInitParameter(JettyConstants.OTHER_INFO, otherInfo);
 
 		ServletContextHandler httpContext = createHttpContext(dictionary);
+		holder.setInitParameter(JettyConstants.CONTEXT_PATH, httpContext.getContextPath());
 		httpContext.addServlet(holder, "/*"); //$NON-NLS-1$
 		server.setHandler(httpContext);
 
diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/pom.xml b/bundles/org.eclipse.equinox.http.servlet.tests/pom.xml
index 7810450..20ecdc8 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.4.0</versionRange>
+                   <versionRange>3.6.0</versionRange>
                 </requirement>
              </extraRequirements>
           </dependency-resolution>
diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/testbase/BaseTest.java b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/testbase/BaseTest.java
index 9aaabd1..8e4fff9 100644
--- a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/testbase/BaseTest.java
+++ b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/testbase/BaseTest.java
@@ -14,9 +14,15 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintWriter;
+import java.lang.reflect.Array;
+import java.lang.reflect.ParameterizedType;
+import java.net.URL;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -47,6 +53,10 @@
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.http.HttpService;
 import org.osgi.service.http.context.ServletContextHelper;
+import org.osgi.service.http.runtime.HttpServiceRuntime;
+import org.osgi.service.http.runtime.HttpServiceRuntimeConstants;
+import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
+import org.osgi.util.tracker.ServiceTracker;
 
 public class BaseTest {
 
@@ -57,15 +67,15 @@
 		System.setProperty("org.eclipse.jetty.server.LEVEL", "OFF");
 		System.setProperty("org.eclipse.jetty.servlet.LEVEL", "OFF");
 
-		System.setProperty("org.osgi.service.http.port", "8090");
+		System.setProperty("org.osgi.service.http.port", "0");
 		BundleContext bundleContext = getBundleContext();
 		installer = new BundleInstaller(TEST_BUNDLES_BINARY_DIRECTORY, bundleContext);
 		advisor = new BundleAdvisor(bundleContext);
-		String port = getPort();
-		String contextPath = getContextPath();
-		requestAdvisor = new ServletRequestAdvisor(port, contextPath);
 		startBundles();
 		stopJetty();
+		runtimeTracker = new ServiceTracker<>(bundleContext, HttpServiceRuntime.class, null);
+		runtimeTracker.open();
+		runtimeTracker.waitForService(100);
 		startJetty();
 	}
 
@@ -74,6 +84,7 @@
 		for (ServiceRegistration<? extends Object> serviceRegistration : registrations) {
 			serviceRegistration.unregister();
 		}
+		runtimeTracker.close();
 		stopJetty();
 		stopBundles();
 		requestAdvisor = null;
@@ -146,6 +157,29 @@
 		return value;
 	}
 
+	protected List<String> getStringPlus(String key, ServiceReference<?> ref) {
+		Object property = ref.getProperty(key);
+		if (String.class.isInstance(property)) {
+			return Collections.singletonList((String)property);
+		}
+		else if (String[].class.isInstance(property)) {
+			return Arrays.asList((String[])property);
+		}
+		else if (Collection.class.isInstance(property)) {
+			List<String> list = new ArrayList<String>();
+			for (@SuppressWarnings("rawtypes")
+				 Iterator i = ((Collection)property).iterator(); i.hasNext();) {
+
+				Object o = i.next();
+				if (String.class.isInstance(o)) {
+					list.add((String)o);
+				}
+			}
+			return list;
+		}
+		return Collections.emptyList();
+	}
+
 	protected Bundle installBundle(String bundle) throws BundleException {
 		return installer.installBundle(bundle);
 	}
@@ -156,8 +190,24 @@
 		}
 	}
 
-	protected void startJetty() throws BundleException {
+	protected void startJetty() throws Exception {
 		advisor.startBundle(EQUINOX_JETTY_BUNDLE);
+		ServiceReference<HttpServiceRuntime> runtimeReference = runtimeTracker.getServiceReference();
+		List<String> endpoints = getStringPlus(HttpServiceRuntimeConstants.HTTP_SERVICE_ENDPOINT, runtimeReference);
+		String port = getPort();
+		if (port.equals("0") && !endpoints.isEmpty()) {
+			for (String endpoint : endpoints) {
+				if (endpoint.startsWith("http://")) {
+					port = String.valueOf(new URL(endpoint).getPort());
+					break;
+				}
+			}
+			if (port.equals("-1")) {
+				port = "80";
+			}
+		}
+		String contextPath = getContextPath();
+		requestAdvisor = new ServletRequestAdvisor(port, contextPath);
 	}
 
 	protected void stopBundles() throws BundleException {
@@ -205,6 +255,7 @@
 	protected BundleAdvisor advisor;
 	protected ServletRequestAdvisor requestAdvisor;
 	protected final Collection<ServiceRegistration<? extends Object>> registrations = new ArrayList<ServiceRegistration<? extends Object>>();
+	protected ServiceTracker<HttpServiceRuntime, HttpServiceRuntime> runtimeTracker;
 
 	protected static class TestFilter implements Filter {
 		AtomicInteger called = new AtomicInteger(0);
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 8e29a6f..881eb7b 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
@@ -3214,7 +3214,7 @@
 			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/SB");
 			registrations.add(getBundleContext().registerService(Servlet.class, servletB, props));
 
-			requestAdvisor.request("foo/a/SA");
+			requestAdvisor.request("a/SA");
 
 			Assert.assertEquals("/foo/a", path.get());
 		}
@@ -3284,7 +3284,7 @@
 			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/SB");
 			registrations.add(getBundleContext().registerService(Servlet.class, servletB, props));
 
-			requestAdvisor.request("foo/a/SA");
+			requestAdvisor.request("a/SA");
 
 			Assert.assertEquals("/foo/a", path.get());
 		}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/Activator.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/Activator.java
index 301b1fe..9e7fc21 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/Activator.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/Activator.java
@@ -132,7 +132,7 @@
 
 		if (httpServiceEndpointObj == null) {
 			String[] httpServiceEndpoints = getHttpServiceEndpoints(
-				servletContext, servletConfig.getServletName());
+				serviceProperties, servletContext, servletConfig.getServletName());
 
 			serviceProperties.put(
 				HttpServiceRuntimeConstants.HTTP_SERVICE_ENDPOINT,
@@ -200,7 +200,45 @@
 	}
 
 	private String[] getHttpServiceEndpoints(
-		ServletContext servletContext, String servletName) {
+		Dictionary<String, Object> serviceProperties, ServletContext servletContext, String servletName) {
+
+		List<String> httpServiceEndpoints = new ArrayList<String>();
+
+		String contextPath = (String)serviceProperties.get(Const.CONTEXT_PATH);
+
+		if ((contextPath != null)) {
+			String httpHost = (String)serviceProperties.get(Const.HTTP_HOST);
+			String httpPort = (String)serviceProperties.get(Const.HTTP_PORT);
+
+			if (httpPort != null) {
+				if (httpHost == null) {
+					String endpoint = assembleEndpoint(Const.HTTP, Const.LOCALHOST, httpPort, contextPath);
+					httpServiceEndpoints.add(endpoint);
+				}
+				else {
+					String endpoint = assembleEndpoint(Const.HTTP, httpHost, httpPort, contextPath);
+					httpServiceEndpoints.add(endpoint);
+				}
+			}
+
+			String httpsHost = (String)serviceProperties.get(Const.HTTPS_HOST);
+			String httpsPort = (String)serviceProperties.get(Const.HTTPS_PORT);
+
+			if (httpsPort != null) {
+				if (httpsHost == null) {
+					String endpoint = assembleEndpoint(Const.HTTPS, Const.LOCALHOST, httpsPort, contextPath);
+					httpServiceEndpoints.add(endpoint);
+				}
+				else {
+					String endpoint = assembleEndpoint(Const.HTTPS, httpHost, httpsPort, contextPath);
+					httpServiceEndpoints.add(endpoint);
+				}
+			}
+
+			if (!httpServiceEndpoints.isEmpty()) {
+				return httpServiceEndpoints.toArray(new String[0]);
+			}
+		}
 
 		int majorVersion = servletContext.getMajorVersion();
 
@@ -214,7 +252,7 @@
 			return new String[0];
 		}
 
-		String contextPath = servletContext.getContextPath();
+		contextPath = servletContext.getContextPath();
 
 		ServletRegistration servletRegistration = null;
 		try {
@@ -235,8 +273,6 @@
 
 		Collection<String> mappings = servletRegistration.getMappings();
 
-		List<String> httpServiceEndpoints = new ArrayList<String>();
-
 		for (String mapping : mappings) {
 			if (mapping.indexOf('/') == 0) {
 				if (mapping.charAt(mapping.length() - 1) == '*') {
@@ -253,8 +289,21 @@
 			}
 		}
 
-		return httpServiceEndpoints.toArray(
-			new String[httpServiceEndpoints.size()]);
+		return httpServiceEndpoints.toArray(new String[0]);
+	}
+
+	private String assembleEndpoint(String protocol, String host, String port, String contextPath) {
+		StringBuilder sb = new StringBuilder();
+		sb.append(protocol);
+		sb.append(Const.PROTOCOL);
+		sb.append(host);
+		sb.append(':');
+		sb.append(port);
+		sb.append(contextPath);
+		if (sb.charAt(sb.length() - 1) != '/') {
+			sb.append('/');
+		}
+		return sb.toString();
 	}
 
 	private void processRegistrations() {
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 e286bca..7ba714b 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
@@ -826,9 +826,15 @@
 
 		String defaultEndpoint = endpoints.get(0);
 
-		if ((defaultEndpoint.length() > 0) && defaultEndpoint.endsWith(Const.SLASH)) {
-			defaultEndpoint = defaultEndpoint.substring(
-				0, defaultEndpoint.length() - 1);
+		if (defaultEndpoint.length() > 0) {
+			int protocol = defaultEndpoint.indexOf(Const.PROTOCOL);
+			if (protocol > -1) {
+				defaultEndpoint = defaultEndpoint.substring(protocol + 3);
+			}
+			int slash = defaultEndpoint.indexOf(Const.SLASH);
+			if (defaultEndpoint.endsWith(Const.SLASH)) {
+				defaultEndpoint = defaultEndpoint.substring(slash, defaultEndpoint.length() - 1);
+			}
 		}
 
 		return defaultEndpoint + contextPath;
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 d577c05..6e9e130 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
@@ -19,14 +19,21 @@
 	public static final String AMP = "&"; //$NON-NLS-1$
 	public static final String BLANK = ""; //$NON-NLS-1$
 	public static final String CLOSE_PAREN = ")"; //$NON-NLS-1$
+	public static final String CONTEXT_PATH = "context.path"; //$NON-NLS-1$
 	public static final String DOT = "."; //$NON-NLS-1$
 	public static final String[] EMPTY_ARRAY = new String[0];
 	public static final String EQUAL = "="; //$NON-NLS-1$
 	public static final String FILTER_NAME = "filter-name"; //$NON-NLS-1$
 	public static final String FILTER_PRIORITY = "filter-priority"; //$NON-NLS-1$
 	public static final String HTTP = "http"; //$NON-NLS-1$
+	public static final String HTTP_HOST = "http.host"; //$NON-NLS-1$
+	public static final String HTTP_PORT = "http.port"; //$NON-NLS-1$
+	public static final String HTTPS = "https"; //$NON-NLS-1$
+	public static final String HTTPS_HOST = "https.host"; //$NON-NLS-1$
+	public static final String HTTPS_PORT = "https.port"; //$NON-NLS-1$
 	public static final String LOCALHOST = "localhost"; //$NON-NLS-1$
 	public static final String OPEN_PAREN = "("; //$NON-NLS-1$
+	public static final String PROTOCOL = "://"; //$NON-NLS-1$
 	public static final String SERVLET_NAME = "servlet-name"; //$NON-NLS-1$
 	public static final String SLASH = "/"; //$NON-NLS-1$
 	public static final String SLASH_STAR = "/*"; //$NON-NLS-1$