Don't NullPointerException when a URL contains a space.
We end up creating a URI of http://and%20roid which has no host
name part because and%20roid is not a valid host name. It's unclear
where the best place to fail is. This is consistent with the RI
which doesn't fail until it attempts to connect.
Bug: http://code.google.com/p/android/issues/detail?id=16895
Change-Id: Ifa4dc3c651f4627e27622ed5cedfa820f9a35358
diff --git a/luni/src/main/java/libcore/net/http/HttpConnection.java b/luni/src/main/java/libcore/net/http/HttpConnection.java
index 756edb8..461a309 100644
--- a/luni/src/main/java/libcore/net/http/HttpConnection.java
+++ b/luni/src/main/java/libcore/net/http/HttpConnection.java
@@ -30,6 +30,7 @@
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.URI;
+import java.net.UnknownHostException;
import java.util.List;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSocket;
@@ -292,13 +293,16 @@
private final String socketHost;
private final int socketPort;
- public Address(URI uri) {
+ public Address(URI uri) throws UnknownHostException {
this.proxy = null;
this.requiresTunnel = false;
this.uriHost = uri.getHost();
this.uriPort = uri.getEffectivePort();
this.socketHost = uriHost;
this.socketPort = uriPort;
+ if (uriHost == null) {
+ throw new UnknownHostException(uri.toString());
+ }
}
/**
@@ -307,7 +311,7 @@
* proxy. When doing so, we must avoid buffering bytes intended for
* the higher-level protocol.
*/
- public Address(URI uri, Proxy proxy, boolean requiresTunnel) {
+ public Address(URI uri, Proxy proxy, boolean requiresTunnel) throws UnknownHostException {
this.proxy = proxy;
this.requiresTunnel = requiresTunnel;
this.uriHost = uri.getHost();
@@ -321,6 +325,9 @@
InetSocketAddress proxySocketAddress = (InetSocketAddress) proxyAddress;
this.socketHost = proxySocketAddress.getHostName();
this.socketPort = proxySocketAddress.getPort();
+ if (uriHost == null) {
+ throw new UnknownHostException(uri.toString());
+ }
}
public Proxy getProxy() {
diff --git a/luni/src/test/java/libcore/java/net/URITest.java b/luni/src/test/java/libcore/java/net/URITest.java
index d45facc..ea33568 100644
--- a/luni/src/test/java/libcore/java/net/URITest.java
+++ b/luni/src/test/java/libcore/java/net/URITest.java
@@ -621,5 +621,43 @@
assertEquals(new URI(""), relative.relativize(relative));
}
+ public void testPartContainsSpace() throws Exception {
+ try {
+ new URI("ht tp://host/");
+ fail();
+ } catch (URISyntaxException expected) {
+ }
+ try {
+ new URI("http://user name@host/");
+ fail();
+ } catch (URISyntaxException expected) {
+ }
+ try {
+ new URI("http://ho st/");
+ fail();
+ } catch (URISyntaxException expected) {
+ }
+ try {
+ new URI("http://host:80 80/");
+ fail();
+ } catch (URISyntaxException expected) {
+ }
+ try {
+ new URI("http://host/fi le");
+ fail();
+ } catch (URISyntaxException expected) {
+ }
+ try {
+ new URI("http://host/file?que ry");
+ fail();
+ } catch (URISyntaxException expected) {
+ }
+ try {
+ new URI("http://host/file?query#re f");
+ fail();
+ } catch (URISyntaxException expected) {
+ }
+ }
+
// Adding a new test? Consider adding an equivalent test to URLTest.java
}
diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
index acd3c13..4e65d4c 100644
--- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
@@ -42,6 +42,7 @@
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
+import java.net.UnknownHostException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
@@ -1895,6 +1896,28 @@
assertEquals(-1, in.read());
}
+ // http://code.google.com/p/android/issues/detail?id=16895
+ public void testUrlWithSpaceInHost() throws Exception {
+ URLConnection urlConnection = new URL("http://and roid.com/").openConnection();
+ try {
+ urlConnection.getInputStream();
+ fail();
+ } catch (UnknownHostException expected) {
+ }
+ }
+
+ public void testUrlWithSpaceInHostViaHttpProxy() throws Exception {
+ server.enqueue(new MockResponse());
+ server.play();
+ URLConnection urlConnection = new URL("http://and roid.com/")
+ .openConnection(server.toProxyAddress());
+ try {
+ urlConnection.getInputStream();
+ fail(); // the RI makes a bogus proxy request for "GET http://and roid.com/ HTTP/1.1"
+ } catch (UnknownHostException expected) {
+ }
+ }
+
/**
* Returns a gzipped copy of {@code bytes}.
*/
diff --git a/luni/src/test/java/libcore/java/net/URLTest.java b/luni/src/test/java/libcore/java/net/URLTest.java
index af5915a..3574b8f 100644
--- a/luni/src/test/java/libcore/java/net/URLTest.java
+++ b/luni/src/test/java/libcore/java/net/URLTest.java
@@ -668,5 +668,23 @@
assertEquals("", new URL("http", "host", -1, "", null).getPath());
}
+ public void testPartContainsSpace() throws Exception {
+ try {
+ new URL("ht tp://host/");
+ fail();
+ } catch (MalformedURLException expected) {
+ }
+ assertEquals("user name", new URL("http://user name@host/").getUserInfo());
+ assertEquals("ho st", new URL("http://ho st/").getHost());
+ try {
+ new URL("http://host:80 80/");
+ fail();
+ } catch (MalformedURLException expected) {
+ }
+ assertEquals("/fi le", new URL("http://host/fi le").getFile());
+ assertEquals("que ry", new URL("http://host/file?que ry").getQuery());
+ assertEquals("re f", new URL("http://host/file?query#re f").getRef());
+ }
+
// Adding a new test? Consider adding an equivalent test to URITest.java
}