You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by py...@apache.org on 2007/07/03 08:08:25 UTC
svn commit: r552679 [2/2] - in
/harmony/enhanced/classlib/trunk/modules/luni: ./
src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/
src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/
src/test/api/common/org/apache...
Modified: harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java?view=diff&rev=552679&r1=552678&r2=552679
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java Mon Jul 2 23:08:23 2007
@@ -161,6 +161,48 @@
}
/**
+ * Checks if HTTPS connection performs initial SSL handshake with the
+ * server working over SSL, sends encrypted HTTP request,
+ * and receives expected HTTP response. After that it checks that the
+ * established connection is persistent.
+ * After HTTPS session if finished
+ * test checks connection state parameters established by
+ * HttpsURLConnection.
+ */
+ public void testHttpsPersistentConnection() throws Throwable {
+ // set up the properties defining the default values needed by SSL stuff
+ setUpStoreProperties();
+
+ try {
+ // create the SSL server socket acting as a server
+ SSLContext ctx = getContext();
+ ServerSocket ss = ctx.getServerSocketFactory()
+ .createServerSocket(0);
+
+ // create the HostnameVerifier to check hostname verification
+ TestHostnameVerifier hnv = new TestHostnameVerifier();
+ HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+
+ // create url connection to be tested
+ URL url = new URL("https://localhost:" + ss.getLocalPort());
+ HttpsURLConnection connection = (HttpsURLConnection) url
+ .openConnection();
+
+ // perform the interaction between the peers
+ SSLSocket peerSocket = (SSLSocket) doPersistentInteraction(connection, ss);
+
+ // check the connection state
+ checkConnectionStateParameters(connection, peerSocket);
+
+ // should silently exit
+ connection.connect();
+ } finally {
+ // roll the properties back to system values
+ tearDownStoreProperties();
+ }
+ }
+
+ /**
* Tests the behaviour of HTTPS connection in case of unavailability
* of requested resource.
*/
@@ -408,6 +450,43 @@
}
/**
+ * Tests the behaviour in case of sending the data to the server
+ * over persistent connection.
+ */
+ public void testPersistence_doOutput() throws Throwable {
+ // setting up the properties pointing to the key/trust stores
+ setUpStoreProperties();
+
+ try {
+ // create the SSLServerSocket which will be used by server side
+ SSLServerSocket ss = (SSLServerSocket) getContext()
+ .getServerSocketFactory().createServerSocket(0);
+
+ // create the HostnameVerifier to check that Hostname verification
+ // is done
+ TestHostnameVerifier hnv = new TestHostnameVerifier();
+ HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+
+ // create HttpsURLConnection to be tested
+ URL url = new URL("https://localhost:" + ss.getLocalPort());
+ HttpsURLConnection connection = (HttpsURLConnection) url
+ .openConnection();
+ connection.setDoOutput(true);
+
+ // perform the interaction between the peers and check the results
+ SSLSocket peerSocket = (SSLSocket)
+ doPersistentInteraction(connection, ss);
+ checkConnectionStateParameters(connection, peerSocket);
+
+ // should silently exit
+ connection.connect();
+ } finally {
+ // roll the properties back to system values
+ tearDownStoreProperties();
+ }
+ }
+
+ /**
* Tests HTTPS connection process made through the proxy server.
*/
public void testProxyConnection() throws Throwable {
@@ -444,6 +523,43 @@
/**
* Tests HTTPS connection process made through the proxy server.
+ * Checks that persistent connection to the host exists and can
+ * be used no in spite of explicit Proxy specifying.
+ */
+ public void testPersistentProxyConnection() throws Throwable {
+ // setting up the properties pointing to the key/trust stores
+ setUpStoreProperties();
+
+ try {
+ // create the SSLServerSocket which will be used by server side
+ ServerSocket ss = new ServerSocket(0);
+
+ // create the HostnameVerifier to check that Hostname verification
+ // is done
+ TestHostnameVerifier hnv = new TestHostnameVerifier();
+ HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+
+ // create HttpsURLConnection to be tested
+ URL url = new URL("https://requested.host:55556/requested.data");
+ HttpsURLConnection connection = (HttpsURLConnection) url
+ .openConnection(new Proxy(Proxy.Type.HTTP,
+ new InetSocketAddress("localhost", ss
+ .getLocalPort())));
+
+ // perform the interaction between the peers and check the results
+ SSLSocket peerSocket = (SSLSocket) doPersistentInteraction(connection, ss);
+ checkConnectionStateParameters(connection, peerSocket);
+
+ // should silently exit
+ connection.connect();
+ } finally {
+ // roll the properties back to system values
+ tearDownStoreProperties();
+ }
+ }
+
+ /**
+ * Tests HTTPS connection process made through the proxy server.
* Proxy server needs authentication.
*/
public void testProxyAuthConnection() throws Throwable {
@@ -568,7 +684,7 @@
// perform the interaction between the peers and check the results
SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss,
- OK_CODE, true);
+ OK_CODE);
checkConnectionStateParameters(connection, peerSocket);
} finally {
// roll the properties back to system values
@@ -603,8 +719,7 @@
// perform the interaction between the peers and check the results
try {
- doInteraction(connection, ss, AUTHENTICATION_REQUIRED_CODE,
- true);
+ doInteraction(connection, ss, AUTHENTICATION_REQUIRED_CODE);
} catch (IOException e) {
// SSL Tunnelling failed
if (DO_LOG) {
@@ -704,10 +819,10 @@
}
/**
- * Returns the file name of the key/trust store. The key store file
+ * Returns the file name of the key/trust store. The key store file
* (named as "key_store." + extension equals to the default KeyStore
* type installed in the system in lower case) is searched in classpath.
- * @throws AssertionFailedError if property was not set
+ * @throws AssertionFailedError if property was not set
* or file does not exist.
*/
private static String getKeyStoreFileName() throws Exception {
@@ -826,7 +941,7 @@
public static Socket doInteraction(
final HttpURLConnection clientConnection,
final ServerSocket serverSocket) throws Throwable {
- return doInteraction(clientConnection, serverSocket, OK_CODE, false);
+ return doInteraction(clientConnection, serverSocket, OK_CODE, false, false);
}
/**
@@ -839,7 +954,31 @@
final ServerSocket serverSocket, final int responseCode)
throws Throwable {
return doInteraction(clientConnection, serverSocket, responseCode,
- false);
+ false, false);
+ }
+
+ /**
+ * Performs interaction between client's HttpURLConnection and
+ * servers side (ServerSocket) over persistent connection.
+ */
+ public static Socket doPersistentInteraction(
+ final HttpURLConnection clientConnection,
+ final ServerSocket serverSocket) throws Throwable {
+ return doInteraction(clientConnection, serverSocket, OK_CODE,
+ false, true);
+ }
+
+ /**
+ * Performs interaction between client's HttpURLConnection and
+ * servers side (ServerSocket) over persistent connection.
+ * Server will response with specified response code.
+ */
+ public static Socket doPersistentInteraction(
+ final HttpURLConnection clientConnection,
+ final ServerSocket serverSocket, final int responseCode)
+ throws Throwable {
+ return doInteraction(clientConnection, serverSocket, responseCode,
+ false, true);
}
/**
@@ -852,7 +991,8 @@
public static Socket doInteraction(
final HttpURLConnection clientConnection,
final ServerSocket serverSocket, final int responseCode,
- final boolean doAuthentication) throws Throwable {
+ final boolean doAuthentication,
+ final boolean checkPersistence) throws Throwable {
// set up the connection
clientConnection.setDoInput(true);
@@ -860,7 +1000,7 @@
clientConnection.setReadTimeout(TIMEOUT);
ServerWork server = new ServerWork(serverSocket, responseCode,
- doAuthentication);
+ doAuthentication, checkPersistence);
ClientConnectionWork client = new ClientConnectionWork(clientConnection);
@@ -868,8 +1008,6 @@
client.start();
client.join();
- server.join();
-
if (client.thrown != null) {
if (responseCode != OK_CODE) { // not OK response expected
// it is probably expected exception, keep it as is
@@ -883,6 +1021,30 @@
throw new Exception(client.thrown);
}
}
+
+ if (checkPersistence) {
+ ClientConnectionWork client2 =
+ new ClientConnectionWork((HttpURLConnection)
+ clientConnection.getURL().openConnection());
+ client2.start();
+ client2.join();
+ if (client2.thrown != null) {
+ if (responseCode != OK_CODE) { // not OK response expected
+ // it is probably expected exception, keep it as is
+ throw client2.thrown;
+ }
+ if ((client2.thrown instanceof SocketTimeoutException)
+ && (server.thrown != null)) {
+ // server's exception is more informative in this case
+ throw new Exception(server.thrown);
+ } else {
+ throw new Exception(client2.thrown);
+ }
+ }
+ }
+
+ server.join();
+
if (server.thrown != null) {
throw server.thrown;
}
@@ -998,6 +1160,9 @@
// indicates if the server needs proxy authentication
private boolean needProxyAuthentication;
+ // do we check for connection persistence
+ private boolean checkPersistence;
+
// response code to be send to the client peer
private int responseCode;
@@ -1007,7 +1172,7 @@
public ServerWork(ServerSocket serverSocket) {
// the server does not require proxy authentication
// and sends OK_CODE (OK) response code
- this(serverSocket, OK_CODE, false);
+ this(serverSocket, OK_CODE, false, false);
}
/**
@@ -1018,10 +1183,11 @@
* indicates if the server needs proxy authentication
*/
public ServerWork(ServerSocket serverSocket, int responseCode,
- boolean needProxyAuthentication) {
+ boolean needProxyAuthentication, boolean checkPersistence) {
this.serverSocket = serverSocket;
this.responseCode = responseCode;
this.needProxyAuthentication = needProxyAuthentication;
+ this.checkPersistence = checkPersistence;
// will act as a proxy server if the specified server socket
// is not a secure server socket
if (serverSocket instanceof SSLServerSocket) {
@@ -1073,105 +1239,120 @@
InputStream is = peerSocket.getInputStream();
OutputStream os = peerSocket.getOutputStream();
- num = is.read(buff);
- String message = new String(buff, 0, num);
- log("Got request:\n" + message);
- log("------------------");
-
- if (!actAsProxy) {
- // Act as Server (not Proxy) side
- if (message.startsWith("POST")) {
- // client connection sent some data
- log("try to read client data");
- num = is.read(buff);
- message = new String(buff, 0, num);
- log("client's data: '" + message + "'");
- // check the received data
- assertEquals(clientsData, message);
+ // how many times established connection will be used
+ int number_of_uses = checkPersistence ? 2 : 1;
+ for (int it=0; it<number_of_uses; it++) {
+ if (checkPersistence) {
+ log("==========================================");
+ log("Use established connection for "+(it+1)+" time");
}
- // just send the response
- os
- .write(("HTTP/1.1 " + responseCode + "\n" + httpsResponseTail)
- .getBytes());
- // and return
- log("Work is DONE");
- return;
- }
- // Do proxy work
- if (needProxyAuthentication) {
- log("Authentication required ...");
- // send Authentication Request
- os.write(respAuthenticationRequired.getBytes());
- // read response
num = is.read(buff);
- if (num == -1) {
- // this connection was closed,
- // do clean up and create new one:
- closeSocket(peerSocket);
- peerSocket = serverSocket.accept();
- peerSocket.setSoTimeout(TIMEOUT);
- log("New client connection ACCEPTED");
- is = peerSocket.getInputStream();
- os = peerSocket.getOutputStream();
+ String message = new String(buff, 0, num);
+ log("Got request:\n" + message);
+ log("------------------");
+
+ if (!actAsProxy) {
+ // Act as Server (not Proxy) side
+ if (message.startsWith("POST")) {
+ // client connection sent some data
+ log("try to read client data");
+ num = is.read(buff);
+ message = new String(buff, 0, num);
+ log("client's data: '" + message + "'");
+ // check the received data
+ assertEquals(clientsData, message);
+ }
+ // just send the response
+ os.write(("HTTP/1.1 " + responseCode + "\n"
+ + httpsResponseTail).getBytes());
+ log("Simple NON-Proxy work is DONE");
+ continue;
+ }
+
+ // Do proxy work
+ if (needProxyAuthentication) {
+ log("Authentication required ...");
+ // send Authentication Request
+ os.write(respAuthenticationRequired.getBytes());
+ // read response
num = is.read(buff);
+ if (num == -1) {
+ // this connection was closed,
+ // do clean up and create new one:
+ closeSocket(peerSocket);
+ peerSocket = serverSocket.accept();
+ peerSocket.setSoTimeout(TIMEOUT);
+ log("New client connection ACCEPTED");
+ is = peerSocket.getInputStream();
+ os = peerSocket.getOutputStream();
+ num = is.read(buff);
+ }
+ message = new String(buff, 0, num);
+ log("Got authenticated request:\n" + message);
+ log("------------------");
+ // check provided authorization credentials
+ assertTrue("Received message does not contain "
+ + "authorization credentials", message
+ .toLowerCase().indexOf("proxy-authorization:") > 0);
}
- message = new String(buff, 0, num);
- log("Got authenticated request:\n" + message);
- log("------------------");
- // check provided authorization credentials
- assertTrue("Received message does not contain "
- + "authorization credentials", message
- .toLowerCase().indexOf("proxy-authorization:") > 0);
- }
- // The content of this response will reach proxied HTTPUC
- // but will not reach proxied HTTPSUC
- // In case of HTTP connection it will be the final message,
- // in case of HTTPS connection this message will just indicate
- // that connection with remote host has been done
- // (i.e. SSL tunnel has been established).
- os.write(plainResponse.getBytes());
- log("Sent OK RESPONSE");
-
- if (message.startsWith("CONNECT")) { // request for SSL tunnel
- log("Perform SSL Handshake...");
- // create sslSocket acting as a remote server peer
- SSLSocket sslSocket = (SSLSocket) getContext()
- .getSocketFactory().createSocket(peerSocket,
- "localhost", peerSocket.getPort(), true); // do autoclose
- sslSocket.setUseClientMode(false);
- // demand client authentication
- sslSocket.setNeedClientAuth(true);
- sslSocket.startHandshake();
- peerSocket = sslSocket;
- is = peerSocket.getInputStream();
- os = peerSocket.getOutputStream();
+ if (peerSocket instanceof SSLSocket) {
+ // it will be so if we are have second iteration
+ // over persistent connection
+ os.write(("HTTP/1.1 " + OK_CODE
+ + "\n" + httpsResponseTail).getBytes());
+ log("Sent OK RESPONSE over SSL");
+ } else {
+ // The content of this response will reach proxied
+ // HTTPUC but will not reach proxied HTTPSUC
+ // In case of HTTP connection it will be the final
+ // message, in case of HTTPS connection this message
+ // will just indicate that connection with remote
+ // host has been done
+ // (i.e. SSL tunnel has been established).
+ os.write(plainResponse.getBytes());
+ log("Sent OK RESPONSE");
+ }
- // read the HTTP request sent by secure connection
- // (HTTPS request)
- num = is.read(buff);
- message = new String(buff, 0, num);
- log("[Remote Server] Request from SSL tunnel:\n" + message);
- log("------------------");
+ if (message.startsWith("CONNECT")) { // request for SSL tunnel
+ log("Perform SSL Handshake...");
+ // create sslSocket acting as a remote server peer
+ SSLSocket sslSocket = (SSLSocket) getContext()
+ .getSocketFactory().createSocket(peerSocket,
+ "localhost", peerSocket.getPort(), true); // do autoclose
+ sslSocket.setUseClientMode(false);
+ // demand client authentication
+ sslSocket.setNeedClientAuth(true);
+ sslSocket.startHandshake();
+ peerSocket = sslSocket;
+ is = peerSocket.getInputStream();
+ os = peerSocket.getOutputStream();
- if (message.startsWith("POST")) {
- // client connection sent some data
- log("[Remote Server] try to read client data");
+ // read the HTTP request sent by secure connection
+ // (HTTPS request)
num = is.read(buff);
message = new String(buff, 0, num);
- log("[Remote Server] client's data: '" + message + "'");
- // check the received data
- assertEquals(clientsData, message);
- }
+ log("[Remote Server] Request from SSL tunnel:\n" + message);
+ log("------------------");
- log("[Remote Server] Sending the response by SSL tunnel..");
- // send the response with specified response code
- os
- .write(("HTTP/1.1 " + responseCode + "\n" + httpsResponseTail)
- .getBytes());
- }
- log("Work is DONE");
+ if (message.startsWith("POST")) {
+ // client connection sent some data
+ log("[Remote Server] try to read client data");
+ num = is.read(buff);
+ message = new String(buff, 0, num);
+ log("[Remote Server] client's data: '" + message + "'");
+ // check the received data
+ assertEquals(clientsData, message);
+ }
+
+ log("[Remote Server] Sending the response by SSL tunnel..");
+ // send the response with specified response code
+ os.write(("HTTP/1.1 " + responseCode
+ + "\n" + httpsResponseTail).getBytes());
+ }
+ log("Work is DONE");
+ };
} catch (Throwable e) {
if (DO_LOG) {
e.printStackTrace();
@@ -1222,7 +1403,7 @@
}
// read the content of HTTP(s) response
InputStream is = connection.getInputStream();
- log("Input Stream obtained");
+ log("Input Stream obtained: "+is.getClass());
byte[] buff = new byte[2048];
int num = 0;
int byt = 0;
Added: harmony/enhanced/classlib/trunk/modules/luni/src/test/impl/org/apache/harmony/tests/internal/net/www/protocol/http/PersistenceTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/test/impl/org/apache/harmony/tests/internal/net/www/protocol/http/PersistenceTest.java?view=auto&rev=552679
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/test/impl/org/apache/harmony/tests/internal/net/www/protocol/http/PersistenceTest.java (added)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/test/impl/org/apache/harmony/tests/internal/net/www/protocol/http/PersistenceTest.java Mon Jul 2 23:08:23 2007
@@ -0,0 +1,549 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.internal.net.www.protocol.http;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.net.HttpURLConnection;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection;
+import org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnectionManager;
+
+import tests.support.Support_HttpServer;
+import tests.support.Support_HttpServerSocket;
+import tests.support.Support_Jetty;
+import tests.support.Support_PortManager;
+import tests.support.Support_URLConnector;
+
+/**
+ * Tests for <code>HttpURLConnection</code> persistence.
+ * These tests depends on internal implementation.
+ */
+public class PersistenceTest extends TestCase {
+
+ private static final boolean DEBUG = false;
+
+ private final static Object bound = new Object();
+
+ private static int port;
+
+ static {
+ // run-once set up
+ try {
+ port = Support_Jetty.startDefaultHttpServer();
+ } catch (Exception e) {
+ fail("Exception during setup jetty : " + e.getMessage());
+ }
+ }
+
+ static class MockServer extends Thread {
+ ServerSocket serverSocket;
+ boolean accepted = false;
+ boolean started = false;
+
+ public MockServer(String name) throws IOException {
+ super(name);
+ serverSocket = new ServerSocket(0);
+ serverSocket.setSoTimeout(5000);
+ }
+
+ public int port() {
+ return serverSocket.getLocalPort();
+ }
+
+ @Override
+ public void run() {
+ try {
+ synchronized (bound) {
+ started = true;
+ bound.notify();
+ }
+ try {
+ serverSocket.accept().close();
+ accepted = true;
+ } catch (SocketTimeoutException ignore) {
+ }
+ serverSocket.close();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ static class MockHTTPServer extends MockServer {
+ // HTTP response codes
+ static final int OK_CODE = 200;
+ static final int NOT_FOUND_CODE = 404;
+ // how many times persistent connection will be used
+ // by server
+ int persUses;
+ // result code to be sent to client
+ int responseCode;
+ // response content to be sent to client
+ String response = "<html></html>";
+ // client's POST message
+ String clientPost = "Hello from client!";
+
+ public MockHTTPServer(String name, int persUses) throws IOException {
+ this(name, persUses, OK_CODE);
+ }
+
+ public MockHTTPServer(String name, int persUses,
+ int responseCode) throws IOException {
+ super(name);
+ this.persUses = persUses;
+ this.responseCode = responseCode;
+ }
+
+ public int port() {
+ return serverSocket.getLocalPort();
+ }
+
+ @Override
+ public void run() {
+ try {
+ synchronized (bound) {
+ started = true;
+ bound.notify();
+ }
+ InputStream is = null;
+ Socket client = null;
+ try {
+ client = serverSocket.accept();
+ accepted = true;
+ for (int i=0; i<persUses; i++) {
+ if (DEBUG) {
+ System.out.println("*** Using connection for "
+ + (i+1) + " time ***");
+ }
+ byte[] buff = new byte[1024];
+ is = client.getInputStream();
+ int num = 0; // number of read bytes
+ int bytik; // read byte value
+ boolean wasEOL = false;
+ // read header (until empty string)
+ while (((bytik = is.read()) > 0)) {
+ if (bytik == '\r') {
+ bytik = is.read();
+ }
+ if (wasEOL && (bytik == '\n')) {
+ break;
+ }
+ wasEOL = (bytik == '\n');
+ buff[num++] = (byte) bytik;
+ }
+ //int num = is.read(buff);
+ String message = new String(buff, 0, num);
+ if (DEBUG) {
+ System.out.println("---- Server got request: ----\n"
+ + message + "-----------------------------");
+ }
+
+ // Act as Server (not Proxy) side
+ if (message.startsWith("POST")) {
+ // client connection sent some data
+ // if the data was not read with header
+ if (DEBUG) {
+ System.out.println(
+ "---- Server read client's data: ----");
+ }
+ num = is.read(buff);
+ message = new String(buff, 0, num);
+ if (DEBUG) {
+ System.out.println("'" + message + "'");
+ System.out.println(
+ "------------------------------------");
+ }
+ // check the received data
+ assertEquals(clientPost, message);
+ }
+
+ client.getOutputStream().write((
+ "HTTP/1.1 " + responseCode + " OK\n"
+ + "Content-type: text/html\n"
+ + "Content-length: "
+ + response.length() + "\n\n"
+ + response).getBytes());
+
+ if (responseCode != OK_CODE) {
+ // wait while test case check closed connection
+ // and interrupt this thread
+ try {
+ while (!isInterrupted()) {
+ Thread.sleep(1000);
+ }
+ } catch (Exception ignore) { }
+ }
+ }
+ } catch (SocketTimeoutException ignore) {
+ ignore.printStackTrace();
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ if (client != null) {
+ client.close();
+ }
+ serverSocket.close();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public void setUp() {
+ if (DEBUG) {
+ System.out.println("\n==============================");
+ System.out.println("===== Execution: "+getName());
+ System.out.println("==============================");
+ }
+ }
+
+ /**
+ * Test that an HTTP connection persists
+ */
+ public void testConnectionsPersist() throws IOException, InterruptedException {
+ int initialFreeConnections = HttpConnectionManager.getDefault().numFreeConnections();
+ MockServer httpServer =
+ new MockServer("ServerSocket for HttpURLConnectionTest");
+ httpServer.start();
+ synchronized(bound) {
+ if (!httpServer.started) {
+ bound.wait(5000);
+ }
+ }
+ HttpURLConnection c = (HttpURLConnection)
+ new URL("http://127.0.0.1:" + httpServer.port()).openConnection();
+ c.setDoOutput(true);
+ c.setRequestMethod("POST");
+ c.getOutputStream().close();
+ assertEquals(initialFreeConnections + 1, HttpConnectionManager.getDefault().numFreeConnections());
+ c = (HttpURLConnection)
+ new URL("http://127.0.0.1:" + httpServer.port()).openConnection();
+ c.setDoOutput(true);
+ c.setRequestMethod("POST");
+ OutputStream os = c.getOutputStream();
+ assertEquals(initialFreeConnections, HttpConnectionManager.getDefault().numFreeConnections());
+ os.close();
+ assertEquals(initialFreeConnections + 1, HttpConnectionManager.getDefault().numFreeConnections());
+ httpServer.join();
+ }
+
+ /**
+ * Test that multiple HTTP connections persist
+ */
+ public void testMultipleConnectionsPersist() throws IOException, InterruptedException {
+ int initialFreeConnections = HttpConnectionManager.getDefault().numFreeConnections();
+ MockServer httpServer =
+ new MockServer("ServerSocket for HttpURLConnectionTest");
+ httpServer.start();
+ synchronized(bound) {
+ if (!httpServer.started) {
+ bound.wait(5000);
+ }
+ }
+ MockServer httpServer2 =
+ new MockServer("ServerSocket for HttpURLConnectionTest");
+ httpServer2.start();
+ synchronized(bound) {
+ if (!httpServer2.started) {
+ bound.wait(5000);
+ }
+ }
+ HttpURLConnection c = (HttpURLConnection)
+ new URL("http://127.0.0.1:" + httpServer.port()).openConnection();
+ c.setDoOutput(true);
+ c.setRequestMethod("POST");
+ OutputStream os = c.getOutputStream();
+ HttpURLConnection c2 = (HttpURLConnection)
+ new URL("http://127.0.0.1:" + httpServer2.port()).openConnection();
+ c2.setDoOutput(true);
+ c2.setRequestMethod("POST");
+ OutputStream os2 = c2.getOutputStream();
+ os.close();
+ os2.close();
+ assertEquals(initialFreeConnections + 2, HttpConnectionManager.getDefault().numFreeConnections());
+
+ c = (HttpURLConnection)
+ new URL("http://127.0.0.1:" + httpServer.port()).openConnection();
+ c.setDoOutput(true);
+ c.setRequestMethod("POST");
+ os = c.getOutputStream();
+ assertEquals(initialFreeConnections + 1, HttpConnectionManager.getDefault().numFreeConnections());
+ c2 = (HttpURLConnection)
+ new URL("http://127.0.0.1:" + httpServer2.port()).openConnection();
+ c2.setDoOutput(true);
+ c2.setRequestMethod("POST");
+ os2 = c2.getOutputStream();
+ assertEquals(initialFreeConnections, HttpConnectionManager.getDefault().numFreeConnections());
+ os.close();
+ os2.close();
+ assertEquals(initialFreeConnections + 2, HttpConnectionManager.getDefault().numFreeConnections());
+ httpServer.join();
+ httpServer2.join();
+ }
+
+ /**
+ * Test that a closed HTTP connection is not kept in the pool of live connections
+ * @throws URISyntaxException
+ */
+ public void testForcedClosure() throws Exception {
+ int initialFreeConnections = HttpConnectionManager.getDefault().numFreeConnections();
+ MockServer httpServer =
+ new MockServer("ServerSocket for HttpURLConnectionTest");
+ httpServer.start();
+ synchronized(bound) {
+ if (!httpServer.started) {
+ bound.wait(5000);
+ }
+ }
+ HttpConnection connection = HttpConnectionManager.getDefault().getConnection(new URI("http://127.0.0.1:" + httpServer.port()), 1000);
+ HttpConnectionManager.getDefault().returnConnectionToPool(connection);
+ assertEquals(initialFreeConnections + 1, HttpConnectionManager.getDefault().numFreeConnections());
+ HttpURLConnection c = (HttpURLConnection)
+ new URL("http://127.0.0.1:" + httpServer.port()).openConnection();
+ c.setDoOutput(true);
+ c.setRequestMethod("POST");
+ c.getOutputStream();
+ assertEquals(initialFreeConnections, HttpConnectionManager.getDefault().numFreeConnections());
+ c.disconnect();
+ assertEquals(initialFreeConnections, HttpConnectionManager.getDefault().numFreeConnections());
+ }
+
+ /**
+ * Test that a connection is closed if the client does not read all the data
+ * @throws Exception
+ */
+ public void testIncorrectUsage() throws Exception {
+ int initialFreeConnections = HttpConnectionManager.getDefault().numFreeConnections();
+ HttpURLConnection c = (HttpURLConnection)
+ new URL("http://localhost:" + port).openConnection();
+ c.setDoOutput(true);
+ c.setRequestMethod("GET");
+ InputStream is = c.getInputStream(); // get the input stream but don't finish reading it
+ is.close();
+ assertEquals(initialFreeConnections, HttpConnectionManager.getDefault().numFreeConnections());
+ }
+
+ /**
+ * Test that a connection is closed in case of unsuccessful connection.
+ * Here client gets NOT_FOUND response.
+ */
+ public void testConnectionNonPersistence() throws Exception {
+ MockHTTPServer httpServer =
+ new MockHTTPServer("HTTP Server for NOT FOUND checking", 1,
+ MockHTTPServer.NOT_FOUND_CODE);
+ httpServer.start();
+ synchronized(bound) {
+ if (!httpServer.started) {
+ bound.wait(5000);
+ }
+ }
+
+ int initialFreeConnections
+ = HttpConnectionManager.getDefault().numFreeConnections();
+
+ HttpURLConnection c = (HttpURLConnection)
+ new URL("http://localhost:"+httpServer.port()).openConnection();
+ if (DEBUG) {
+ System.out.println("Actual connection class: "+c.getClass());
+ }
+
+ c.setDoInput(true);
+ c.setConnectTimeout(5000);
+ c.setReadTimeout(5000);
+ try {
+ c.getInputStream();
+ fail("Expected IOException was not thrown");
+ } catch (IOException expected) {
+ // expected
+ } finally {
+ httpServer.interrupt();
+ }
+ assertEquals("Unsuccessful connection was not closed",
+ initialFreeConnections,
+ HttpConnectionManager.getDefault().numFreeConnections());
+ }
+
+ /**
+ * Test that a connection is not closed if the client does read all the data
+ * @throws Exception
+ */
+ public void testCorrectUsage() throws Exception {
+ int initialFreeConnections = HttpConnectionManager.getDefault().numFreeConnections();
+ HttpURLConnection c = (HttpURLConnection)
+ new URL("http://localhost:" + port).openConnection();
+ c.setDoOutput(true);
+ c.setRequestMethod("GET");
+ InputStream is = c.getInputStream();
+ byte[] buffer = new byte[128];
+ int totalBytes = 0;
+ int bytesRead = 0;
+ while((bytesRead = is.read(buffer)) > 0){
+ totalBytes += bytesRead;
+ }
+ is.close();
+ assertEquals(initialFreeConnections + 1, HttpConnectionManager.getDefault().numFreeConnections());
+
+ HttpURLConnection c2 = (HttpURLConnection)
+ new URL("http://localhost:" + port).openConnection();
+ c2.setDoOutput(true);
+ c2.setRequestMethod("GET");
+ InputStream is2 = c2.getInputStream();
+ byte[] buffer2 = new byte[128];
+ int totalBytes2 = 0;
+ int bytesRead2 = 0;
+ while((bytesRead2 = is2.read(buffer2)) > 0){
+ totalBytes2 += bytesRead2;
+ }
+ is2.close();
+ assertEquals(initialFreeConnections + 1, HttpConnectionManager.getDefault().numFreeConnections());
+ assertEquals(totalBytes, totalBytes2);
+ }
+
+ /**
+ * Test that the http.keepAlive system property has the required effect on persistent connections
+ */
+ public void testKeepAliveSystemProperty() throws IOException, InterruptedException {
+ System.setProperty("http.keepAlive", "false");
+ MockServer httpServer =
+ new MockServer("ServerSocket for HttpURLConnectionTest");
+ httpServer.start();
+ synchronized(bound) {
+ if (!httpServer.started) {
+ bound.wait(5000);
+ }
+ }
+ HttpURLConnection c = (HttpURLConnection)
+ new URL("http://127.0.0.1:" + httpServer.port()).openConnection();
+ c.setDoOutput(true);
+ c.setRequestMethod("POST");
+ OutputStream os = c.getOutputStream();
+ os.close();
+ assertEquals(0, HttpConnectionManager.getDefault().numFreeConnections());
+ httpServer.join();
+ System.setProperty("http.keepAlive", "true");
+ }
+
+ /**
+ * Test that the http.maxConnections system property has the required effect on persistent connections
+ * @throws Exception
+ */
+ public void testMaxConnectionsSystemProperty() throws Exception {
+ int initialFreeConnections = HttpConnectionManager.getDefault().numFreeConnections();
+ System.setProperty("http.maxConnections", "2");
+ HttpURLConnection c = (HttpURLConnection)
+ new URL("http://localhost:" + port).openConnection();
+ c.setDoOutput(true);
+ c.setRequestMethod("GET");
+ InputStream is = c.getInputStream();
+ c = (HttpURLConnection)
+ new URL("http://localhost:" + port).openConnection();
+ c.setDoOutput(true);
+ c.setRequestMethod("GET");
+ InputStream is2 = c.getInputStream();
+ c = (HttpURLConnection)
+ new URL("http://localhost:" + port).openConnection();
+ c.setDoOutput(true);
+ c.setRequestMethod("GET");
+ InputStream is3 = c.getInputStream();
+ byte[] buffer = new byte[128];
+ while(is.read(buffer) > 0){
+ }
+ while(is2.read(buffer) > 0){
+ }
+ while(is3.read(buffer) > 0){
+ }
+ is.close();
+ is2.close();
+ is3.close();
+ assertEquals(initialFreeConnections + 2, HttpConnectionManager.getDefault().numFreeConnections());
+ }
+
+ public void testClosingOutputStream() throws IOException {
+// create a serversocket
+ Support_HttpServerSocket serversocket = new Support_HttpServerSocket();
+ int portNumber = Support_PortManager.getNextPort();
+ // create a client connector
+ Support_URLConnector connector = new Support_URLConnector();
+ Support_HttpServer server = new Support_HttpServer(serversocket, this);
+
+ server.startServer(portNumber);
+
+
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ InputStream is;
+ int c;
+ final String postTestUrl = "http://localhost:" + portNumber
+ + Support_HttpServer.POSTTEST;
+
+ String toWrite = "abcdef";
+ connector.open(postTestUrl);
+ OutputStream out = connector.getOutputStream();
+ System.out.println("Output stream = " + out.hashCode());
+ out.write(toWrite.getBytes("ISO8859_1"));
+ out.close();
+ is = connector.getInputStream();
+ bout.reset();
+ do {
+ c = is.read();
+ if (c != -1) {
+ bout.write(c);
+ }
+ } while (c != -1);
+ is.close();
+ connector.close();
+ String result = new String(bout.toByteArray(), "ISO8859_1");
+ assertTrue("Error sending data 1: " + result, toWrite
+ .equals(result));
+
+ toWrite = "zyxwvuts";
+ connector.open(postTestUrl);
+ connector.setRequestProperty("Transfer-encoding", "chunked");
+ out = connector.getOutputStream();
+ System.out.println("Output stream = " + out.hashCode());
+ out.write(toWrite.getBytes("ISO8859_1"));
+ out.close();
+ is = connector.getInputStream();
+ bout.reset();
+ do {
+ c = is.read();
+ if (c != -1) {
+ bout.write(c);
+ }
+ } while (c != -1);
+ is.close();
+ connector.close();
+ result = new String(bout.toByteArray(), "ISO8859_1");
+ assertEquals(toWrite, result);
+
+ }
+
+}
\ No newline at end of file