1561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes/*
2561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  Licensed to the Apache Software Foundation (ASF) under one or more
3561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  contributor license agreements.  See the NOTICE file distributed with
4561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  this work for additional information regarding copyright ownership.
5561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  The ASF licenses this file to You under the Apache License, Version 2.0
6561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  (the "License"); you may not use this file except in compliance with
7561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  the License.  You may obtain a copy of the License at
8561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *
9561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *     http://www.apache.org/licenses/LICENSE-2.0
10561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *
11561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  Unless required by applicable law or agreed to in writing, software
12561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  distributed under the License is distributed on an "AS IS" BASIS,
13561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  See the License for the specific language governing permissions and
15561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  limitations under the License.
16561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes */
17561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
18561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughespackage org.apache.harmony.luni.tests.internal.net.www.protocol.https;
19561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
20561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.io.File;
21561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.io.FileInputStream;
22561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.io.FileNotFoundException;
23561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.io.IOException;
24561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.io.InputStream;
25561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.io.OutputStream;
26561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.io.PrintStream;
27561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.net.Authenticator;
28561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.net.HttpURLConnection;
29561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.net.InetSocketAddress;
30561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.net.PasswordAuthentication;
31561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.net.Proxy;
32561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.net.ServerSocket;
33561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.net.Socket;
34561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.net.SocketTimeoutException;
35561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.net.URL;
36561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.security.KeyStore;
37561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.security.cert.Certificate;
38561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.util.Arrays;
39561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
40561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport javax.net.ssl.HostnameVerifier;
41561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport javax.net.ssl.HttpsURLConnection;
42561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport javax.net.ssl.KeyManagerFactory;
43561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport javax.net.ssl.SSLContext;
44561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport javax.net.ssl.SSLServerSocket;
45561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport javax.net.ssl.SSLSession;
46561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport javax.net.ssl.SSLSocket;
47561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport javax.net.ssl.SSLSocketFactory;
48561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport javax.net.ssl.TrustManagerFactory;
49561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
50561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport junit.framework.AssertionFailedError;
51561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport junit.framework.TestCase;
52561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport junit.framework.TestSuite;
53561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
54561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes/**
55561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * Implementation independent test for HttpsURLConnection. The test needs
56561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * certstore file placed in system classpath and named as "key_store." + the
57561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * type of the default KeyStore installed in the system in lower case. <br>
58561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * For example: if default KeyStore type in the system is BKS (i.e.
59561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * java.security file sets up the property keystore.type=BKS), thus classpath
60561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * should point to the directory with "key_store.bks" file. <br>
61561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * This certstore file should contain self-signed certificate generated by
62561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * keytool utility in a usual way. <br>
63561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * The password to the certstore should be "password" (without quotes).
64561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes */
65561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughespublic class HttpsURLConnectionTest extends TestCase {
66561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
67561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    // the password to the store
68561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static final String KS_PASSWORD = "password";
69561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
70561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    // turn on/off logging
71561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static final boolean DO_LOG = false;
72561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
73561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    // read/connection timeout value
74561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static final int TIMEOUT = 5000;
75561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
76561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    // OK response code
77561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static final int OK_CODE = 200;
78561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
79561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    // Not Found response code
80561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static final int NOT_FOUND_CODE = 404;
81561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
82561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    // Proxy authentication required response code
83561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static final int AUTHENTICATION_REQUIRED_CODE = 407;
84561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
85561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    // fields keeping the system values of corresponding properties
86561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static String systemKeyStoreType;
87561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
88561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static String systemKeyStore;
89561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
90561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static String systemKeyStorePassword;
91561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
92561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static String systemTrustStoreType;
93561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
94561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static String systemTrustStore;
95561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
96561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static String systemTrustStorePassword;
97561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
98561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
99561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Checks that HttpsURLConnection's default SSLSocketFactory is operable.
100561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
101561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testGetDefaultSSLSocketFactory() throws Exception {
102561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // set up the properties defining the default values needed by SSL stuff
103561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        setUpStoreProperties();
104561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
105561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
106561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLSocketFactory defaultSSLSF = HttpsURLConnection
107561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .getDefaultSSLSocketFactory();
108561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            ServerSocket ss = new ServerSocket(0);
109561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            Socket s = defaultSSLSF
110561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .createSocket("localhost", ss.getLocalPort());
111561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            ss.accept();
112561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            s.close();
113561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            ss.close();
114561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } finally {
115561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // roll the properties back to system values
116561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            tearDownStoreProperties();
117561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
118561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
119561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
120561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
121561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Checks if HTTPS connection performs initial SSL handshake with the server
122561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * working over SSL, sends encrypted HTTP request, and receives expected
123561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * HTTP response. After HTTPS session if finished test checks connection
124561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * state parameters established by HttpsURLConnection.
125561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
126561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testHttpsConnection() throws Throwable {
127561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // set up the properties defining the default values needed by SSL stuff
128561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        setUpStoreProperties();
129561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
130561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
131561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the SSL server socket acting as a server
132561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLContext ctx = getContext();
133561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            ServerSocket ss = ctx.getServerSocketFactory()
134561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .createServerSocket(0);
135561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
136561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the HostnameVerifier to check hostname verification
137561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            TestHostnameVerifier hnv = new TestHostnameVerifier();
138561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection.setDefaultHostnameVerifier(hnv);
139561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
140561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create url connection to be tested
141561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            URL url = new URL("https://localhost:" + ss.getLocalPort());
142561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection connection = (HttpsURLConnection) url
143561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .openConnection();
144561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
145561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // perform the interaction between the peers
146561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
147561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
148561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // check the connection state
149561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            checkConnectionStateParameters(connection, peerSocket);
150561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
151561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // should silently exit
152561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            connection.connect();
153561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } finally {
154561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // roll the properties back to system values
155561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            tearDownStoreProperties();
156561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
157561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
158561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
159561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
160561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Checks if HTTPS connection performs initial SSL handshake with the server
161561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * working over SSL, sends encrypted HTTP request, and receives expected
162561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * HTTP response. After that it checks that the established connection is
163561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * persistent. After HTTPS session if finished test checks connection state
164561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * parameters established by HttpsURLConnection.
165561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
166561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testHttpsPersistentConnection() throws Throwable {
167561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // set up the properties defining the default values needed by SSL stuff
168561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        setUpStoreProperties();
169561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
170561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
171561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the SSL server socket acting as a server
172561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLContext ctx = getContext();
173561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            ServerSocket ss = ctx.getServerSocketFactory()
174561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .createServerSocket(0);
175561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
176561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the HostnameVerifier to check hostname verification
177561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            TestHostnameVerifier hnv = new TestHostnameVerifier();
178561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection.setDefaultHostnameVerifier(hnv);
179561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
180561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create url connection to be tested
181561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            URL url = new URL("https://localhost:" + ss.getLocalPort());
182561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection connection = (HttpsURLConnection) url
183561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .openConnection();
184561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
185561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // perform the interaction between the peers
186561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLSocket peerSocket = (SSLSocket) doPersistentInteraction(
187561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    connection, ss);
188561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
189561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // check the connection state
190561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            checkConnectionStateParameters(connection, peerSocket);
191561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
192561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // should silently exit
193561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            connection.connect();
194561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } finally {
195561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // roll the properties back to system values
196561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            tearDownStoreProperties();
197561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
198561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
199561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
200561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
201561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Tests the behaviour of HTTPS connection in case of unavailability of
202561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * requested resource.
203561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
204561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testHttpsConnection_Not_Found_Response() throws Throwable {
205561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // set up the properties defining the default values needed by SSL stuff
206561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        setUpStoreProperties();
207561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
208561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
209561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the SSL server socket acting as a server
210561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLContext ctx = getContext();
211561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            ServerSocket ss = ctx.getServerSocketFactory()
212561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .createServerSocket(0);
213561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
214561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the HostnameVerifier to check hostname verification
215561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            TestHostnameVerifier hnv = new TestHostnameVerifier();
216561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection.setDefaultHostnameVerifier(hnv);
217561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
218561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create url connection to be tested
219561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            URL url = new URL("https://localhost:" + ss.getLocalPort());
220561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection connection = (HttpsURLConnection) url
221561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .openConnection();
222561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
223561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            try {
224561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                doInteraction(connection, ss, NOT_FOUND_CODE);
225561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                fail("Expected exception was not thrown.");
226561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } catch (FileNotFoundException e) {
227561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (DO_LOG) {
228561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    System.out.println("Expected exception was thrown: "
229561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            + e.getMessage());
230561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
231561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
232561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
233561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // should silently exit
234561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            connection.connect();
235561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } finally {
236561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // roll the properties back to system values
237561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            tearDownStoreProperties();
238561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
239561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
240561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
241561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
242561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Tests possibility to set up the default SSLSocketFactory to be used by
243561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * HttpsURLConnection.
244561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
245561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testSetDefaultSSLSocketFactory() throws Throwable {
246561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // create the SSLServerSocket which will be used by server side
247561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLContext ctx = getContext();
248561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLServerSocket ss = (SSLServerSocket) ctx.getServerSocketFactory()
249561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .createServerSocket(0);
250561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
251561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLSocketFactory socketFactory = (SSLSocketFactory) ctx
252561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .getSocketFactory();
253561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // set up the factory as default
254561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory);
255561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // check the result
256561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertSame("Default SSLSocketFactory differs from expected",
257561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                socketFactory, HttpsURLConnection.getDefaultSSLSocketFactory());
258561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
259561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // create the HostnameVerifier to check hostname verification
260561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        TestHostnameVerifier hnv = new TestHostnameVerifier();
261561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        HttpsURLConnection.setDefaultHostnameVerifier(hnv);
262561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
263561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // create HttpsURLConnection to be tested
264561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        URL url = new URL("https://localhost:" + ss.getLocalPort());
265561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        HttpsURLConnection connection = (HttpsURLConnection) url
266561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .openConnection();
267561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
268561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        TestHostnameVerifier hnv_late = new TestHostnameVerifier();
269561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // late initialization: should not be used for created connection
270561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        HttpsURLConnection.setDefaultHostnameVerifier(hnv_late);
271561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
272561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // perform the interaction between the peers
273561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
274561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // check the connection state
275561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        checkConnectionStateParameters(connection, peerSocket);
276561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // check the verification process
277561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertTrue("Hostname verification was not done", hnv.verified);
278561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertFalse(
279561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                "Hostname verification should not be done by this verifier",
280561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                hnv_late.verified);
281561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // check the used SSLSocketFactory
282561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertSame("Default SSLSocketFactory should be used",
283561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                HttpsURLConnection.getDefaultSSLSocketFactory(), connection
2848d8858e39800de641b50f6e8e864af9cf68bedeaNarayan Kamath                .getSSLSocketFactory());
285561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
286561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // should silently exit
287561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        connection.connect();
288561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
289561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
290561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
291561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Tests possibility to set up the SSLSocketFactory to be used by
292561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * HttpsURLConnection.
293561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
294561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testSetSSLSocketFactory() throws Throwable {
295561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // create the SSLServerSocket which will be used by server side
296561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLContext ctx = getContext();
297561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLServerSocket ss = (SSLServerSocket) ctx.getServerSocketFactory()
298561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .createServerSocket(0);
299561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
300561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // create the HostnameVerifier to check hostname verification
301561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        TestHostnameVerifier hnv = new TestHostnameVerifier();
302561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        HttpsURLConnection.setDefaultHostnameVerifier(hnv);
303561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
304561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // create HttpsURLConnection to be tested
305561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        URL url = new URL("https://localhost:" + ss.getLocalPort());
306561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        HttpsURLConnection connection = (HttpsURLConnection) url
307561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .openConnection();
308561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
309561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLSocketFactory socketFactory = (SSLSocketFactory) ctx
310561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .getSocketFactory();
311561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        connection.setSSLSocketFactory(socketFactory);
312561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
313561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        TestHostnameVerifier hnv_late = new TestHostnameVerifier();
314561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // late initialization: should not be used for created connection
315561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        HttpsURLConnection.setDefaultHostnameVerifier(hnv_late);
316561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
317561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // perform the interaction between the peers
318561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
319561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // check the connection state
320561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        checkConnectionStateParameters(connection, peerSocket);
321561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // check the verification process
322561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertTrue("Hostname verification was not done", hnv.verified);
323561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertFalse(
324561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                "Hostname verification should not be done by this verifier",
325561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                hnv_late.verified);
326561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // check the used SSLSocketFactory
327561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertNotSame("Default SSLSocketFactory should not be used",
328561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                HttpsURLConnection.getDefaultSSLSocketFactory(), connection
3298d8858e39800de641b50f6e8e864af9cf68bedeaNarayan Kamath                .getSSLSocketFactory());
330561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertSame("Result differs from expected", socketFactory, connection
331561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .getSSLSocketFactory());
332561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
333561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // should silently exit
334561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        connection.connect();
335561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
336561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
337561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
338561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Tests the behaviour of HttpsURLConnection in case of retrieving of the
339561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * connection state parameters before connection has been made.
340561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
341561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testUnconnectedStateParameters() throws Throwable {
342561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // create HttpsURLConnection to be tested
343561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        URL url = new URL("https://localhost:55555");
344561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        HttpsURLConnection connection = (HttpsURLConnection) url
345561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .openConnection();
346561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
347561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
348561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            connection.getCipherSuite();
349561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            fail("Expected IllegalStateException was not thrown");
350561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } catch (IllegalStateException e) {
351561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
352561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
353561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            connection.getPeerPrincipal();
354561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            fail("Expected IllegalStateException was not thrown");
355561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } catch (IllegalStateException e) {
356561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
357561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
358561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            connection.getLocalPrincipal();
359561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            fail("Expected IllegalStateException was not thrown");
360561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } catch (IllegalStateException e) {
361561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
362561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
363561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
364561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            connection.getServerCertificates();
365561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            fail("Expected IllegalStateException was not thrown");
366561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } catch (IllegalStateException e) {
367561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
368561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
369561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            connection.getLocalCertificates();
370561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            fail("Expected IllegalStateException was not thrown");
371561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } catch (IllegalStateException e) {
372561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
373561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
374561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
375561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
376561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Tests if setHostnameVerifier() method replaces default verifier.
377561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
378561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testSetHostnameVerifier() throws Throwable {
379561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // setting up the properties pointing to the key/trust stores
380561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        setUpStoreProperties();
381561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
382561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
383561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the SSLServerSocket which will be used by server side
384561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLServerSocket ss = (SSLServerSocket) getContext()
385561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .getServerSocketFactory().createServerSocket(0);
386561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
387561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the HostnameVerifier to check that Hostname verification
388561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // is done
389561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            TestHostnameVerifier hnv = new TestHostnameVerifier();
390561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection.setDefaultHostnameVerifier(hnv);
391561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
392561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create HttpsURLConnection to be tested
393561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            URL url = new URL("https://localhost:" + ss.getLocalPort());
394561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection connection = (HttpsURLConnection) url
395561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .openConnection();
396561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
397561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            TestHostnameVerifier hnv_late = new TestHostnameVerifier();
398561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // replace default verifier
399561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            connection.setHostnameVerifier(hnv_late);
400561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
401561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // perform the interaction between the peers and check the results
402561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
403561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertTrue("Hostname verification was not done", hnv_late.verified);
404561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertFalse(
405561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    "Hostname verification should not be done by this verifier",
406561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    hnv.verified);
407561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            checkConnectionStateParameters(connection, peerSocket);
408561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
409561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // should silently exit
410561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            connection.connect();
411561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } finally {
412561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // roll the properties back to system values
413561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            tearDownStoreProperties();
414561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
415561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
416561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
417561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
418561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Tests the behaviour in case of sending the data to the server.
419561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
420561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void test_doOutput() throws Throwable {
421561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // setting up the properties pointing to the key/trust stores
422561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        setUpStoreProperties();
423561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
424561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
425561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the SSLServerSocket which will be used by server side
426561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLServerSocket ss = (SSLServerSocket) getContext()
427561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .getServerSocketFactory().createServerSocket(0);
428561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
429561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the HostnameVerifier to check that Hostname verification
430561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // is done
431561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            TestHostnameVerifier hnv = new TestHostnameVerifier();
432561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection.setDefaultHostnameVerifier(hnv);
433561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
434561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create HttpsURLConnection to be tested
435561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            URL url = new URL("https://localhost:" + ss.getLocalPort());
436561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection connection = (HttpsURLConnection) url
437561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .openConnection();
438561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            connection.setDoOutput(true);
439561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
440561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // perform the interaction between the peers and check the results
441561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
442561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            checkConnectionStateParameters(connection, peerSocket);
443561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
444561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // should silently exit
445561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            connection.connect();
446561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } finally {
447561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // roll the properties back to system values
448561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            tearDownStoreProperties();
449561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
450561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
451561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
452561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
453561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Tests the behaviour in case of sending the data to the server over
454561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * persistent connection.
455561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
456561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testPersistence_doOutput() throws Throwable {
457561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // setting up the properties pointing to the key/trust stores
458561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        setUpStoreProperties();
459561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
460561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
461561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the SSLServerSocket which will be used by server side
462561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLServerSocket ss = (SSLServerSocket) getContext()
463561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .getServerSocketFactory().createServerSocket(0);
464561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
465561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the HostnameVerifier to check that Hostname verification
466561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // is done
467561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            TestHostnameVerifier hnv = new TestHostnameVerifier();
468561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection.setDefaultHostnameVerifier(hnv);
469561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
470561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create HttpsURLConnection to be tested
471561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            URL url = new URL("https://localhost:" + ss.getLocalPort());
472561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection connection = (HttpsURLConnection) url
473561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .openConnection();
474561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            connection.setDoOutput(true);
475561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
476561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // perform the interaction between the peers and check the results
477561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLSocket peerSocket = (SSLSocket) doPersistentInteraction(
478561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    connection, ss);
479561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            checkConnectionStateParameters(connection, peerSocket);
480561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
481561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // should silently exit
482561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            connection.connect();
483561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } finally {
484561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // roll the properties back to system values
485561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            tearDownStoreProperties();
486561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
487561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
488561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
489561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
490561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Tests HTTPS connection process made through the proxy server.
491561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
492561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testProxyConnection() throws Throwable {
493561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // setting up the properties pointing to the key/trust stores
494561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        setUpStoreProperties();
495561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
496561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
497561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the SSLServerSocket which will be used by server side
498561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            ServerSocket ss = new ServerSocket(0);
499561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
500561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the HostnameVerifier to check that Hostname verification
501561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // is done
502561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            TestHostnameVerifier hnv = new TestHostnameVerifier();
503561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection.setDefaultHostnameVerifier(hnv);
504561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
505561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create HttpsURLConnection to be tested
506561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            URL url = new URL("https://requested.host:55556/requested.data");
507561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection connection = (HttpsURLConnection) url
508561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .openConnection(new Proxy(Proxy.Type.HTTP,
509561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            new InetSocketAddress("localhost", ss
510561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                    .getLocalPort())));
511561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
512561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // perform the interaction between the peers and check the results
513561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
514561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            checkConnectionStateParameters(connection, peerSocket);
515561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
516561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // should silently exit
517561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            connection.connect();
518561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } finally {
519561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // roll the properties back to system values
520561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            tearDownStoreProperties();
521561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
522561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
523561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
524561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
525561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Tests HTTPS connection process made through the proxy server. Checks that
526561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * persistent connection to the host exists and can be used no in spite of
527561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * explicit Proxy specifying.
528561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
529561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testPersistentProxyConnection() throws Throwable {
530561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // setting up the properties pointing to the key/trust stores
531561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        setUpStoreProperties();
532561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
533561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
534561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the SSLServerSocket which will be used by server side
535561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            ServerSocket ss = new ServerSocket(0);
536561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
537561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the HostnameVerifier to check that Hostname verification
538561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // is done
539561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            TestHostnameVerifier hnv = new TestHostnameVerifier();
540561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection.setDefaultHostnameVerifier(hnv);
541561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
542561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create HttpsURLConnection to be tested
543561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            URL url = new URL("https://requested.host:55556/requested.data");
544561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection connection = (HttpsURLConnection) url
545561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .openConnection(new Proxy(Proxy.Type.HTTP,
546561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            new InetSocketAddress("localhost", ss
547561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                    .getLocalPort())));
548561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
549561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // perform the interaction between the peers and check the results
550561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLSocket peerSocket = (SSLSocket) doPersistentInteraction(
551561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    connection, ss);
552561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            checkConnectionStateParameters(connection, peerSocket);
553561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
554561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // should silently exit
555561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            connection.connect();
556561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } finally {
557561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // roll the properties back to system values
558561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            tearDownStoreProperties();
559561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
560561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
561561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
562561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
563561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Tests HTTPS connection process made through the proxy server. Proxy
564561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * server needs authentication.
565561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
566561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testProxyAuthConnection() throws Throwable {
567561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // setting up the properties pointing to the key/trust stores
568561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        setUpStoreProperties();
569561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
570561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
571561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the SSLServerSocket which will be used by server side
572561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            ServerSocket ss = new ServerSocket(0);
573561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
574561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the HostnameVerifier to check that Hostname verification
575561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // is done
576561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            TestHostnameVerifier hnv = new TestHostnameVerifier();
577561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection.setDefaultHostnameVerifier(hnv);
578561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
579561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            Authenticator.setDefault(new Authenticator() {
580561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
581561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                protected PasswordAuthentication getPasswordAuthentication() {
582561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    return new PasswordAuthentication("user", "password"
583561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            .toCharArray());
584561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
585561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            });
586561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
587561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create HttpsURLConnection to be tested
588561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            URL url = new URL("https://requested.host:55555/requested.data");
589561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection connection = (HttpsURLConnection) url
590561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .openConnection(new Proxy(Proxy.Type.HTTP,
591561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            new InetSocketAddress("localhost", ss
592561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                    .getLocalPort())));
593561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
594561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // perform the interaction between the peers and check the results
595561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
596561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            checkConnectionStateParameters(connection, peerSocket);
597561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
598561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // should silently exit
599561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            connection.connect();
600561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } finally {
601561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // roll the properties back to system values
602561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            tearDownStoreProperties();
603561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
604561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
605561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
606561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
607561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Tests HTTPS connection process made through the proxy server. 2 HTTPS
608561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * connections are opened for one URL. For the first time the connection is
609561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * opened through one proxy, for the second time through another.
610561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
611561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testConsequentProxyConnection() throws Throwable {
612561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // setting up the properties pointing to the key/trust stores
613561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        setUpStoreProperties();
614561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
615561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
616561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the SSLServerSocket which will be used by server side
617561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            ServerSocket ss = new ServerSocket(0);
618561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
619561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the HostnameVerifier to check that Hostname verification
620561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // is done
621561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            TestHostnameVerifier hnv = new TestHostnameVerifier();
622561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection.setDefaultHostnameVerifier(hnv);
623561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
624561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create HttpsURLConnection to be tested
625561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            URL url = new URL("https://requested.host:55555/requested.data");
626561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection connection = (HttpsURLConnection) url
627561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .openConnection(new Proxy(Proxy.Type.HTTP,
628561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            new InetSocketAddress("localhost", ss
629561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                    .getLocalPort())));
630561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
631561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // perform the interaction between the peers and check the results
632561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
633561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            checkConnectionStateParameters(connection, peerSocket);
634561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
635561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create another SSLServerSocket which will be used by server side
636561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            ss = new ServerSocket(0);
637561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
638561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            connection = (HttpsURLConnection) url.openConnection(new Proxy(
639561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    Proxy.Type.HTTP, new InetSocketAddress("localhost", ss
6408d8858e39800de641b50f6e8e864af9cf68bedeaNarayan Kamath                    .getLocalPort())));
641561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
642561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // perform the interaction between the peers and check the results
643561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            peerSocket = (SSLSocket) doInteraction(connection, ss);
644561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            checkConnectionStateParameters(connection, peerSocket);
645561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } finally {
646561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // roll the properties back to system values
647561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            tearDownStoreProperties();
648561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
649561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
650561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
651561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
652561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Tests HTTPS connection process made through the proxy server. Proxy
653561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * server needs authentication. Client sends data to the server.
654561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
655561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testProxyAuthConnection_doOutput() throws Throwable {
656561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // setting up the properties pointing to the key/trust stores
657561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        setUpStoreProperties();
658561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
659561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
660561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the SSLServerSocket which will be used by server side
661561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            ServerSocket ss = new ServerSocket(0);
662561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
663561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the HostnameVerifier to check that Hostname verification
664561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // is done
665561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            TestHostnameVerifier hnv = new TestHostnameVerifier();
666561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection.setDefaultHostnameVerifier(hnv);
667561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
668561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            Authenticator.setDefault(new Authenticator() {
669561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
670561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                protected PasswordAuthentication getPasswordAuthentication() {
671561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    return new PasswordAuthentication("user", "password"
672561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            .toCharArray());
673561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
674561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            });
675561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
676561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create HttpsURLConnection to be tested
677561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            URL url = new URL("https://requested.host:55554/requested.data");
678561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection connection = (HttpsURLConnection) url
679561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .openConnection(new Proxy(Proxy.Type.HTTP,
680561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            new InetSocketAddress("localhost", ss
681561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                    .getLocalPort())));
682561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            connection.setDoOutput(true);
683561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
684561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // perform the interaction between the peers and check the results
685561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss,
686561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    OK_CODE);
687561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            checkConnectionStateParameters(connection, peerSocket);
688561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } finally {
689561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // roll the properties back to system values
690561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            tearDownStoreProperties();
691561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
692561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
693561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
694561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
695561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Tests HTTPS connection process made through the proxy server. Proxy
696561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * server needs authentication but client fails to authenticate
697561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * (Authenticator was not set up in the system).
698561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
699561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testProxyAuthConnectionFailed() throws Throwable {
700561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // setting up the properties pointing to the key/trust stores
701561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        setUpStoreProperties();
702561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
703561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
704561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the SSLServerSocket which will be used by server side
705561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            ServerSocket ss = new ServerSocket(0);
706561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
707561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the HostnameVerifier to check that Hostname verification
708561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // is done
709561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            TestHostnameVerifier hnv = new TestHostnameVerifier();
710561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection.setDefaultHostnameVerifier(hnv);
711561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
712561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create HttpsURLConnection to be tested
713561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            URL url = new URL("https://requested.host:55555/requested.data");
714561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpURLConnection connection = (HttpURLConnection) url
715561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .openConnection(new Proxy(Proxy.Type.HTTP,
716561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            new InetSocketAddress("localhost", ss
717561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                    .getLocalPort())));
718561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
719561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // perform the interaction between the peers and check the results
720561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            try {
721561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                doInteraction(connection, ss, AUTHENTICATION_REQUIRED_CODE);
722561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } catch (IOException e) {
723561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // SSL Tunnelling failed
724561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (DO_LOG) {
725561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    System.out.println("Got expected IOException: "
726561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            + e.getMessage());
727561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
728561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
729561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } finally {
730561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // roll the properties back to system values
731561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            tearDownStoreProperties();
732561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
733561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
734561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
735561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
736561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Tests the behaviour of HTTPS connection in case of unavailability of
737561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * requested resource.
738561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
739561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testProxyConnection_Not_Found_Response() throws Throwable {
740561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // setting up the properties pointing to the key/trust stores
741561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        setUpStoreProperties();
742561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
743561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
744561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the SSLServerSocket which will be used by server side
745561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            ServerSocket ss = new ServerSocket(0);
746561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
747561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create the HostnameVerifier to check that Hostname verification
748561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // is done
749561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            TestHostnameVerifier hnv = new TestHostnameVerifier();
750561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection.setDefaultHostnameVerifier(hnv);
751561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
752561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // create HttpsURLConnection to be tested
753561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            URL url = new URL("https://localhost:" + ss.getLocalPort());
754561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpURLConnection connection = (HttpURLConnection) url
755561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .openConnection(new Proxy(Proxy.Type.HTTP,
756561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            new InetSocketAddress("localhost", ss
757561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                    .getLocalPort())));
758561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
759561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            try {
760561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                doInteraction(connection, ss, NOT_FOUND_CODE); // NOT FOUND
761561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                fail("Expected exception was not thrown.");
762561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } catch (FileNotFoundException e) {
763561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (DO_LOG) {
764561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    System.out.println("Expected exception was thrown: "
765561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            + e.getMessage());
766561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
767561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
768561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } finally {
769561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // roll the properties back to system values
770561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            tearDownStoreProperties();
771561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
772561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
773561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
774561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    // ---------------------------------------------------------------------
775561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    // ------------------------ Staff Methods ------------------------------
776561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    // ---------------------------------------------------------------------
777561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
778561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
779561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Log the name of the test case to be executed.
780561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
781561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void setUp() throws Exception {
782561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (DO_LOG) {
783561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println();
784561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("------------------------");
785561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("------ " + getName());
786561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("------------------------");
787561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
788561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
789561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
790561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
791561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Checks the HttpsURLConnection getter's values and compares them with
792561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * actual corresponding values of remote peer.
793561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
794561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public static void checkConnectionStateParameters(
795561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            HttpsURLConnection clientConnection, SSLSocket serverPeer)
796561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            throws Exception {
797561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLSession session = serverPeer.getSession();
798561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
799561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals(session.getCipherSuite(), clientConnection
800561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .getCipherSuite());
801561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
802561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals(session.getLocalPrincipal(), clientConnection
803561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .getPeerPrincipal());
804561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
805561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals(session.getPeerPrincipal(), clientConnection
806561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .getLocalPrincipal());
807561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
808561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        Certificate[] serverCertificates = clientConnection
809561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .getServerCertificates();
810561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        Certificate[] localCertificates = session.getLocalCertificates();
811561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertTrue("Server certificates differ from expected", Arrays.equals(
812561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                serverCertificates, localCertificates));
813561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
814561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        localCertificates = clientConnection.getLocalCertificates();
815561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        serverCertificates = session.getPeerCertificates();
816561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertTrue("Local certificates differ from expected", Arrays.equals(
817561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                serverCertificates, localCertificates));
818561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
819561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
820561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
821561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Returns the file name of the key/trust store. The key store file (named
822561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * as "key_store." + extension equals to the default KeyStore type installed
823561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * in the system in lower case) is searched in classpath.
824e98fbf8686c5289bf03fe5c3de7ff82d3a77104dElliott Hughes     *
8258d8858e39800de641b50f6e8e864af9cf68bedeaNarayan Kamath     * @throws AssertionFailedError if property was not set or file does not exist.
826561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
827561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static String getKeyStoreFileName() throws Exception {
828561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String ksFileName = "org/apache/harmony/luni/tests/key_store."
829561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + KeyStore.getDefaultType().toLowerCase();
830561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        URL url = ClassLoader.getSystemClassLoader().getResource(ksFileName);
831561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertNotNull("Expected KeyStore file: '" + ksFileName
832561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + "' for default KeyStore of type '"
833561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + KeyStore.getDefaultType() + "' does not exist.", url);
834561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        return new File(url.toURI()).getAbsolutePath();
835561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
836561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
837561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
838561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Builds and returns the context used for secure socket creation.
839561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
840561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static SSLContext getContext() throws Exception {
841561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String type = KeyStore.getDefaultType();
842561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLContext ctx;
843561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
844561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String keyStore = getKeyStoreFileName();
845561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        File keyStoreFile = new File(keyStore);
846561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
847561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        FileInputStream fis = new FileInputStream(keyStoreFile);
848561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
849561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        KeyStore ks = KeyStore.getInstance(type);
850561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ks.load(fis, KS_PASSWORD.toCharArray());
851561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
852561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
853561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .getDefaultAlgorithm());
854561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        kmf.init(ks, KS_PASSWORD.toCharArray());
855561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
856561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        TrustManagerFactory tmf = TrustManagerFactory
857561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .getInstance(TrustManagerFactory.getDefaultAlgorithm());
858561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        tmf.init(ks);
859561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
860561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ctx = SSLContext.getInstance("TLSv1");
861561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
862561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
863561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        return ctx;
864561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
865561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
866561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
867561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Sets up the properties pointing to the key store and trust store and used
868561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * as default values by JSSE staff. This is needed to test HTTPS behaviour
869561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * in the case of default SSL Socket Factories.
870561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
871561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static void setUpStoreProperties() throws Exception {
872561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String type = KeyStore.getDefaultType();
873561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
874561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        systemKeyStoreType = System.getProperty("javax.net.ssl.keyStoreType");
875561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        systemKeyStore = System.getProperty("javax.net.ssl.keyStore");
876561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        systemKeyStorePassword = System
877561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .getProperty("javax.net.ssl.keyStorePassword");
878561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
879561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        systemTrustStoreType = System
880561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .getProperty("javax.net.ssl.trustStoreType");
881561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        systemTrustStore = System.getProperty("javax.net.ssl.trustStore");
882561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        systemTrustStorePassword = System
883561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .getProperty("javax.net.ssl.trustStorePassword");
884561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
885561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        System.setProperty("javax.net.ssl.keyStoreType", type);
886561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        System.setProperty("javax.net.ssl.keyStore", getKeyStoreFileName());
887561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        System.setProperty("javax.net.ssl.keyStorePassword", KS_PASSWORD);
888561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
889561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        System.setProperty("javax.net.ssl.trustStoreType", type);
890561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        System.setProperty("javax.net.ssl.trustStore", getKeyStoreFileName());
891561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        System.setProperty("javax.net.ssl.trustStorePassword", KS_PASSWORD);
892561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
893561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
894561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
895561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Rolls back the values of system properties.
896561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
897561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static void tearDownStoreProperties() {
898561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (systemKeyStoreType == null) {
899561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.clearProperty("javax.net.ssl.keyStoreType");
900561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } else {
901561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System
902561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .setProperty("javax.net.ssl.keyStoreType",
903561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            systemKeyStoreType);
904561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
905561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (systemKeyStore == null) {
906561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.clearProperty("javax.net.ssl.keyStore");
907561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } else {
908561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.setProperty("javax.net.ssl.keyStore", systemKeyStore);
909561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
910561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (systemKeyStorePassword == null) {
911561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.clearProperty("javax.net.ssl.keyStorePassword");
912561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } else {
913561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.setProperty("javax.net.ssl.keyStorePassword",
914561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    systemKeyStorePassword);
915561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
916561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
917561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (systemTrustStoreType == null) {
918561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.clearProperty("javax.net.ssl.trustStoreType");
919561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } else {
920561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.setProperty("javax.net.ssl.trustStoreType",
921561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    systemTrustStoreType);
922561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
923561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (systemTrustStore == null) {
924561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.clearProperty("javax.net.ssl.trustStore");
925561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } else {
926561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.setProperty("javax.net.ssl.trustStore", systemTrustStore);
927561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
928561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (systemTrustStorePassword == null) {
929561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.clearProperty("javax.net.ssl.trustStorePassword");
930561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } else {
931561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.setProperty("javax.net.ssl.trustStorePassword",
932561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    systemTrustStorePassword);
933561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
934561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
935561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
936561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
937561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Performs interaction between client's HttpURLConnection and servers side
938561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * (ServerSocket).
939561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
940561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public static Socket doInteraction(
941561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final HttpURLConnection clientConnection,
942561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final ServerSocket serverSocket) throws Throwable {
943561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        return doInteraction(clientConnection, serverSocket, OK_CODE, false,
944561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                false);
945561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
946561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
947561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
948561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Performs interaction between client's HttpURLConnection and servers side
949561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * (ServerSocket). Server will response with specified response code.
950561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
951561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public static Socket doInteraction(
952561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final HttpURLConnection clientConnection,
953561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final ServerSocket serverSocket, final int responseCode)
954561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            throws Throwable {
955561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        return doInteraction(clientConnection, serverSocket, responseCode,
956561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                false, false);
957561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
958561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
959561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
960561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Performs interaction between client's HttpURLConnection and servers side
961561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * (ServerSocket) over persistent connection.
962561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
963561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public static Socket doPersistentInteraction(
964561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final HttpURLConnection clientConnection,
965561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final ServerSocket serverSocket) throws Throwable {
966561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        return doInteraction(clientConnection, serverSocket, OK_CODE, false,
967561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                true);
968561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
969561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
970561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
971561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Performs interaction between client's HttpURLConnection and servers side
972561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * (ServerSocket) over persistent connection. Server will response with
973561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * specified response code.
974561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
975561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public static Socket doPersistentInteraction(
976561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final HttpURLConnection clientConnection,
977561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final ServerSocket serverSocket, final int responseCode)
978561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            throws Throwable {
979561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        return doInteraction(clientConnection, serverSocket, responseCode,
980561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                false, true);
981561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
982561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
983561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
984561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Performs interaction between client's HttpURLConnection and servers side
985561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * (ServerSocket). Server will response with specified response code.
986e98fbf8686c5289bf03fe5c3de7ff82d3a77104dElliott Hughes     *
9878d8858e39800de641b50f6e8e864af9cf68bedeaNarayan Kamath     * @param doAuthentication specifies if the server needs client authentication.
988561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
989561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public static Socket doInteraction(
990561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final HttpURLConnection clientConnection,
991561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final ServerSocket serverSocket, final int responseCode,
992561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final boolean doAuthentication, final boolean checkPersistence)
993561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            throws Throwable {
994561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
995561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // set up the connection
996561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        clientConnection.setDoInput(true);
997561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        clientConnection.setConnectTimeout(TIMEOUT);
998561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        clientConnection.setReadTimeout(TIMEOUT);
999561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1000561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ServerWork server = new ServerWork(serverSocket, responseCode,
1001561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                doAuthentication, checkPersistence);
1002561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1003561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ClientConnectionWork client = new ClientConnectionWork(clientConnection);
1004561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1005561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        server.start();
1006561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        client.start();
1007561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1008561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        client.join();
1009561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (client.thrown != null) {
1010561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (responseCode != OK_CODE) { // not OK response expected
1011561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // it is probably expected exception, keep it as is
1012561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                throw client.thrown;
1013561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1014561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if ((client.thrown instanceof SocketTimeoutException)
1015561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    && (server.thrown != null)) {
1016561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // server's exception is more informative in this case
1017561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                throw new Exception(server.thrown);
1018561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } else {
1019561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                throw new Exception(client.thrown);
1020561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1021561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1022561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1023561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (checkPersistence) {
1024561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            ClientConnectionWork client2 = new ClientConnectionWork(
1025561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    (HttpURLConnection) clientConnection.getURL()
1026561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            .openConnection());
1027561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            client2.start();
1028561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            client2.join();
1029561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (client2.thrown != null) {
1030561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (responseCode != OK_CODE) { // not OK response expected
1031561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    // it is probably expected exception, keep it as is
1032561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    throw client2.thrown;
1033561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
1034561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if ((client2.thrown instanceof SocketTimeoutException)
1035561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        && (server.thrown != null)) {
1036561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    // server's exception is more informative in this case
1037561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    throw new Exception(server.thrown);
1038561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                } else {
1039561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    throw new Exception(client2.thrown);
1040561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
1041561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1042561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1043561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1044561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        server.join();
1045561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1046561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (server.thrown != null) {
1047561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            throw server.thrown;
1048561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1049561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        return server.peerSocket;
1050561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
1051561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1052561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
1053561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * The host name verifier used in test.
1054561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
1055561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    static class TestHostnameVerifier implements HostnameVerifier {
1056561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1057561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        boolean verified = false;
1058561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1059561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        public boolean verify(String hostname, SSLSession session) {
1060561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (DO_LOG) {
1061561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                System.out.println("***> verification " + hostname + " "
1062561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        + session.getPeerHost());
1063561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1064561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            verified = true;
1065561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            return true;
1066561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1067561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
1068561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1069561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
1070561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * The base class for mock Client and Server.
1071561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
1072561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    static class Work extends Thread {
1073561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1074561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1075561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The header of OK HTTP response.
1076561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1077561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        static String responseHead = "HTTP/1.1 200 OK\n";
1078561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1079561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1080561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The content of the response.
1081561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1082561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        static String plainResponseContent = "<HTML>\n"
1083561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + "<HEAD><TITLE>Plain Response Content</TITLE></HEAD>\n"
1084561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + "</HTML>";
1085561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1086561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1087561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The tail of the response.
1088561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1089561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        static String plainResponseTail = "Content-type: text/html\n"
1090561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + "Content-length: " + plainResponseContent.length() + "\n\n"
1091561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + plainResponseContent;
1092561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1093561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1094561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The response message to be sent in plain (HTTP) format.
1095561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1096561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        static String plainResponse = responseHead + plainResponseTail;
1097561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1098561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1099561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The content of the response to be sent during HTTPS session.
1100561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1101561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        static String httpsResponseContent = "<HTML>\n"
1102561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + "<HEAD><TITLE>HTTPS Response Content</TITLE></HEAD>\n"
1103561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + "</HTML>";
1104561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1105561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1106561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The tail of the response to be sent during HTTPS session.
1107561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1108561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        static String httpsResponseTail = "Content-type: text/html\n"
1109561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + "Content-length: " + httpsResponseContent.length() + "\n\n"
1110561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + httpsResponseContent;
1111561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1112561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1113561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The response requiring client's proxy authentication.
1114561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1115561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        static String respAuthenticationRequired = "HTTP/1.0 407 Proxy authentication required\n"
1116561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + "Proxy-authenticate: Basic realm=\"localhost\"\n\n";
1117561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1118561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1119561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The data to be posted by client to the server.
1120561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1121561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        static String clientsData = "_.-^ Client's Data ^-._";
1122561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1123561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1124561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The exception thrown during peers interaction.
1125561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1126561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        protected Throwable thrown;
1127561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1128561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1129561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The print stream used for debug log. If it is null debug info will
1130561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * not be printed.
1131561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1132561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        private PrintStream out = new PrintStream(System.out);
1133561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1134561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1135561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * Prints log message.
1136561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1137561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        public synchronized void log(String message) {
1138561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (DO_LOG && (out != null)) {
1139561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                System.out.println("[" + getName() + "]: " + message);
1140561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1141561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1142561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
1143561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1144561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
1145561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * The class used for server side works.
1146561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
1147561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    static class ServerWork extends Work {
1148561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1149561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // the server socket used for connection
1150561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        private ServerSocket serverSocket;
1151561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1152561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // the socket connected with client peer
1153561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        private Socket peerSocket;
1154561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1155561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // indicates if the server acts as proxy server
1156561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        private boolean actAsProxy;
1157561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1158561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // indicates if the server needs proxy authentication
1159561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        private boolean needProxyAuthentication;
1160561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1161561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // do we check for connection persistence
1162561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        private boolean checkPersistence;
1163561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1164561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // response code to be send to the client peer
1165561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        private int responseCode;
1166561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1167561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1168561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * Creates the thread acting as a server side.
1169561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1170561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        public ServerWork(ServerSocket serverSocket) {
1171561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // the server does not require proxy authentication
1172561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // and sends OK_CODE (OK) response code
1173561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            this(serverSocket, OK_CODE, false, false);
1174561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1175561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1176561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1177561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * Creates the thread acting as a server side.
1178e98fbf8686c5289bf03fe5c3de7ff82d3a77104dElliott Hughes         *
11798d8858e39800de641b50f6e8e864af9cf68bedeaNarayan Kamath         * @param serverSocket            the server socket to be used during connection
11808d8858e39800de641b50f6e8e864af9cf68bedeaNarayan Kamath         * @param responseCode            the response code to be sent to the client
11818d8858e39800de641b50f6e8e864af9cf68bedeaNarayan Kamath         * @param needProxyAuthentication indicates if the server needs proxy authentication
1182561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1183561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        public ServerWork(ServerSocket serverSocket, int responseCode,
1184561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                boolean needProxyAuthentication, boolean checkPersistence) {
1185561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            this.serverSocket = serverSocket;
1186561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            this.responseCode = responseCode;
1187561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            this.needProxyAuthentication = needProxyAuthentication;
1188561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            this.checkPersistence = checkPersistence;
1189561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // will act as a proxy server if the specified server socket
1190561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // is not a secure server socket
1191561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (serverSocket instanceof SSLServerSocket) {
1192561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // demand client to send its certificate
1193561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                ((SSLServerSocket) serverSocket).setNeedClientAuth(true);
1194561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // work as a HTTPS server, not as HTTP proxy
1195561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                this.actAsProxy = false;
1196561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } else {
1197561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                this.actAsProxy = true;
1198561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1199561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            this.actAsProxy = !(serverSocket instanceof SSLServerSocket);
1200561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            setName(this.actAsProxy ? "Proxy Server" : "Server");
1201561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1202561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1203561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1204561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * Closes the connection.
1205561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1206561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        public void closeSocket(Socket socket) {
1207561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            try {
1208561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                socket.getInputStream().close();
1209561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } catch (IOException e) {
1210561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1211561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            try {
1212561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                socket.getOutputStream().close();
1213561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } catch (IOException e) {
1214561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1215561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            try {
1216561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                socket.close();
1217561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } catch (IOException e) {
1218561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1219561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1220561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1221561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1222561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * Performs the actual server work. If some exception occurs during the
1223561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * work it will be stored in the <code>thrown</code> field.
1224561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1225561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        public void run() {
1226561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // the buffer used for reading the messages
1227561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            byte[] buff = new byte[2048];
1228561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // the number of bytes read into the buffer
1229561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            int num;
1230561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            try {
1231561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // configure the server socket to avoid blocking
1232561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                serverSocket.setSoTimeout(TIMEOUT);
1233561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // accept client connection
1234561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                peerSocket = serverSocket.accept();
1235561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // configure the client connection to avoid blocking
1236561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                peerSocket.setSoTimeout(TIMEOUT);
1237561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                log("Client connection ACCEPTED");
1238561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1239561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                InputStream is = peerSocket.getInputStream();
1240561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                OutputStream os = peerSocket.getOutputStream();
1241561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1242561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // how many times established connection will be used
1243561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                int number_of_uses = checkPersistence ? 2 : 1;
1244561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                for (int it = 0; it < number_of_uses; it++) {
1245561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (checkPersistence) {
1246561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("==========================================");
1247561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("Use established connection for " + (it + 1)
1248561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                + " time");
1249561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
1250561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1251561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    num = is.read(buff);
1252561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    String message = new String(buff, 0, num, "UTF-8");
1253561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    log("Got request:\n" + message);
1254561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    log("------------------");
1255561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1256561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (!actAsProxy) {
1257561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // Act as Server (not Proxy) side
1258561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        if (message.startsWith("POST")) {
1259561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            // client connection sent some data
1260561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            log("try to read client data");
1261561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            num = is.read(buff);
1262561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            message = new String(buff, 0, num, "UTF-8");
1263561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            log("client's data: '" + message + "'");
1264561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            // check the received data
1265561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            assertEquals(clientsData, message);
1266561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        }
1267561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // just send the response
1268561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        os
1269561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                .write(("HTTP/1.1 " + responseCode + "\n" + httpsResponseTail)
1270561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                        .getBytes("UTF-8"));
1271561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("Simple NON-Proxy work is DONE");
1272561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        continue;
1273561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
1274561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1275561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    // Do proxy work
1276561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (needProxyAuthentication) {
1277561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("Authentication required ...");
1278561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // send Authentication Request
1279561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        os.write(respAuthenticationRequired.getBytes("UTF-8"));
1280561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // read response
1281561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        num = is.read(buff);
1282561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        if (num == -1) {
1283561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            // this connection was closed,
1284561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            // do clean up and create new one:
1285561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            closeSocket(peerSocket);
1286561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            peerSocket = serverSocket.accept();
1287561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            peerSocket.setSoTimeout(TIMEOUT);
1288561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            log("New client connection ACCEPTED");
1289561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            is = peerSocket.getInputStream();
1290561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            os = peerSocket.getOutputStream();
1291561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            num = is.read(buff);
1292561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        }
1293561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        message = new String(buff, 0, num, "UTF-8");
1294561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("Got authenticated request:\n" + message);
1295561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("------------------");
1296561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // check provided authorization credentials
1297561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        assertTrue("Received message does not contain "
1298561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                + "authorization credentials",
1299561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                message.toLowerCase().indexOf(
1300561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                        "proxy-authorization:") > 0);
1301561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
1302561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1303561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (peerSocket instanceof SSLSocket) {
1304561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // it will be so if we are have second iteration
1305561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // over persistent connection
1306561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        os
1307561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                .write(("HTTP/1.1 " + OK_CODE + "\n" + httpsResponseTail)
1308561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                        .getBytes("UTF-8"));
1309561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("Sent OK RESPONSE over SSL");
1310561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    } else {
1311561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // The content of this response will reach proxied
1312561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // HTTPUC but will not reach proxied HTTPSUC
1313561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // In case of HTTP connection it will be the final
1314561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // message, in case of HTTPS connection this message
1315561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // will just indicate that connection with remote
1316561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // host has been done
1317561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // (i.e. SSL tunnel has been established).
1318561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        os.write(plainResponse.getBytes("UTF-8"));
1319561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("Sent OK RESPONSE");
1320561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
1321561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1322561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (message.startsWith("CONNECT")) { // request for SSL
13238d8858e39800de641b50f6e8e864af9cf68bedeaNarayan Kamath                        // tunnel
1324561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("Perform SSL Handshake...");
1325561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // create sslSocket acting as a remote server peer
1326561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        SSLSocket sslSocket = (SSLSocket) getContext()
1327561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                .getSocketFactory()
1328561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                .createSocket(peerSocket, "localhost",
1329561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                        peerSocket.getPort(), true); // do
13308d8858e39800de641b50f6e8e864af9cf68bedeaNarayan Kamath                        // autoclose
1331561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        sslSocket.setUseClientMode(false);
1332561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // demand client authentication
1333561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        sslSocket.setNeedClientAuth(true);
1334561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        sslSocket.startHandshake();
1335561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        peerSocket = sslSocket;
1336561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        is = peerSocket.getInputStream();
1337561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        os = peerSocket.getOutputStream();
1338561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1339561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // read the HTTP request sent by secure connection
1340561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // (HTTPS request)
1341561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        num = is.read(buff);
1342561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        message = new String(buff, 0, num, "UTF-8");
1343561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("[Remote Server] Request from SSL tunnel:\n"
1344561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                + message);
1345561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("------------------");
1346561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1347561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        if (message.startsWith("POST")) {
1348561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            // client connection sent some data
1349561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            log("[Remote Server] try to read client data");
1350561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            num = is.read(buff);
1351561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            message = new String(buff, 0, num, "UTF-8");
1352561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            log("[Remote Server] client's data: '" + message
1353561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                    + "'");
1354561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            // check the received data
1355561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            assertEquals(clientsData, message);
1356561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        }
1357561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1358561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("[Remote Server] Sending the response by SSL tunnel..");
1359561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // send the response with specified response code
1360561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        os
1361561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                .write(("HTTP/1.1 " + responseCode + "\n" + httpsResponseTail)
1362561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                        .getBytes("UTF-8"));
1363561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
1364561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    log("Work is DONE");
1365561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
1366561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                ;
1367561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } catch (Throwable e) {
1368561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (DO_LOG) {
1369561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    e.printStackTrace();
1370561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
1371561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                thrown = e;
1372561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } finally {
1373561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                closeSocket(peerSocket);
1374561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                try {
1375561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    serverSocket.close();
1376561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                } catch (IOException e) {
1377561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
1378561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1379561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1380561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
1381561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1382561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
1383561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * The class used for client side works. It could be used to test both
1384561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * HttpURLConnection and HttpsURLConnection.
1385561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
1386561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    static class ClientConnectionWork extends Work {
1387561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1388561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // connection to be used to contact the server side
1389561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        private HttpURLConnection connection;
1390561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1391561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1392561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * Creates the thread acting as a client side.
1393e98fbf8686c5289bf03fe5c3de7ff82d3a77104dElliott Hughes         *
13948d8858e39800de641b50f6e8e864af9cf68bedeaNarayan Kamath         * @param connection connection to be used to contact the server side
1395561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1396561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        public ClientConnectionWork(HttpURLConnection connection) {
1397561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            this.connection = connection;
1398561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            setName("Client Connection");
1399561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            log("Created over connection: " + connection.getClass());
1400561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1401561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1402561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1403561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * Performs the actual client work. If some exception occurs during the
1404561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * work it will be stored in the <code>thrown<code> field.
1405561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1406561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        public void run() {
1407561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            try {
1408561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                log("Opening the connection..");
1409561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                connection.connect();
1410561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                log("Connection has been ESTABLISHED, using proxy: "
1411561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        + connection.usingProxy());
1412561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (connection.getDoOutput()) {
1413561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    // connection configured to post data, do so
1414561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    connection.getOutputStream().write(clientsData.getBytes("UTF-8"));
1415561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
1416561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // read the content of HTTP(s) response
1417561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                InputStream is = connection.getInputStream();
1418561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                log("Input Stream obtained: " + is.getClass());
1419561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                byte[] buff = new byte[2048];
1420561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                int num = 0;
1421561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                int byt = 0;
1422561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                while ((num < buff.length) && (is.available() > 0)
1423561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        && ((byt = is.read()) != -1)) {
1424561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    buff[num++] = (byte) byt;
1425561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
1426561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                String message = new String(buff, 0, num, "UTF-8");
1427561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                log("Got content:\n" + message);
1428561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                log("------------------");
1429561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                log("Response code: " + connection.getResponseCode());
1430561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1431561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (connection instanceof HttpsURLConnection) {
1432561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    assertEquals(httpsResponseContent, message);
1433561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                } else {
1434561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    assertEquals(plainResponseContent, message);
1435561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
1436561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } catch (Throwable e) {
1437561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (DO_LOG) {
1438561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    e.printStackTrace();
1439561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
1440561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                thrown = e;
1441561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1442561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1443561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
1444561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1445561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public static junit.framework.Test suite() {
1446561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        return new TestSuite(HttpsURLConnectionTest.class);
1447561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
1448561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1449561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes}
1450