diff options
author | Anjum Fatima | 2018-11-14 16:21:06 +0000 |
---|---|---|
committer | Thomas Watson | 2018-11-15 13:46:42 +0000 |
commit | d9c09b0d2fb52458b3acbfe93590bbe7e768feb4 (patch) | |
tree | 6516775faacee78b769294e1c037f2d85565d079 | |
parent | dc5952d249f244c87dcd42a197da1991a5aa1711 (diff) | |
download | rt.equinox.bundles-d9c09b0d2fb52458b3acbfe93590bbe7e768feb4.tar.gz rt.equinox.bundles-d9c09b0d2fb52458b3acbfe93590bbe7e768feb4.tar.xz rt.equinox.bundles-d9c09b0d2fb52458b3acbfe93590bbe7e768feb4.zip |
Bug 537160 - NPE inI20181115-1800
org.eclipse.equinox.http.jetty.internal.HttpServerManager.updated() with
HTTPS
Add Tests to test HTTPS endpoint.
Change-Id: I93ea68d4543e273c725482ad2829f00e6a9133c3
Signed-off-by: Anjum Fatima <anjum.eclipse@gmail.com>
6 files changed, 158 insertions, 5 deletions
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 e3590d8db..b4d65a4f1 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 @@ -188,6 +188,7 @@ public class HttpServerManager implements ManagedServiceFactory { // HTTPS connector httpsConnector = new ServerConnector(server, new SslConnectionFactory(sslContextFactory, "http/1.1"), new HttpConnectionFactory(https_config)); //$NON-NLS-1$ httpsConnector.setPort(Details.getInt(dictionary, JettyConstants.HTTPS_PORT, 443)); + httpsConnector.setHost(Details.getString(dictionary, JettyConstants.HTTPS_HOST, null)); } return httpsConnector; } diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.http.servlet.tests/META-INF/MANIFEST.MF index 34a0ad3c9..981c2c0f5 100644 --- a/bundles/org.eclipse.equinox.http.servlet.tests/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.http.servlet.tests/META-INF/MANIFEST.MF @@ -12,6 +12,7 @@ Import-Package: javax.servlet;version="2.6.0", org.apache.commons.fileupload;version="1.2.2", org.apache.commons.fileupload.disk;version="1.2.2", org.apache.commons.fileupload.servlet;version="1.2.2", + org.eclipse.equinox.http.jetty;version="1.4.0", org.eclipse.equinox.http.servlet;version="1.1.0", org.eclipse.equinox.http.servlet.context;version="1.0.0", org.eclipse.equinox.http.servlet.session;version="1.0.0", 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 2bb9155b1..527492cae 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 @@ -39,6 +39,7 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.equinox.http.jetty.JettyConstants; import org.eclipse.equinox.http.servlet.context.ContextPathCustomizer; import org.eclipse.equinox.http.servlet.tests.bundle.Activator; import org.eclipse.equinox.http.servlet.tests.bundle.BundleAdvisor; @@ -142,6 +143,11 @@ public class BaseTest { } return value; } + + protected void setJettyProperty(String key, String value) { + String qualifiedKey = JETTY_PROPERTY_PREFIX + key; + System.setProperty(qualifiedKey, value); + } protected String getPort() { String defaultPort = getProperty(OSGI_HTTP_PORT_PROPERTY); @@ -209,6 +215,33 @@ public class BaseTest { String contextPath = getContextPath(); requestAdvisor = new ServletRequestAdvisor(port, contextPath); } + + protected void startJettyWithSSL(String port, String ksPath, String ksPassword, String keyPassword) throws Exception { + if(port == null) { + throw new IllegalArgumentException("Port cannot be null"); + } + if (ksPath == null) { + throw new IllegalArgumentException("Keystore path cannot be null"); + } + setJettyProperty(JettyConstants.HTTP_ENABLED, "false"); + setJettyProperty(JettyConstants.HTTPS_ENABLED, "true"); + + setJettyProperty(JettyConstants.HTTPS_PORT, port); + + setJettyProperty(JettyConstants.SSL_KEYSTORE, ksPath); + + if(ksPassword != null) { + setJettyProperty(JettyConstants.SSL_PASSWORD, ksPassword); + } + if(keyPassword != null) { + setJettyProperty(JettyConstants.SSL_KEYPASSWORD, keyPassword); + } + + advisor.startBundle(EQUINOX_JETTY_BUNDLE); + String contextPath = getContextPath(); + requestAdvisor = new ServletRequestAdvisor(port, contextPath, ksPath, ksPassword); + } + protected void stopBundles() throws BundleException { for (int i = BUNDLES.length - 1; i >= 0; i--) { @@ -220,6 +253,12 @@ public class BaseTest { protected void stopJetty() throws BundleException { advisor.stopBundle(EQUINOX_JETTY_BUNDLE); } + + protected void stopJettyWithSSL() throws BundleException { + advisor.stopBundle(EQUINOX_JETTY_BUNDLE); + setJettyProperty(JettyConstants.HTTP_ENABLED, "true"); + setJettyProperty(JettyConstants.HTTPS_ENABLED, "false"); + } protected void uninstallBundle(Bundle bundle) throws BundleException { installer.uninstallBundle(bundle); 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 c423ba64c..74a898559 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 @@ -32,6 +32,7 @@ import java.net.CookieHandler; import java.net.CookieManager; import java.net.CookiePolicy; import java.net.URL; +import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -4309,6 +4310,27 @@ public class ServletTest extends BaseTest { String actual = requestAdvisor.request(testName.getMethodName()); Assert.assertEquals(expected, actual); } - - + + @Test + public void testHTTPSEndpoint() throws Exception { + stopJetty(); + File keyStoreFile = getBundleContext().getDataFile("server-keystore.jks"); + URL keyStoreURL = getClass().getResource("server-keystore.jks"); + if (!keyStoreFile.exists()) { + Files.copy(keyStoreURL.openStream(), keyStoreFile.toPath()); + } + + startJettyWithSSL("8443", keyStoreFile.getAbsolutePath(), "secret", "secret"); + + Bundle bundle = installBundle(TEST_BUNDLE_1); + try { + bundle.start(); + + String actual = requestAdvisor.requestHttps("TestServlet10"); + assertEquals("Expected output not found", "a", actual); + } finally { + uninstallBundle(bundle); + stopJettyWithSSL(); + } + } } diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/server-keystore.jks b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/server-keystore.jks Binary files differnew file mode 100644 index 000000000..f782374e7 --- /dev/null +++ b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/server-keystore.jks diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/util/ServletRequestAdvisor.java b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/util/ServletRequestAdvisor.java index 0918d46bd..f4224206d 100644 --- a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/util/ServletRequestAdvisor.java +++ b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/util/ServletRequestAdvisor.java @@ -14,22 +14,32 @@ *******************************************************************************/ package org.eclipse.equinox.http.servlet.tests.util; +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; - import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; - +import java.security.KeyStore; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + /* * The ServletRequestAdvisor is responsible for composing URLs and using them * to performing servlet requests. @@ -37,8 +47,14 @@ import java.util.Map; public class ServletRequestAdvisor extends Object { private final String contextPath; private final String port; + private final String ksPath; + private final String ksPassword; public ServletRequestAdvisor(String port, String contextPath) { + this(port, contextPath, null, null); + } + + public ServletRequestAdvisor(String port, String contextPath, String ksPath, String ksPassword) { super(); if (port == null) { @@ -46,11 +62,16 @@ public class ServletRequestAdvisor extends Object { } this.port = port; this.contextPath = contextPath; + this.ksPath = ksPath; + this.ksPassword = ksPassword; } - private String createUrlSpec(String value) { + private String createUrlSpec(String value, boolean isHttps) { StringBuffer buffer = new StringBuffer(100); String protocol = "http://"; //$NON-NLS-1$ + if (isHttps) { + protocol = "https://"; + } String host = "localhost"; //$NON-NLS-1$ buffer.append(protocol); buffer.append(host); @@ -62,8 +83,13 @@ public class ServletRequestAdvisor extends Object { buffer.append(value); } return buffer.toString(); + } + private String createUrlSpec(String value) { + return createUrlSpec(value, false); + } + private String drain(InputStream stream) throws IOException { byte[] bytes = new byte[100]; StringBuffer buffer = new StringBuffer(500); @@ -99,6 +125,70 @@ public class ServletRequestAdvisor extends Object { stream.close(); } } + + public String requestHttps(String value) throws Exception { + String spec = createUrlSpec(value, true); + log("Requesting " + spec); //$NON-NLS-1$ + URL url = new URL(spec); + SSLContext sslContext = SSLContext.getInstance("SSL"); + initializeSSLContext(sslContext, ksPath, ksPassword); + + HttpsURLConnection httpsConn = (HttpsURLConnection)url.openConnection(); + httpsConn.setSSLSocketFactory(sslContext.getSocketFactory()); + httpsConn.setRequestMethod("GET"); + httpsConn.setDoOutput(false); + httpsConn.setDoInput(true); + httpsConn.setConnectTimeout(150 * 1000); + httpsConn.setReadTimeout(150 * 1000); + httpsConn.connect(); + + assertEquals("Request to the url " + spec + " was not successful", 200 , httpsConn.getResponseCode()); + InputStream stream = httpsConn.getInputStream(); + try { + return drain(stream); + } finally { + stream.close(); + } + } + + private void initializeSSLContext(SSLContext sslContext, String ksPath, String ksPassword) throws Exception { + KeyManager keyManagers[] = null; + if (ksPath != null) { + KeyManagerFactory kmFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + File ksFile = new File(ksPath); + KeyStore keyStore = KeyStore.getInstance("JKS"); + + try(InputStream ksStream = new FileInputStream(ksFile)){ + keyStore.load(ksStream, ksPassword.toCharArray()); + kmFactory.init(keyStore, ksPassword.toCharArray()); + keyManagers = kmFactory.getKeyManagers(); + } + } + + TrustManager[] trustManagers = getTrustManager(); + + sslContext.init(keyManagers, trustManagers, null); + + } + + private TrustManager[] getTrustManager() { + TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { + @Override + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + + @Override + public void checkClientTrusted( + java.security.cert.X509Certificate[] certs, String authType) {} + + @Override + public void checkServerTrusted( + java.security.cert.X509Certificate[] certs, String authType) {} + } }; + + return trustAllCerts; + } public Map<String, List<String>> request(String value, Map<String, List<String>> headers) throws IOException { String spec = createUrlSpec(value); |