You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by rf...@apache.org on 2008/08/09 08:11:55 UTC

svn commit: r684186 - in /tuscany/java/sca/modules: host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/ host-jetty/src/test/java/org/apache/tuscany/sca/http/jetty/ host-jetty/src/test/resources/ host-tomcat/src/main/java/org/apache/tuscany/sca/...

Author: rfeng
Date: Fri Aug  8 23:11:54 2008
New Revision: 684186

URL: http://svn.apache.org/viewvc?rev=684186&view=rev
Log:
Enable the https support for embedded tomcat and jetty with unit tests

Added:
    tuscany/java/sca/modules/host-jetty/src/test/resources/tuscany.keyStore   (with props)
    tuscany/java/sca/modules/host-tomcat/src/test/resources/tuscany.keyStore   (with props)
Modified:
    tuscany/java/sca/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyServer.java
    tuscany/java/sca/modules/host-jetty/src/test/java/org/apache/tuscany/sca/http/jetty/JettyServerTestCase.java
    tuscany/java/sca/modules/host-tomcat/src/main/java/org/apache/tuscany/sca/http/tomcat/TomcatServer.java
    tuscany/java/sca/modules/host-tomcat/src/test/java/org/apache/tuscany/sca/http/tomcat/TomcatServerTestCase.java

Modified: tuscany/java/sca/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyServer.java
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyServer.java?rev=684186&r1=684185&r2=684186&view=diff
==============================================================================
--- tuscany/java/sca/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyServer.java (original)
+++ tuscany/java/sca/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyServer.java Fri Aug  8 23:11:54 2008
@@ -23,6 +23,9 @@
 import java.net.URI;
 import java.net.URL;
 import java.net.UnknownHostException;
+import java.security.AccessController;
+import java.security.KeyStore;
+import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -62,9 +65,15 @@
     private static final Logger logger = Logger.getLogger(JettyServer.class.getName());
 
     private final Object joinLock = new Object();
-    private String keystore;
-    private String certPassword;
-    private String keyPassword;
+    private String trustStore;
+    private String truststorePassword;
+    private String keyStore;
+    private String keyStorePassword;
+
+    private String keyStoreType;
+    private String trustStoreType;
+
+    
     private boolean sendServerVersion;
     private WorkScheduler workScheduler;
     private int defaultPort = 8080;
@@ -101,6 +110,18 @@
 
     public JettyServer(WorkScheduler workScheduler) {
         this.workScheduler = workScheduler;
+        AccessController.doPrivileged(new PrivilegedAction<Object>() {
+            public Object run() {
+                trustStore = System.getProperty("javax.net.ssl.trustStore");
+                truststorePassword = System.getProperty("javax.net.ssl.trustStorePassword");
+                keyStore = System.getProperty("javax.net.ssl.keyStore");
+                keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword");
+
+                keyStoreType = System.getProperty("javax.net.ssl.keyStoreType", KeyStore.getDefaultType());
+                trustStoreType = System.getProperty("javax.net.ssl.trustStoreType", KeyStore.getDefaultType());
+                return null;
+            }
+        });
     }
     
     public void setDefaultPort(int port) {
@@ -115,18 +136,6 @@
         this.sendServerVersion = sendServerVersion;
     }
 
-    public void setKeystore(String keystore) {
-        this.keystore = keystore;
-    }
-
-    public void setCertPassword(String certPassword) {
-        this.certPassword = certPassword;
-    }
-
-    public void setKeyPassword(String keyPassword) {
-        this.keyPassword = keyPassword;
-    }
-
     /**
      * Stop all the started servers.
      */
@@ -145,6 +154,23 @@
             throw new ServletMappingException(e);
         }
     }
+    
+    private void configureSSL(SslSocketConnector connector) {
+        connector.setProtocol("TLS");
+        connector.setKeystore(keyStore);
+        connector.setKeyPassword(keyStorePassword);
+        connector.setKeystoreType(keyStoreType);
+
+        connector.setTruststore(trustStore);
+        connector.setTrustPassword(truststorePassword);
+        connector.setTruststoreType(trustStoreType);
+
+        connector.setPassword(keyStorePassword);
+        if (trustStore != null) {
+            connector.setNeedClientAuth(true);
+        }
+
+    }
 
     public void addServletMapping(String suri, Servlet servlet) throws ServletMappingException {
         URI uri = URI.create(suri);
@@ -168,14 +194,12 @@
                 Server server = new Server();
                 server.setThreadPool(new WorkSchedulerThreadPool());
                 if ("https".equals(scheme)) {
-                    Connector httpConnector = new SelectChannelConnector();
-                    httpConnector.setPort(portNumber);
+//                    Connector httpConnector = new SelectChannelConnector();
+//                    httpConnector.setPort(portNumber);
                     SslSocketConnector sslConnector = new SslSocketConnector();
                     sslConnector.setPort(portNumber);
-                    sslConnector.setKeystore(keystore);
-                    sslConnector.setPassword(certPassword);
-                    sslConnector.setKeyPassword(keyPassword);
-                    server.setConnectors(new Connector[] {httpConnector, sslConnector});
+                    configureSSL(sslConnector);
+                    server.setConnectors(new Connector[] {sslConnector});
                 } else {
                     SelectChannelConnector selectConnector = new SelectChannelConnector();
                     selectConnector.setPort(portNumber);

Modified: tuscany/java/sca/modules/host-jetty/src/test/java/org/apache/tuscany/sca/http/jetty/JettyServerTestCase.java
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/host-jetty/src/test/java/org/apache/tuscany/sca/http/jetty/JettyServerTestCase.java?rev=684186&r1=684185&r2=684186&view=diff
==============================================================================
--- tuscany/java/sca/modules/host-jetty/src/test/java/org/apache/tuscany/sca/http/jetty/JettyServerTestCase.java (original)
+++ tuscany/java/sca/modules/host-jetty/src/test/java/org/apache/tuscany/sca/http/jetty/JettyServerTestCase.java Fri Aug  8 23:11:54 2008
@@ -20,11 +20,16 @@
 
 import java.io.BufferedReader;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.net.ConnectException;
 import java.net.Socket;
+import java.net.URL;
 
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
@@ -93,6 +98,37 @@
         assertTrue(servlet.invoked);
     }
 
+    public void testRegisterServletMappingSSL() throws Exception {
+        System.setProperty("javax.net.ssl.keyStore", "target/test-classes/tuscany.keyStore");
+        System.setProperty("javax.net.ssl.keyStorePassword", "apache");
+        System.setProperty("jetty.ssl.password", "apache");
+        JettyServer service = new JettyServer(workScheduler);
+        TestServlet servlet = new TestServlet();
+        try {
+            service.addServletMapping("https://127.0.0.1:" + HTTP_PORT + "/foo", servlet);
+        } finally {
+            System.clearProperty("javax.net.ssl.keyStore");
+            System.clearProperty("javax.net.ssl.keyStorePassword");
+            System.clearProperty("jetty.ssl.password");
+        }
+        System.setProperty("javax.net.ssl.trustStore", "target/test-classes/tuscany.keyStore");
+        System.setProperty("javax.net.ssl.trustStorePassword", "apache");
+        URL url = new URL("https://127.0.0.1:8085/foo");
+        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
+        conn.setHostnameVerifier(new HostnameVerifier() {
+            public boolean verify(String hostname, SSLSession session) {
+                return true;
+            }}
+        );
+
+        conn.connect();
+        read(conn.getInputStream());
+        
+        service.stop();
+        assertTrue(servlet.invoked);
+
+    }
+
     /**
      * Verifies that Servlets can be registered with multiple ports
      */
@@ -116,7 +152,7 @@
             os.flush();
             read(client);
         }
-        
+
         service.stop();
         assertTrue(servlet.invoked);
         assertTrue(servlet2.invoked);
@@ -172,50 +208,55 @@
         assertNotNull(ex);
         service.stop();
     }
-    
+
     public void testResourceServlet() throws Exception {
         JettyServer service = new JettyServer(workScheduler);
-        
+
         String documentRoot = getClass().getClassLoader().getResource("content/test.html").toString();
         documentRoot = documentRoot.substring(0, documentRoot.lastIndexOf('/'));
         DefaultResourceServlet resourceServlet = new DefaultResourceServlet(documentRoot);
         TestResourceServlet servlet = new TestResourceServlet(resourceServlet);
         service.addServletMapping("http://127.0.0.1:" + HTTP_PORT + "/webcontent/*", servlet);
-        
+
         Socket client = new Socket("127.0.0.1", HTTP_PORT);
         OutputStream os = client.getOutputStream();
         os.write(REQUEST2.getBytes());
         os.flush();
-        
+
         String document = read(client);
         assertTrue(document.indexOf("<body><p>hello</body>") != -1);
-        
+
         service.stop();
     }
 
     public void testDefaultServlet() throws Exception {
         JettyServer service = new JettyServer(workScheduler);
-        
+
         String documentRoot = getClass().getClassLoader().getResource("content/test.html").toString();
         documentRoot = documentRoot.substring(0, documentRoot.lastIndexOf('/'));
         DefaultResourceServlet resourceServlet = new DefaultResourceServlet(documentRoot);
         service.addServletMapping("http://127.0.0.1:" + HTTP_PORT + "/webcontent/*", resourceServlet);
-        
+
         Socket client = new Socket("127.0.0.1", HTTP_PORT);
         OutputStream os = client.getOutputStream();
         os.write(REQUEST2.getBytes());
         os.flush();
-        
+
         String document = read(client);
         assertTrue(document.indexOf("<body><p>hello</body>") != -1);
-        
+
         service.stop();
     }
 
     private static String read(Socket socket) throws IOException {
+        InputStream is = socket.getInputStream();
+        return read(is);
+    }
+
+    private static String read(InputStream is) throws IOException {
         BufferedReader reader = null;
         try {
-            reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+            reader = new BufferedReader(new InputStreamReader(is));
             StringBuffer sb = new StringBuffer();
             String str;
             while ((str = reader.readLine()) != null) {
@@ -251,11 +292,11 @@
     private class TestResourceServlet extends HttpServlet {
         private static final long serialVersionUID = 1L;
         private HttpServlet delegate;
-        
+
         public TestResourceServlet(HttpServlet delegate) {
             this.delegate = delegate;
         }
-        
+
         @Override
         public void init() throws ServletException {
             super.init();
@@ -267,12 +308,12 @@
             super.init();
             delegate.init(config);
         }
-        
+
         @Override
         protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
             delegate.service(req, resp);
         }
-        
+
         @Override
         public void destroy() {
             super.destroy();

Added: tuscany/java/sca/modules/host-jetty/src/test/resources/tuscany.keyStore
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/host-jetty/src/test/resources/tuscany.keyStore?rev=684186&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tuscany/java/sca/modules/host-jetty/src/test/resources/tuscany.keyStore
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: tuscany/java/sca/modules/host-tomcat/src/main/java/org/apache/tuscany/sca/http/tomcat/TomcatServer.java
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/host-tomcat/src/main/java/org/apache/tuscany/sca/http/tomcat/TomcatServer.java?rev=684186&r1=684185&r2=684186&view=diff
==============================================================================
--- tuscany/java/sca/modules/host-tomcat/src/main/java/org/apache/tuscany/sca/http/tomcat/TomcatServer.java (original)
+++ tuscany/java/sca/modules/host-tomcat/src/main/java/org/apache/tuscany/sca/http/tomcat/TomcatServer.java Fri Aug  8 23:11:54 2008
@@ -25,6 +25,7 @@
 import java.net.URL;
 import java.net.UnknownHostException;
 import java.security.AccessController;
+import java.security.KeyStore;
 import java.security.PrivilegedAction;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
@@ -217,7 +218,7 @@
         if (scheme == null) {
             scheme = "http";
         }
-        final int portNumber = (uri.getPort() == -1 ? defaultPortNumber : uri.getPort() ); 
+        final int portNumber = (uri.getPort() == -1 ? defaultPortNumber : uri.getPort());
 
         // Get the port object associated with the given port number
         Port port = ports.get(portNumber);
@@ -226,13 +227,12 @@
             // Create an engine
             // Allow privileged access to read properties. Requires PropertiesPermission read in
             // security policy.
-            final StandardEngine engine = 
-            AccessController.doPrivileged(new PrivilegedAction<StandardEngine>() {
+            final StandardEngine engine = AccessController.doPrivileged(new PrivilegedAction<StandardEngine>() {
                 public StandardEngine run() {
                     return new StandardEngine();
                 }
             });
-            
+
             engine.setBaseDir("");
             engine.setDefaultHost("localhost");
             engine.setName("engine/" + portNumber);
@@ -265,7 +265,7 @@
             // Allow privileged access to read properties. Requires PropertiesPermission read in
             // security policy.
             try {
-            AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+                AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                     public Object run() throws LifecycleException {
                         engine.start();
                         return null;
@@ -274,20 +274,52 @@
             } catch (PrivilegedActionException e) {
                 // throw (LifecycleException)e.getException();
                 throw new ServletMappingException(e);
-            }                
+            }
             Connector connector;
             // Allow privileged access to read properties. Requires PropertiesPermission read in
             // security policy.
             try {
+                final String protocol = scheme;
                 connector = AccessController.doPrivileged(new PrivilegedExceptionAction<CustomConnector>() {
                     public CustomConnector run() throws Exception {
-                       CustomConnector customConnector = new CustomConnector();
-                       customConnector.setPort(portNumber);
-                       customConnector.setContainer(engine);
-                       customConnector.initialize();
-                       customConnector.start();
-                       return customConnector;
-                   }
+                        CustomConnector customConnector = new CustomConnector();
+                        customConnector.setPort(portNumber);
+                        customConnector.setContainer(engine);
+
+                        if ("https".equalsIgnoreCase(protocol)) {
+                            configureSSL(customConnector);
+                            ((Http11Protocol) customConnector.getProtocolHandler()).setSSLEnabled(true);
+                        }
+                        customConnector.initialize();
+                        customConnector.start();
+                        return customConnector;
+                    }
+
+                    private void configureSSL(CustomConnector customConnector) {
+                        String trustStore = System.getProperty("javax.net.ssl.trustStore");
+                        String trustStorePass = System.getProperty("javax.net.ssl.trustStorePassword");
+                        String keyStore = System.getProperty("javax.net.ssl.keyStore");
+                        String keyStorePass = System.getProperty("javax.net.ssl.keyStorePassword");
+
+                        customConnector.setProperty("protocol", "TLS");
+
+                        customConnector.setProperty("keystore", keyStore);
+                        customConnector.setProperty("keypass", keyStorePass);
+                        String keyStoreType =
+                            System.getProperty("javax.net.ssl.keyStoreType", KeyStore.getDefaultType());
+                        String trustStoreType =
+                            System.getProperty("javax.net.ssl.trustStoreType", KeyStore.getDefaultType());
+                        customConnector.setProperty("keytype", keyStoreType);
+                        customConnector.setProperty("trusttype", trustStoreType);
+                        customConnector.setProperty("truststore", trustStore);
+                        customConnector.setProperty("trustpass", trustStorePass);
+
+                        customConnector.setProperty("clientauth", "false");
+                        customConnector.setProtocol("HTTP/1.1");
+                        customConnector.setScheme(protocol);
+                        customConnector.setProperty("backlog", "10");
+                        customConnector.setSecure(true);
+                    }
                 });
             } catch (Exception e) {
                 throw new ServletMappingException(e);
@@ -512,12 +544,12 @@
             } catch (Exception ex) {
                 // Hack to handle destruction of Servlets without Servlet context 
             }
-            
+
             logger.info("Removed Servlet mapping: " + suri);
-            
+
             // Stop the port if there's no servlets on it anymore
             String[] contextNames = port.getConnector().getMapper().getContextNames();
-            if (contextNames == null || contextNames.length ==0) {
+            if (contextNames == null || contextNames.length == 0) {
                 try {
                     port.getConnector().stop();
                     port.getEngine().stop();
@@ -526,7 +558,7 @@
                     throw new IllegalStateException(e);
                 }
             }
-            
+
             return servletWrapper.getServlet();
         } else {
             logger.warning("Trying to Remove servlet mapping: " + mapping + " where mapping is not registered");

Modified: tuscany/java/sca/modules/host-tomcat/src/test/java/org/apache/tuscany/sca/http/tomcat/TomcatServerTestCase.java
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/host-tomcat/src/test/java/org/apache/tuscany/sca/http/tomcat/TomcatServerTestCase.java?rev=684186&r1=684185&r2=684186&view=diff
==============================================================================
--- tuscany/java/sca/modules/host-tomcat/src/test/java/org/apache/tuscany/sca/http/tomcat/TomcatServerTestCase.java (original)
+++ tuscany/java/sca/modules/host-tomcat/src/test/java/org/apache/tuscany/sca/http/tomcat/TomcatServerTestCase.java Fri Aug  8 23:11:54 2008
@@ -20,10 +20,15 @@
 
 import java.io.BufferedReader;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.net.Socket;
+import java.net.URL;
 
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
@@ -91,7 +96,38 @@
         service.stop();
         assertTrue(servlet.invoked);
     }
+    
+    /**
+     * Verifies requests are properly routed according to the Servlet mapping
+     */
+    public void testRegisterServletMappingSSL() throws Exception {
+        System.setProperty("javax.net.ssl.keyStore", "target/test-classes/tuscany.keyStore");
+        System.setProperty("javax.net.ssl.keyStorePassword", "apache");
+        TomcatServer service = new TomcatServer(workScheduler);
+        TestServlet servlet = new TestServlet();
+        try {
+            service.addServletMapping("https://127.0.0.1:" + HTTP_PORT + "/foo", servlet);
+        } finally {
+            System.clearProperty("javax.net.ssl.keyStore");
+            System.clearProperty("javax.net.ssl.keyStorePassword");
+        }
+        System.setProperty("javax.net.ssl.trustStore", "target/test-classes/tuscany.keyStore");
+        System.setProperty("javax.net.ssl.trustStorePassword", "apache");
+        URL url = new URL("https://127.0.0.1:8085/foo");
+        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
+        conn.setHostnameVerifier(new HostnameVerifier() {
+            public boolean verify(String hostname, SSLSession session) {
+                return true;
+            }}
+        );
 
+        conn.connect();
+        read(conn.getInputStream());
+        
+        service.stop();
+        assertTrue(servlet.invoked);
+
+    }
     /**
      * Verifies that Servlets can be registered with multiple ports
      */
@@ -244,9 +280,14 @@
     }
 
     private static String read(Socket socket) throws IOException {
+        InputStream is = socket.getInputStream();
+        return read(is);
+    }
+
+    private static String read(InputStream is) throws IOException {
         BufferedReader reader = null;
         try {
-            reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+            reader = new BufferedReader(new InputStreamReader(is));
             StringBuffer sb = new StringBuffer();
             String str;
             while ((str = reader.readLine()) != null) {
@@ -259,7 +300,6 @@
             }
         }
     }
-
     private class TestServlet extends HttpServlet {
         private static final long serialVersionUID = 1L;
         boolean invoked;

Added: tuscany/java/sca/modules/host-tomcat/src/test/resources/tuscany.keyStore
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/host-tomcat/src/test/resources/tuscany.keyStore?rev=684186&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tuscany/java/sca/modules/host-tomcat/src/test/resources/tuscany.keyStore
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream