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
284561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        .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
329561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        .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
640561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            .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     *
825561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * @throws AssertionFailedError
826561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     *             if property was not set or file does not exist.
827561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
828561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static String getKeyStoreFileName() throws Exception {
829561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String ksFileName = "org/apache/harmony/luni/tests/key_store."
830561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + KeyStore.getDefaultType().toLowerCase();
831561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        URL url = ClassLoader.getSystemClassLoader().getResource(ksFileName);
832561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertNotNull("Expected KeyStore file: '" + ksFileName
833561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + "' for default KeyStore of type '"
834561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + KeyStore.getDefaultType() + "' does not exist.", url);
835561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        return new File(url.toURI()).getAbsolutePath();
836561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
837561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
838561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
839561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Builds and returns the context used for secure socket creation.
840561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
841561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static SSLContext getContext() throws Exception {
842561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String type = KeyStore.getDefaultType();
843561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLContext ctx;
844561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
845561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String keyStore = getKeyStoreFileName();
846561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        File keyStoreFile = new File(keyStore);
847561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
848561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        FileInputStream fis = new FileInputStream(keyStoreFile);
849561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
850561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        KeyStore ks = KeyStore.getInstance(type);
851561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ks.load(fis, KS_PASSWORD.toCharArray());
852561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
853561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
854561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .getDefaultAlgorithm());
855561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        kmf.init(ks, KS_PASSWORD.toCharArray());
856561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
857561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        TrustManagerFactory tmf = TrustManagerFactory
858561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .getInstance(TrustManagerFactory.getDefaultAlgorithm());
859561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        tmf.init(ks);
860561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
861561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ctx = SSLContext.getInstance("TLSv1");
862561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
863561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
864561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        return ctx;
865561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
866561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
867561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
868561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Sets up the properties pointing to the key store and trust store and used
869561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * as default values by JSSE staff. This is needed to test HTTPS behaviour
870561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * in the case of default SSL Socket Factories.
871561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
872561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static void setUpStoreProperties() throws Exception {
873561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String type = KeyStore.getDefaultType();
874561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
875561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        systemKeyStoreType = System.getProperty("javax.net.ssl.keyStoreType");
876561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        systemKeyStore = System.getProperty("javax.net.ssl.keyStore");
877561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        systemKeyStorePassword = System
878561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .getProperty("javax.net.ssl.keyStorePassword");
879561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
880561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        systemTrustStoreType = System
881561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .getProperty("javax.net.ssl.trustStoreType");
882561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        systemTrustStore = System.getProperty("javax.net.ssl.trustStore");
883561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        systemTrustStorePassword = System
884561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                .getProperty("javax.net.ssl.trustStorePassword");
885561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
886561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        System.setProperty("javax.net.ssl.keyStoreType", type);
887561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        System.setProperty("javax.net.ssl.keyStore", getKeyStoreFileName());
888561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        System.setProperty("javax.net.ssl.keyStorePassword", KS_PASSWORD);
889561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
890561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        System.setProperty("javax.net.ssl.trustStoreType", type);
891561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        System.setProperty("javax.net.ssl.trustStore", getKeyStoreFileName());
892561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        System.setProperty("javax.net.ssl.trustStorePassword", KS_PASSWORD);
893561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
894561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
895561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
896561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Rolls back the values of system properties.
897561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
898561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static void tearDownStoreProperties() {
899561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (systemKeyStoreType == null) {
900561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.clearProperty("javax.net.ssl.keyStoreType");
901561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } else {
902561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System
903561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .setProperty("javax.net.ssl.keyStoreType",
904561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            systemKeyStoreType);
905561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
906561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (systemKeyStore == null) {
907561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.clearProperty("javax.net.ssl.keyStore");
908561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } else {
909561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.setProperty("javax.net.ssl.keyStore", systemKeyStore);
910561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
911561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (systemKeyStorePassword == null) {
912561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.clearProperty("javax.net.ssl.keyStorePassword");
913561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } else {
914561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.setProperty("javax.net.ssl.keyStorePassword",
915561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    systemKeyStorePassword);
916561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
917561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
918561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (systemTrustStoreType == null) {
919561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.clearProperty("javax.net.ssl.trustStoreType");
920561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } else {
921561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.setProperty("javax.net.ssl.trustStoreType",
922561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    systemTrustStoreType);
923561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
924561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (systemTrustStore == null) {
925561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.clearProperty("javax.net.ssl.trustStore");
926561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } else {
927561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.setProperty("javax.net.ssl.trustStore", systemTrustStore);
928561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
929561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (systemTrustStorePassword == null) {
930561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.clearProperty("javax.net.ssl.trustStorePassword");
931561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } else {
932561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.setProperty("javax.net.ssl.trustStorePassword",
933561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    systemTrustStorePassword);
934561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
935561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
936561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
937561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
938561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Performs interaction between client's HttpURLConnection and servers side
939561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * (ServerSocket).
940561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
941561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public static Socket doInteraction(
942561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final HttpURLConnection clientConnection,
943561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final ServerSocket serverSocket) throws Throwable {
944561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        return doInteraction(clientConnection, serverSocket, OK_CODE, false,
945561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                false);
946561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
947561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
948561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
949561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Performs interaction between client's HttpURLConnection and servers side
950561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * (ServerSocket). Server will response with specified response code.
951561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
952561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public static Socket doInteraction(
953561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final HttpURLConnection clientConnection,
954561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final ServerSocket serverSocket, final int responseCode)
955561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            throws Throwable {
956561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        return doInteraction(clientConnection, serverSocket, responseCode,
957561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                false, false);
958561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
959561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
960561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
961561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Performs interaction between client's HttpURLConnection and servers side
962561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * (ServerSocket) over persistent connection.
963561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
964561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public static Socket doPersistentInteraction(
965561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final HttpURLConnection clientConnection,
966561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final ServerSocket serverSocket) throws Throwable {
967561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        return doInteraction(clientConnection, serverSocket, OK_CODE, false,
968561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                true);
969561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
970561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
971561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
972561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Performs interaction between client's HttpURLConnection and servers side
973561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * (ServerSocket) over persistent connection. Server will response with
974561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * specified response code.
975561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
976561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public static Socket doPersistentInteraction(
977561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final HttpURLConnection clientConnection,
978561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final ServerSocket serverSocket, final int responseCode)
979561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            throws Throwable {
980561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        return doInteraction(clientConnection, serverSocket, responseCode,
981561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                false, true);
982561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
983561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
984561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
985561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Performs interaction between client's HttpURLConnection and servers side
986561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * (ServerSocket). Server will response with specified response code.
987e98fbf8686c5289bf03fe5c3de7ff82d3a77104dElliott Hughes     *
988561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * @param doAuthentication
989561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     *            specifies if the server needs client authentication.
990561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
991561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public static Socket doInteraction(
992561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final HttpURLConnection clientConnection,
993561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final ServerSocket serverSocket, final int responseCode,
994561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            final boolean doAuthentication, final boolean checkPersistence)
995561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            throws Throwable {
996561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
997561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // set up the connection
998561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        clientConnection.setDoInput(true);
999561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        clientConnection.setConnectTimeout(TIMEOUT);
1000561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        clientConnection.setReadTimeout(TIMEOUT);
1001561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1002561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ServerWork server = new ServerWork(serverSocket, responseCode,
1003561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                doAuthentication, checkPersistence);
1004561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1005561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ClientConnectionWork client = new ClientConnectionWork(clientConnection);
1006561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1007561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        server.start();
1008561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        client.start();
1009561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1010561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        client.join();
1011561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (client.thrown != null) {
1012561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (responseCode != OK_CODE) { // not OK response expected
1013561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // it is probably expected exception, keep it as is
1014561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                throw client.thrown;
1015561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1016561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if ((client.thrown instanceof SocketTimeoutException)
1017561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    && (server.thrown != null)) {
1018561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // server's exception is more informative in this case
1019561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                throw new Exception(server.thrown);
1020561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } else {
1021561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                throw new Exception(client.thrown);
1022561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1023561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1024561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1025561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (checkPersistence) {
1026561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            ClientConnectionWork client2 = new ClientConnectionWork(
1027561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    (HttpURLConnection) clientConnection.getURL()
1028561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            .openConnection());
1029561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            client2.start();
1030561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            client2.join();
1031561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (client2.thrown != null) {
1032561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (responseCode != OK_CODE) { // not OK response expected
1033561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    // it is probably expected exception, keep it as is
1034561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    throw client2.thrown;
1035561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
1036561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if ((client2.thrown instanceof SocketTimeoutException)
1037561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        && (server.thrown != null)) {
1038561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    // server's exception is more informative in this case
1039561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    throw new Exception(server.thrown);
1040561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                } else {
1041561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    throw new Exception(client2.thrown);
1042561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
1043561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1044561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1045561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1046561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        server.join();
1047561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1048561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (server.thrown != null) {
1049561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            throw server.thrown;
1050561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1051561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        return server.peerSocket;
1052561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
1053561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1054561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
1055561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * The host name verifier used in test.
1056561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
1057561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    static class TestHostnameVerifier implements HostnameVerifier {
1058561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1059561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        boolean verified = false;
1060561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1061561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        public boolean verify(String hostname, SSLSession session) {
1062561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (DO_LOG) {
1063561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                System.out.println("***> verification " + hostname + " "
1064561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        + session.getPeerHost());
1065561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1066561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            verified = true;
1067561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            return true;
1068561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1069561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
1070561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1071561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
1072561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * The base class for mock Client and Server.
1073561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
1074561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    static class Work extends Thread {
1075561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1076561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1077561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The header of OK HTTP response.
1078561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1079561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        static String responseHead = "HTTP/1.1 200 OK\n";
1080561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1081561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1082561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The content of the response.
1083561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1084561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        static String plainResponseContent = "<HTML>\n"
1085561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + "<HEAD><TITLE>Plain Response Content</TITLE></HEAD>\n"
1086561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + "</HTML>";
1087561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1088561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1089561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The tail of the response.
1090561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1091561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        static String plainResponseTail = "Content-type: text/html\n"
1092561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + "Content-length: " + plainResponseContent.length() + "\n\n"
1093561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + plainResponseContent;
1094561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1095561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1096561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The response message to be sent in plain (HTTP) format.
1097561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1098561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        static String plainResponse = responseHead + plainResponseTail;
1099561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1100561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1101561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The content of the response to be sent during HTTPS session.
1102561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1103561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        static String httpsResponseContent = "<HTML>\n"
1104561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + "<HEAD><TITLE>HTTPS Response Content</TITLE></HEAD>\n"
1105561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + "</HTML>";
1106561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1107561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1108561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The tail of the response to be sent during HTTPS session.
1109561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1110561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        static String httpsResponseTail = "Content-type: text/html\n"
1111561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + "Content-length: " + httpsResponseContent.length() + "\n\n"
1112561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + httpsResponseContent;
1113561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1114561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1115561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The response requiring client's proxy authentication.
1116561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1117561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        static String respAuthenticationRequired = "HTTP/1.0 407 Proxy authentication required\n"
1118561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + "Proxy-authenticate: Basic realm=\"localhost\"\n\n";
1119561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1120561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1121561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The data to be posted by client to the server.
1122561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1123561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        static String clientsData = "_.-^ Client's Data ^-._";
1124561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1125561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1126561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The exception thrown during peers interaction.
1127561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1128561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        protected Throwable thrown;
1129561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1130561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1131561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * The print stream used for debug log. If it is null debug info will
1132561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * not be printed.
1133561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1134561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        private PrintStream out = new PrintStream(System.out);
1135561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1136561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1137561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * Prints log message.
1138561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1139561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        public synchronized void log(String message) {
1140561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (DO_LOG && (out != null)) {
1141561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                System.out.println("[" + getName() + "]: " + message);
1142561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1143561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1144561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
1145561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1146561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
1147561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * The class used for server side works.
1148561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
1149561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    static class ServerWork extends Work {
1150561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1151561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // the server socket used for connection
1152561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        private ServerSocket serverSocket;
1153561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1154561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // the socket connected with client peer
1155561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        private Socket peerSocket;
1156561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1157561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // indicates if the server acts as proxy server
1158561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        private boolean actAsProxy;
1159561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1160561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // indicates if the server needs proxy authentication
1161561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        private boolean needProxyAuthentication;
1162561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1163561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // do we check for connection persistence
1164561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        private boolean checkPersistence;
1165561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1166561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // response code to be send to the client peer
1167561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        private int responseCode;
1168561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1169561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1170561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * Creates the thread acting as a server side.
1171561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1172561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        public ServerWork(ServerSocket serverSocket) {
1173561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // the server does not require proxy authentication
1174561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // and sends OK_CODE (OK) response code
1175561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            this(serverSocket, OK_CODE, false, false);
1176561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1177561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1178561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1179561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * Creates the thread acting as a server side.
1180e98fbf8686c5289bf03fe5c3de7ff82d3a77104dElliott Hughes         *
1181561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * @param serverSocket
1182561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         *            the server socket to be used during connection
1183561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * @param responseCode
1184561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         *            the response code to be sent to the client
1185561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * @param needProxyAuthentication
1186561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         *            indicates if the server needs proxy authentication
1187561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1188561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        public ServerWork(ServerSocket serverSocket, int responseCode,
1189561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                boolean needProxyAuthentication, boolean checkPersistence) {
1190561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            this.serverSocket = serverSocket;
1191561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            this.responseCode = responseCode;
1192561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            this.needProxyAuthentication = needProxyAuthentication;
1193561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            this.checkPersistence = checkPersistence;
1194561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // will act as a proxy server if the specified server socket
1195561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // is not a secure server socket
1196561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (serverSocket instanceof SSLServerSocket) {
1197561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // demand client to send its certificate
1198561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                ((SSLServerSocket) serverSocket).setNeedClientAuth(true);
1199561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // work as a HTTPS server, not as HTTP proxy
1200561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                this.actAsProxy = false;
1201561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } else {
1202561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                this.actAsProxy = true;
1203561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1204561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            this.actAsProxy = !(serverSocket instanceof SSLServerSocket);
1205561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            setName(this.actAsProxy ? "Proxy Server" : "Server");
1206561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1207561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1208561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1209561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * Closes the connection.
1210561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1211561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        public void closeSocket(Socket socket) {
1212561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            try {
1213561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                socket.getInputStream().close();
1214561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } catch (IOException e) {
1215561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1216561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            try {
1217561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                socket.getOutputStream().close();
1218561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } catch (IOException e) {
1219561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1220561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            try {
1221561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                socket.close();
1222561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } catch (IOException e) {
1223561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1224561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1225561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1226561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1227561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * Performs the actual server work. If some exception occurs during the
1228561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * work it will be stored in the <code>thrown</code> field.
1229561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1230561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        public void run() {
1231561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // the buffer used for reading the messages
1232561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            byte[] buff = new byte[2048];
1233561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // the number of bytes read into the buffer
1234561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            int num;
1235561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            try {
1236561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // configure the server socket to avoid blocking
1237561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                serverSocket.setSoTimeout(TIMEOUT);
1238561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // accept client connection
1239561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                peerSocket = serverSocket.accept();
1240561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // configure the client connection to avoid blocking
1241561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                peerSocket.setSoTimeout(TIMEOUT);
1242561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                log("Client connection ACCEPTED");
1243561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1244561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                InputStream is = peerSocket.getInputStream();
1245561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                OutputStream os = peerSocket.getOutputStream();
1246561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1247561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // how many times established connection will be used
1248561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                int number_of_uses = checkPersistence ? 2 : 1;
1249561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                for (int it = 0; it < number_of_uses; it++) {
1250561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (checkPersistence) {
1251561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("==========================================");
1252561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("Use established connection for " + (it + 1)
1253561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                + " time");
1254561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
1255561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1256561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    num = is.read(buff);
1257561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    String message = new String(buff, 0, num, "UTF-8");
1258561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    log("Got request:\n" + message);
1259561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    log("------------------");
1260561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1261561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (!actAsProxy) {
1262561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // Act as Server (not Proxy) side
1263561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        if (message.startsWith("POST")) {
1264561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            // client connection sent some data
1265561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            log("try to read client data");
1266561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            num = is.read(buff);
1267561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            message = new String(buff, 0, num, "UTF-8");
1268561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            log("client's data: '" + message + "'");
1269561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            // check the received data
1270561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            assertEquals(clientsData, message);
1271561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        }
1272561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // just send the response
1273561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        os
1274561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                .write(("HTTP/1.1 " + responseCode + "\n" + httpsResponseTail)
1275561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                        .getBytes("UTF-8"));
1276561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("Simple NON-Proxy work is DONE");
1277561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        continue;
1278561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
1279561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1280561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    // Do proxy work
1281561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (needProxyAuthentication) {
1282561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("Authentication required ...");
1283561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // send Authentication Request
1284561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        os.write(respAuthenticationRequired.getBytes("UTF-8"));
1285561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // read response
1286561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        num = is.read(buff);
1287561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        if (num == -1) {
1288561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            // this connection was closed,
1289561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            // do clean up and create new one:
1290561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            closeSocket(peerSocket);
1291561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            peerSocket = serverSocket.accept();
1292561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            peerSocket.setSoTimeout(TIMEOUT);
1293561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            log("New client connection ACCEPTED");
1294561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            is = peerSocket.getInputStream();
1295561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            os = peerSocket.getOutputStream();
1296561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            num = is.read(buff);
1297561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        }
1298561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        message = new String(buff, 0, num, "UTF-8");
1299561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("Got authenticated request:\n" + message);
1300561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("------------------");
1301561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // check provided authorization credentials
1302561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        assertTrue("Received message does not contain "
1303561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                + "authorization credentials",
1304561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                message.toLowerCase().indexOf(
1305561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                        "proxy-authorization:") > 0);
1306561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
1307561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1308561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (peerSocket instanceof SSLSocket) {
1309561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // it will be so if we are have second iteration
1310561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // over persistent connection
1311561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        os
1312561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                .write(("HTTP/1.1 " + OK_CODE + "\n" + httpsResponseTail)
1313561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                        .getBytes("UTF-8"));
1314561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("Sent OK RESPONSE over SSL");
1315561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    } else {
1316561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // The content of this response will reach proxied
1317561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // HTTPUC but will not reach proxied HTTPSUC
1318561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // In case of HTTP connection it will be the final
1319561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // message, in case of HTTPS connection this message
1320561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // will just indicate that connection with remote
1321561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // host has been done
1322561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // (i.e. SSL tunnel has been established).
1323561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        os.write(plainResponse.getBytes("UTF-8"));
1324561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("Sent OK RESPONSE");
1325561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
1326561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1327561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (message.startsWith("CONNECT")) { // request for SSL
1328561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                                            // tunnel
1329561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("Perform SSL Handshake...");
1330561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // create sslSocket acting as a remote server peer
1331561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        SSLSocket sslSocket = (SSLSocket) getContext()
1332561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                .getSocketFactory()
1333561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                .createSocket(peerSocket, "localhost",
1334561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                        peerSocket.getPort(), true); // do
1335561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                                                        // autoclose
1336561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        sslSocket.setUseClientMode(false);
1337561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // demand client authentication
1338561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        sslSocket.setNeedClientAuth(true);
1339561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        sslSocket.startHandshake();
1340561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        peerSocket = sslSocket;
1341561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        is = peerSocket.getInputStream();
1342561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        os = peerSocket.getOutputStream();
1343561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1344561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // read the HTTP request sent by secure connection
1345561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // (HTTPS request)
1346561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        num = is.read(buff);
1347561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        message = new String(buff, 0, num, "UTF-8");
1348561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("[Remote Server] Request from SSL tunnel:\n"
1349561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                + message);
1350561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("------------------");
1351561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1352561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        if (message.startsWith("POST")) {
1353561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            // client connection sent some data
1354561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            log("[Remote Server] try to read client data");
1355561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            num = is.read(buff);
1356561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            message = new String(buff, 0, num, "UTF-8");
1357561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            log("[Remote Server] client's data: '" + message
1358561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                    + "'");
1359561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            // check the received data
1360561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            assertEquals(clientsData, message);
1361561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        }
1362561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1363561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        log("[Remote Server] Sending the response by SSL tunnel..");
1364561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // send the response with specified response code
1365561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        os
1366561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                .write(("HTTP/1.1 " + responseCode + "\n" + httpsResponseTail)
1367561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                        .getBytes("UTF-8"));
1368561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
1369561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    log("Work is DONE");
1370561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
1371561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                ;
1372561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } catch (Throwable e) {
1373561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (DO_LOG) {
1374561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    e.printStackTrace();
1375561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
1376561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                thrown = e;
1377561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } finally {
1378561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                closeSocket(peerSocket);
1379561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                try {
1380561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    serverSocket.close();
1381561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                } catch (IOException e) {
1382561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
1383561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1384561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1385561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
1386561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1387561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
1388561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * The class used for client side works. It could be used to test both
1389561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * HttpURLConnection and HttpsURLConnection.
1390561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
1391561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    static class ClientConnectionWork extends Work {
1392561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1393561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // connection to be used to contact the server side
1394561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        private HttpURLConnection connection;
1395561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1396561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1397561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * Creates the thread acting as a client side.
1398e98fbf8686c5289bf03fe5c3de7ff82d3a77104dElliott Hughes         *
1399561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * @param connection
1400561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         *            connection to be used to contact the server side
1401561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1402561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        public ClientConnectionWork(HttpURLConnection connection) {
1403561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            this.connection = connection;
1404561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            setName("Client Connection");
1405561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            log("Created over connection: " + connection.getClass());
1406561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1407561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1408561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        /**
1409561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * Performs the actual client work. If some exception occurs during the
1410561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         * work it will be stored in the <code>thrown<code> field.
1411561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes         */
1412561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        public void run() {
1413561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            try {
1414561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                log("Opening the connection..");
1415561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                connection.connect();
1416561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                log("Connection has been ESTABLISHED, using proxy: "
1417561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        + connection.usingProxy());
1418561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (connection.getDoOutput()) {
1419561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    // connection configured to post data, do so
1420561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    connection.getOutputStream().write(clientsData.getBytes("UTF-8"));
1421561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
1422561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // read the content of HTTP(s) response
1423561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                InputStream is = connection.getInputStream();
1424561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                log("Input Stream obtained: " + is.getClass());
1425561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                byte[] buff = new byte[2048];
1426561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                int num = 0;
1427561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                int byt = 0;
1428561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                while ((num < buff.length) && (is.available() > 0)
1429561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        && ((byt = is.read()) != -1)) {
1430561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    buff[num++] = (byte) byt;
1431561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
1432561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                String message = new String(buff, 0, num, "UTF-8");
1433561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                log("Got content:\n" + message);
1434561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                log("------------------");
1435561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                log("Response code: " + connection.getResponseCode());
1436561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1437561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (connection instanceof HttpsURLConnection) {
1438561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    assertEquals(httpsResponseContent, message);
1439561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                } else {
1440561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    assertEquals(plainResponseContent, message);
1441561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
1442561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } catch (Throwable e) {
1443561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (DO_LOG) {
1444561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    e.printStackTrace();
1445561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
1446561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                thrown = e;
1447561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1448561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1449561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
1450561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1451561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public static junit.framework.Test suite() {
1452561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        return new TestSuite(HttpsURLConnectionTest.class);
1453561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
1454561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1455561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes}
1456