Code example for HttpsURLConnection

Methods: connect, getCipherSuite, getLocalCertificates, getLocalPrincipal, getPeerPrincipal, getSSLSocketFactory, getServerCertificates, setConnectTimeout, setDoInput, setReadTimeout

0
        assertFalse("Hostname verification should not be done by this verifier",
                    hnv_late.verified);
        // check the used SSLSocketFactory 
        assertSame("Default SSLSocketFactory should be used",
                   HttpsURLConnection.getDefaultSSLSocketFactory(),
                   connection.getSSLSocketFactory());
 
        // should silently exit 
        connection.connect();
    } 
 
    /** 
     * Tests possibility to set up the SSLSocketFactory 
     * to be used by HttpsURLConnection. 
     */ 
    public void testSetSSLSocketFactory() throws Throwable { 
        // create the SSLServerSocket which will be used by server side 
        SSLContext ctx = getContext();
        SSLServerSocket ss = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(0);
 
        // create the HostnameVerifier to check hostname verification 
        TestHostnameVerifier hnv = new TestHostnameVerifier();
        HttpsURLConnection.setDefaultHostnameVerifier(hnv);
 
        // create HttpsURLConnection to be tested 
        URL url = new URL("https://localhost:" + ss.getLocalPort());
        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
 
        SSLSocketFactory socketFactory = (SSLSocketFactory) ctx.getSocketFactory();
        connection.setSSLSocketFactory(socketFactory);
 
        TestHostnameVerifier hnv_late = new TestHostnameVerifier();
        // late initialization: should not be used for created connection 
        HttpsURLConnection.setDefaultHostnameVerifier(hnv_late);
 
        // perform the interaction between the peers 
        SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
        // check the connection state 
        checkConnectionStateParameters(connection, peerSocket);
        // check the verification process 
        assertTrue("Hostname verification was not done", hnv.verified);
        assertFalse("Hostname verification should not be done by this verifier",
                    hnv_late.verified);
        // check the used SSLSocketFactory 
        assertNotSame("Default SSLSocketFactory should not be used",
                      HttpsURLConnection.getDefaultSSLSocketFactory(),
                      connection.getSSLSocketFactory());
        assertSame("Result differs from expected",
                   socketFactory, connection.getSSLSocketFactory());
 
        // should silently exit 
        connection.connect();
    } 
 
    /** 
     * Tests the behaviour of HttpsURLConnection in case of retrieving 
     * of the connection state parameters before connection has been made. 
     */ 
    public void testUnconnectedStateParameters() throws Throwable { 
        // create HttpsURLConnection to be tested 
        URL url = new URL("https://localhost:55555");
        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
 
        try { 
            connection.getCipherSuite();
            fail("Expected IllegalStateException was not thrown");
        } catch (IllegalStateException e) {}
        try { 
            connection.getPeerPrincipal();
            fail("Expected IllegalStateException was not thrown");
        } catch (IllegalStateException e) {}
        try { 
            connection.getLocalPrincipal();
            fail("Expected IllegalStateException was not thrown");
        } catch (IllegalStateException e) {}
 
        try { 
            connection.getServerCertificates();
            fail("Expected IllegalStateException was not thrown");
        } catch (IllegalStateException e) {}
        try { 
            connection.getLocalCertificates();
            fail("Expected IllegalStateException was not thrown");
        } catch (IllegalStateException e) {}
    } 
 
    /** 
     * Tests if setHostnameVerifier() method replaces default verifier. 
     */ 
    public void testSetHostnameVerifier() throws Throwable { 
        // setting up the properties pointing to the key/trust stores 
        setUpStoreProperties(); 
 
        // create the SSLServerSocket which will be used by server side 
        SSLServerSocket ss = (SSLServerSocket)
                getContext().getServerSocketFactory().createServerSocket(0);
 
        // create the HostnameVerifier to check that Hostname verification 
        // is done 
        TestHostnameVerifier hnv = new TestHostnameVerifier();
        HttpsURLConnection.setDefaultHostnameVerifier(hnv);
 
        // create HttpsURLConnection to be tested 
        URL url = new URL("https://localhost:" + ss.getLocalPort());
        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
        connection.setSSLSocketFactory(getContext().getSocketFactory());
 
        TestHostnameVerifier hnv_late = new TestHostnameVerifier();
        // replace default verifier 
        connection.setHostnameVerifier(hnv_late);
 
        // perform the interaction between the peers and check the results 
        SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
        assertTrue("Hostname verification was not done", hnv_late.verified);
        assertFalse("Hostname verification should not be done by this verifier",
                    hnv.verified);
        checkConnectionStateParameters(connection, peerSocket);
 
        // should silently exit 
        connection.connect();
    } 
 
    /** 
     * Tests the behaviour in case of sending the data to the server. 
     */ 
    public void test_doOutput() throws Throwable { 
        // setting up the properties pointing to the key/trust stores 
        setUpStoreProperties(); 
 
        // create the SSLServerSocket which will be used by server side 
        SSLServerSocket ss = (SSLServerSocket)
                getContext().getServerSocketFactory().createServerSocket(0);
 
        // create the HostnameVerifier to check that Hostname verification 
        // is done 
        TestHostnameVerifier hnv = new TestHostnameVerifier();
        HttpsURLConnection.setDefaultHostnameVerifier(hnv);
 
        // create HttpsURLConnection to be tested 
        URL url = new URL("https://localhost:" + ss.getLocalPort());
        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
        connection.setSSLSocketFactory(getContext().getSocketFactory());
        connection.setDoOutput(true);
 
        // perform the interaction between the peers and check the results 
        SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
        checkConnectionStateParameters(connection, peerSocket);
 
        // should silently exit 
        connection.connect();
    } 
 
    /** 
     * Tests HTTPS connection process made through the proxy server. 
     */ 
    public void testProxyConnection() throws Throwable { 
        // setting up the properties pointing to the key/trust stores 
        setUpStoreProperties(); 
 
        // create the SSLServerSocket which will be used by server side 
        ServerSocket ss = new ServerSocket(0);
 
        // create the HostnameVerifier to check that Hostname verification 
        // is done 
        TestHostnameVerifier hnv = new TestHostnameVerifier();
        HttpsURLConnection.setDefaultHostnameVerifier(hnv);
 
        // create HttpsURLConnection to be tested 
        URL url = new URL("https://requested.host:55556/requested.data");
        HttpsURLConnection connection = (HttpsURLConnection)
                url.openConnection(new Proxy(Proxy.Type.HTTP,
                                             new InetSocketAddress("localhost",
                                                                   ss.getLocalPort())));
        connection.setSSLSocketFactory(getContext().getSocketFactory());
 
        // perform the interaction between the peers and check the results 
        SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
        checkConnectionStateParameters(connection, peerSocket);
 
        // should silently exit 
        connection.connect();
    } 
 
    /** 
     * Tests HTTPS connection process made through the proxy server. 
     * Proxy server needs authentication. 
     */ 
    public void testProxyAuthConnection() throws Throwable { 
        // setting up the properties pointing to the key/trust stores 
        setUpStoreProperties(); 
 
        // create the SSLServerSocket which will be used by server side 
        ServerSocket ss = new ServerSocket(0);
 
        // create the HostnameVerifier to check that Hostname verification 
        // is done 
        TestHostnameVerifier hnv = new TestHostnameVerifier();
        HttpsURLConnection.setDefaultHostnameVerifier(hnv);
 
        Authenticator.setDefault(new Authenticator() {
 
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("user", "password"
                        .toCharArray());
            } 
        }); 
 
        // create HttpsURLConnection to be tested 
        URL url = new URL("https://requested.host:55555/requested.data");
        HttpsURLConnection connection = (HttpsURLConnection)
                url.openConnection(new Proxy(Proxy.Type.HTTP,
                                             new InetSocketAddress("localhost",
                                                                   ss.getLocalPort())));
        connection.setSSLSocketFactory(getContext().getSocketFactory());
 
        // perform the interaction between the peers and check the results 
        SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
        checkConnectionStateParameters(connection, peerSocket);
 
        // should silently exit 
        connection.connect();
    } 
 
    /** 
     * Tests HTTPS connection process made through the proxy server. 
     * 2 HTTPS connections are opened for one URL. For the first time 
     * the connection is opened through one proxy, 
     * for the second time through another. 
     */ 
    public void testConsequentProxyConnection() throws Throwable { 
        // setting up the properties pointing to the key/trust stores 
        setUpStoreProperties(); 
 
        // create the SSLServerSocket which will be used by server side 
        ServerSocket ss = new ServerSocket(0);
 
        // create the HostnameVerifier to check that Hostname verification 
        // is done 
        TestHostnameVerifier hnv = new TestHostnameVerifier();
        HttpsURLConnection.setDefaultHostnameVerifier(hnv);
 
        // create HttpsURLConnection to be tested 
        URL url = new URL("https://requested.host:55555/requested.data");
        HttpsURLConnection connection = (HttpsURLConnection)
                url.openConnection(new Proxy(Proxy.Type.HTTP,
                                             new InetSocketAddress("localhost",
                                                                   ss.getLocalPort())));
        connection.setSSLSocketFactory(getContext().getSocketFactory());
 
        // perform the interaction between the peers and check the results 
        SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
        checkConnectionStateParameters(connection, peerSocket);
 
        // create another SSLServerSocket which will be used by server side 
        ss = new ServerSocket(0);
 
        connection = (HttpsURLConnection) url.openConnection(new Proxy(
                Proxy.Type.HTTP, new InetSocketAddress("localhost", ss.getLocalPort())));
        connection.setSSLSocketFactory(getContext().getSocketFactory());
 
        // perform the interaction between the peers and check the results 
        peerSocket = (SSLSocket) doInteraction(connection, ss);
        checkConnectionStateParameters(connection, peerSocket);
    } 
 
    /** 
     * Tests HTTPS connection process made through the proxy server. 
     * Proxy server needs authentication. 
     * Client sends data to the server. 
     */ 
    public void testProxyAuthConnection_doOutput() throws Throwable { 
        // setting up the properties pointing to the key/trust stores 
        setUpStoreProperties(); 
 
        // create the SSLServerSocket which will be used by server side 
        ServerSocket ss = new ServerSocket(0);
 
        // create the HostnameVerifier to check that Hostname verification 
        // is done 
        TestHostnameVerifier hnv = new TestHostnameVerifier();
        HttpsURLConnection.setDefaultHostnameVerifier(hnv);
 
        Authenticator.setDefault(new Authenticator() {
 
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("user", "password"
                        .toCharArray());
            } 
        }); 
 
        // create HttpsURLConnection to be tested 
        URL url = new URL("https://requested.host:55554/requested.data");
        HttpsURLConnection connection = (HttpsURLConnection)
                url.openConnection(new Proxy(Proxy.Type.HTTP,
                                             new InetSocketAddress("localhost",
                                                                   ss.getLocalPort())));
        connection.setSSLSocketFactory(getContext().getSocketFactory());
        connection.setDoOutput(true);
 
        // perform the interaction between the peers and check the results 
        SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss, OK_CODE, true);
        checkConnectionStateParameters(connection, peerSocket);
    } 
 
    /** 
     * Tests HTTPS connection process made through the proxy server. 
     * Proxy server needs authentication but client fails to authenticate 
     * (Authenticator was not set up in the system). 
     */ 
    public void testProxyAuthConnectionFailed() throws Throwable { 
        // setting up the properties pointing to the key/trust stores 
        setUpStoreProperties(); 
 
        // create the SSLServerSocket which will be used by server side 
        ServerSocket ss = new ServerSocket(0);
 
        // create the HostnameVerifier to check that Hostname verification 
        // is done 
        TestHostnameVerifier hnv = new TestHostnameVerifier();
        HttpsURLConnection.setDefaultHostnameVerifier(hnv);
 
        // create HttpsURLConnection to be tested 
        URL url = new URL("https://requested.host:55555/requested.data");
        HttpsURLConnection connection = (HttpsURLConnection)
                url.openConnection(new Proxy(Proxy.Type.HTTP,
                                             new InetSocketAddress("localhost",
                                                                   ss.getLocalPort())));
        connection.setSSLSocketFactory(getContext().getSocketFactory());
 
        // perform the interaction between the peers and check the results 
        try { 
            doInteraction(connection, ss, AUTHENTICATION_REQUIRED_CODE, true);
        } catch (IOException e) {
            // SSL Tunnelling failed 
            if (DO_LOG) {
                System.out.println("Got expected IOException: "
                                   + e.getMessage());
            } 
        } 
    } 
 
    /** 
     * Tests the behaviour of HTTPS connection in case of unavailability 
     * of requested resource. 
     */ 
    public void testProxyConnection_Not_Found_Response() throws Throwable { 
        // setting up the properties pointing to the key/trust stores 
        setUpStoreProperties(); 
 
        // create the SSLServerSocket which will be used by server side 
        ServerSocket ss = new ServerSocket(0);
 
        // create the HostnameVerifier to check that Hostname verification 
        // is done 
        TestHostnameVerifier hnv = new TestHostnameVerifier();
        HttpsURLConnection.setDefaultHostnameVerifier(hnv);
 
        // create HttpsURLConnection to be tested 
        URL url = new URL("https://localhost:" + ss.getLocalPort());
        HttpsURLConnection connection = (HttpsURLConnection)
                url.openConnection(new Proxy(Proxy.Type.HTTP,
                                             new InetSocketAddress("localhost",
                                                                   ss.getLocalPort())));
        connection.setSSLSocketFactory(getContext().getSocketFactory());
 
        try { 
            doInteraction(connection, ss, NOT_FOUND_CODE); // NOT FOUND
            fail("Expected exception was not thrown.");
        } catch (FileNotFoundException e) {
            if (DO_LOG) {
                System.out.println("Expected exception was thrown: "
                                   + e.getMessage());
            } 
        } 
    } 
 
    /** 
     * Log the name of the test case to be executed. 
     */ 
    public void setUp() throws Exception { 
        super.setUp(); 
 
        if (DO_LOG) {
            System.out.println();
            System.out.println("------------------------");
            System.out.println("------ " + getName());
            System.out.println("------------------------");
        } 
 
        if (store != null) {
            String ksFileName = ("org/apache/harmony/luni/tests/key_store."
                                 + KeyStore.getDefaultType().toLowerCase());
            InputStream in = getClass().getClassLoader().getResourceAsStream(ksFileName);
            FileOutputStream out = new FileOutputStream(store);
            BufferedInputStream bufIn = new BufferedInputStream(in, 8192);
            while (bufIn.available() > 0) {
                byte[] buf = new byte[128];
                int read = bufIn.read(buf);
                out.write(buf, 0, read);
            } 
            bufIn.close();
            out.close();
        } else { 
            fail("couldn't set up key store");
        } 
    } 
 
    public void tearDown() { 
        if (store != null) {
            store.delete();
        } 
    } 
 
    /** 
     * Checks the HttpsURLConnection getter's values and compares 
     * them with actual corresponding values of remote peer. 
     */ 
    public static void checkConnectionStateParameters( 
            HttpsURLConnection clientConnection, SSLSocket serverPeer)
            throws Exception { 
        SSLSession session = serverPeer.getSession();
 
        assertEquals(session.getCipherSuite(), clientConnection.getCipherSuite());
        assertEquals(session.getLocalPrincipal(), clientConnection.getPeerPrincipal());
        assertEquals(session.getPeerPrincipal(), clientConnection.getLocalPrincipal());
 
        Certificate[] serverCertificates = clientConnection.getServerCertificates();
        Certificate[] localCertificates = session.getLocalCertificates();
        assertTrue("Server certificates differ from expected",
                   Arrays.equals(serverCertificates, localCertificates));
 
        localCertificates = clientConnection.getLocalCertificates();
        serverCertificates = session.getPeerCertificates();
        assertTrue("Local certificates differ from expected",
                   Arrays.equals(serverCertificates, localCertificates));
    } 
 
    /** 
     * Returns the file name of the key/trust store. The key store file 
     * (named as "key_store." + extension equals to the default KeyStore 
     * type installed in the system in lower case) is searched in classpath. 
     * @throws junit.framework.AssertionFailedError if property was not set 
     * or file does not exist. 
     */ 
    private static String getKeyStoreFileName() {
        return store.getAbsolutePath();
    } 
 
    /** 
     * Builds and returns the context used for secure socket creation. 
     */ 
    private static SSLContext getContext() throws Exception {
        String type = KeyStore.getDefaultType();
        String keyStore = getKeyStoreFileName();
        File keyStoreFile = new File(keyStore);
        FileInputStream fis = new FileInputStream(keyStoreFile);
 
        KeyStore ks = KeyStore.getInstance(type);
        ks.load(fis, KS_PASSWORD.toCharArray());
        fis.close();
        if (DO_LOG && false) {
            TestKeyStore.dump("HttpsURLConnection.getContext", ks, KS_PASSWORD.toCharArray());
        } 
 
        String kmfAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfAlgorithm);
        kmf.init(ks, KS_PASSWORD.toCharArray());
        KeyManager[] keyManagers = kmf.getKeyManagers();
 
        String tmfAlgorthm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorthm);
        tmf.init(ks);
        TrustManager[] trustManagers = tmf.getTrustManagers();
 
        SSLContext ctx = SSLContext.getInstance("TLSv1");
        ctx.init(keyManagers, trustManagers, null);
        return ctx;
    } 
 
    /** 
     * Sets up the properties pointing to the key store and trust store 
     * and used as default values by JSSE staff. This is needed to test 
     * HTTPS behaviour in the case of default SSL Socket Factories. 
     */ 
    private static void setUpStoreProperties() throws Exception { 
        String type = KeyStore.getDefaultType();
 
        System.setProperty("javax.net.ssl.keyStoreType", type);
        System.setProperty("javax.net.ssl.keyStore", getKeyStoreFileName());
        System.setProperty("javax.net.ssl.keyStorePassword", KS_PASSWORD);
 
        System.setProperty("javax.net.ssl.trustStoreType", type);
        System.setProperty("javax.net.ssl.trustStore", getKeyStoreFileName());
        System.setProperty("javax.net.ssl.trustStorePassword", KS_PASSWORD);
    } 
 
    /** 
     * Performs interaction between client's HttpsURLConnection and 
     * servers side (ServerSocket). 
     */ 
    public static Socket doInteraction(final HttpsURLConnection clientConnection,
                                       final ServerSocket serverSocket)
            throws Throwable { 
        return doInteraction(clientConnection, serverSocket, OK_CODE, false);
    } 
 
    /** 
     * Performs interaction between client's HttpsURLConnection and 
     * servers side (ServerSocket). Server will response with specified 
     * response code. 
     */ 
    public static Socket doInteraction(final HttpsURLConnection clientConnection,
                                       final ServerSocket serverSocket,
                                       final int responseCode)
            throws Throwable { 
        return doInteraction(clientConnection, serverSocket, responseCode, false);
    } 
 
    /** 
     * Performs interaction between client's HttpsURLConnection and 
     * servers side (ServerSocket). Server will response with specified 
     * response code. 
     * @param doAuthentication specifies 
     * if the server needs client authentication. 
     */ 
    public static Socket doInteraction(final HttpsURLConnection clientConnection,
                                       final ServerSocket serverSocket,
                                       final int responseCode,
                                       final boolean doAuthentication)
            throws Throwable { 
        // set up the connection 
        clientConnection.setDoInput(true);
        clientConnection.setConnectTimeout(TIMEOUT);
        clientConnection.setReadTimeout(TIMEOUT);
 
        ServerWork server = new ServerWork(serverSocket, responseCode, doAuthentication);
 
        ClientConnectionWork client = new ClientConnectionWork(clientConnection);