Test URLConnection.disconnect() while connecting

A HttpURLConnection.disconnect() while establishing a connection
could lead to an infinite busy loop. This CL adds a regression
test that exercises this behavior by disconnecting a connection
from inside the CookieHandler; the CookieHandler is consulted
before the actual connection is established, but late enough
to expose the original bug.

Bug: 33763156
Test: URLConnectionTest

Change-Id: I8e92f8830d6d62922a670e41d612d05f5f8d26b7
(cherry picked from commit f25faf811d480064e13b6bd3b8990d432d1a6510)
diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
index a0f47f4..84ede54 100644
--- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
@@ -37,6 +37,8 @@
 import java.net.Authenticator;
 import java.net.CacheRequest;
 import java.net.CacheResponse;
+import java.net.CookieHandler;
+import java.net.CookieManager;
 import java.net.HttpRetryException;
 import java.net.HttpURLConnection;
 import java.net.InetAddress;
@@ -94,6 +96,8 @@
 import static com.google.mockwebserver.SocketPolicy.FAIL_HANDSHAKE;
 import static com.google.mockwebserver.SocketPolicy.SHUTDOWN_INPUT_AT_END;
 import static com.google.mockwebserver.SocketPolicy.SHUTDOWN_OUTPUT_AT_END;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
 
 public final class URLConnectionTest extends TestCase {
 
@@ -1076,6 +1080,39 @@
         }
     }
 
+    // http://b/33763156
+    public void testDisconnectDuringConnect() throws IOException {
+        server.enqueue(new MockResponse().setBody("This should never be sent"));
+        server.play();
+
+        final AtomicReference<HttpURLConnection> connectionHolder = new AtomicReference<>();
+        class DisconnectingCookieHandler extends CookieManager {
+            @Override
+            public Map<String, List<String>> get(URI uri, Map<String, List<String>> map)
+                    throws IOException {
+                Map<String, List<String>> result = super.get(uri, map);
+                connectionHolder.get().disconnect();
+                return result;
+            }
+        }
+        CookieHandler defaultCookieHandler = CookieHandler.getDefault();
+        try {
+            CookieHandler.setDefault(new DisconnectingCookieHandler());
+            HttpURLConnection connection = (HttpURLConnection) server.getUrl("/").openConnection();
+            connectionHolder.set(connection);
+            try {
+                connection.getInputStream();
+                fail();
+            } catch (IOException expected) {
+                assertEquals("Canceled", expected.getMessage());
+            } finally {
+                connection.disconnect();
+            }
+        } finally {
+            CookieHandler.setDefault(defaultCookieHandler);
+        }
+    }
+
     public void testDisconnectBeforeConnect() throws IOException {
         server.enqueue(new MockResponse().setBody("A"));
         server.play();