From ac277be6a146ade8f150236edf730431a7e12482 Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Fri, 17 Sep 2010 16:26:57 -0700 Subject: [PATCH] Handle the different definitions of 'connected' in HttpURLConnection. Previously we were failing with a NullPointerException when HTTP redirects required connecting to a different server. The connected field means 'we can't change request parameters'. The connection being non-null means 'we're currently connected'. Internally, multiple connections are permitted in order to support HTTP redirects. But in the public API only one connect() call is permitted. I've added a new method, makeConnection() to make the magic work. Change-Id: Ic644d5d192ec2b1de781dc271ae149bcd1655de4 --- luni/src/main/java/java/net/URLConnection.java | 7 ++++--- .../www/protocol/http/HttpURLConnectionImpl.java | 21 +++++++++++++++++---- .../www/protocol/https/HttpsURLConnectionImpl.java | 22 ++++++++++++---------- 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/luni/src/main/java/java/net/URLConnection.java b/luni/src/main/java/java/net/URLConnection.java index 91dfd67a..e467932a 100644 --- a/luni/src/main/java/java/net/URLConnection.java +++ b/luni/src/main/java/java/net/URLConnection.java @@ -47,7 +47,8 @@ import org.apache.harmony.luni.util.PriviAction; * } * *

{@code URLConnection} must be configured before it has connected to the - * remote resource. + * remote resource. Instances of {@code URLConnection} are not reusable: you + * must use a different instance for each connection to a resource. * *

Timeouts

* {@code URLConnection} supports two timeouts: a {@link #setConnectTimeout @@ -160,8 +161,8 @@ public abstract class URLConnection { } /** - * Establishes the connection to the earlier configured resource. The - * connection can only be set up before this method has been called. + * Opens a connection to the resource. This method will not + * reconnect to a resource after the initial connection has been closed. * * @throws IOException * if an error occurs while connecting to the resource. diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnectionImpl.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnectionImpl.java index f9f46ad8..dffe6e65 100644 --- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnectionImpl.java +++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnectionImpl.java @@ -198,15 +198,28 @@ public class HttpURLConnectionImpl extends HttpURLConnection { this.proxy = proxy; } - /** - * Establishes a socket connection to the remote origin server or proxy. - */ @Override public void connect() throws IOException { if (connected) { return; } + makeConnection(); + } + + /** + * Internal method to open a connection to the server. Unlike connect(), + * this method may be called multiple times for a single response. This may + * be necessary when following redirects. + * + *

Request parameters may not be changed after this method has been + * called. + */ + public void makeConnection() throws IOException { connected = true; + if (connection != null) { + return; + } + if (getFromCache()) { return; } @@ -1002,7 +1015,7 @@ public class HttpURLConnectionImpl extends HttpURLConnection { redirectionCount = 0; while (true) { - connect(); + makeConnection(); // if we can get a response from the cache, we're done if (cacheResponse != null) { diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/HttpsURLConnectionImpl.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/HttpsURLConnectionImpl.java index e740a0c2..c7210f5b 100644 --- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/HttpsURLConnectionImpl.java +++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/HttpsURLConnectionImpl.java @@ -137,9 +137,6 @@ public class HttpsURLConnectionImpl extends HttpsURLConnection { @Override public void connect() throws IOException { - if (connected) { - return; - } connected = true; httpsEngine.connect(); } @@ -350,8 +347,14 @@ public class HttpsURLConnectionImpl extends HttpsURLConnection { super(url, port, proxy); } - @Override public void connect() throws IOException { - if (connected) { + @Override public void makeConnection() throws IOException { + /* + * Short-circuit a reentrant call. The first step in doing SSL with + * an HTTP proxy requires calling retrieveResponse() which calls + * back into makeConnection(). We can return immediately because the + * unencrypted connection is already valid. + */ + if (method == CONNECT) { return; } @@ -360,12 +363,11 @@ public class HttpsURLConnectionImpl extends HttpsURLConnection { // not unheard of that it will) fallback to a more // barebones connections try { - connect(true); + makeSslConnection(true); } catch (IOException e) { releaseSocket(false); - connect(false); + makeSslConnection(false); } - connected = true; } /** @@ -375,8 +377,8 @@ public class HttpsURLConnectionImpl extends HttpsURLConnection { * TLS extensions and SSL deflate compression. If false, use * an SSL3 only fallback mode without compression. */ - private void connect(boolean tlsTolerant) throws IOException { - super.connect(); + private void makeSslConnection(boolean tlsTolerant) throws IOException { + super.makeConnection(); // make SSL Tunnel if (requiresTunnel()) { -- 2.11.0