mirror of
https://github.com/square/okhttp.git
synced 2026-01-17 08:42:25 +03:00
Merge pull request #1828 from nfuller/FixUnknownHostException
Throw UnknownHostException again from HttpURLConnection
This commit is contained in:
@@ -17,8 +17,10 @@ package com.squareup.okhttp;
|
||||
|
||||
import com.squareup.okhttp.UrlComponentEncodingTester.Component;
|
||||
import com.squareup.okhttp.UrlComponentEncodingTester.Encoding;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
@@ -949,6 +951,27 @@ public final class HttpUrlTest {
|
||||
assertEquals(null, HttpUrl.get(uri));
|
||||
}
|
||||
|
||||
@Test public void fromJavaNetUrl_checked() throws Exception {
|
||||
HttpUrl httpUrl = HttpUrl.getChecked("http://username:password@host/path?query#fragment");
|
||||
assertEquals("http://username:password@host/path?query#fragment", httpUrl.toString());
|
||||
}
|
||||
|
||||
@Test public void fromJavaNetUrlUnsupportedScheme_checked() throws Exception {
|
||||
try {
|
||||
HttpUrl.getChecked("mailto:user@example.com");
|
||||
fail();
|
||||
} catch (MalformedURLException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void fromJavaNetUrlBadHost_checked() throws Exception {
|
||||
try {
|
||||
HttpUrl.getChecked("http://hostw ithspace/");
|
||||
fail();
|
||||
} catch (UnknownHostException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void composeQueryWithComponents() throws Exception {
|
||||
HttpUrl base = HttpUrl.parse("http://host/");
|
||||
HttpUrl url = base.newBuilder().addQueryParameter("a+=& b", "c+=& d").build();
|
||||
|
||||
@@ -3178,6 +3178,37 @@ public final class URLConnectionTest {
|
||||
assertContent("abc", client.open(server.getUrl("/")));
|
||||
}
|
||||
|
||||
@Test public void urlWithSpaceInHost() throws Exception {
|
||||
URLConnection urlConnection = client.open(new URL("http://and roid.com/"));
|
||||
try {
|
||||
urlConnection.getInputStream();
|
||||
fail();
|
||||
} catch (UnknownHostException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void urlWithSpaceInHostViaHttpProxy() throws Exception {
|
||||
server.enqueue(new MockResponse());
|
||||
URLConnection urlConnection =
|
||||
client.open(new URL("http://and roid.com/"), server.toProxyAddress());
|
||||
|
||||
try {
|
||||
// This test is to check that a NullPointerException is not thrown.
|
||||
urlConnection.getInputStream();
|
||||
fail(); // the RI makes a bogus proxy request for "GET http://and roid.com/ HTTP/1.1"
|
||||
} catch (UnknownHostException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void urlHostWithNul() throws Exception {
|
||||
URLConnection urlConnection = client.open(new URL("http://host\u0000/"));
|
||||
try {
|
||||
urlConnection.getInputStream();
|
||||
fail();
|
||||
} catch (UnknownHostException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a gzipped copy of {@code bytes}. */
|
||||
public Buffer gzip(String data) throws IOException {
|
||||
Buffer result = new Buffer();
|
||||
|
||||
@@ -46,10 +46,12 @@ import java.io.OutputStream;
|
||||
import java.net.HttpRetryException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.Proxy;
|
||||
import java.net.SocketPermission;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.Permission;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -321,14 +323,16 @@ public class HttpURLConnectionImpl extends HttpURLConnection {
|
||||
}
|
||||
}
|
||||
|
||||
private HttpEngine newHttpEngine(String method, Connection connection,
|
||||
RetryableSink requestBody, Response priorResponse) {
|
||||
private HttpEngine newHttpEngine(String method, Connection connection, RetryableSink requestBody,
|
||||
Response priorResponse) throws MalformedURLException, UnknownHostException {
|
||||
// OkHttp's Call API requires a placeholder body; the real body will be streamed separately.
|
||||
RequestBody placeholderBody = HttpMethod.requiresRequestBody(method)
|
||||
? EMPTY_REQUEST_BODY
|
||||
: null;
|
||||
URL url = getURL();
|
||||
HttpUrl httpUrl = Internal.instance.getHttpUrlChecked(url.toString());
|
||||
Request.Builder builder = new Request.Builder()
|
||||
.url(getURL())
|
||||
.url(httpUrl)
|
||||
.method(method, placeholderBody);
|
||||
Headers headers = requestHeaders.build();
|
||||
for (int i = 0, size = headers.size(); i < size; i++) {
|
||||
|
||||
@@ -561,7 +561,9 @@ public final class HttpUrl {
|
||||
|
||||
/** Returns the URL that would be retrieved by following {@code link} from this URL. */
|
||||
public HttpUrl resolve(String link) {
|
||||
return new Builder().parse(this, link);
|
||||
Builder builder = new Builder();
|
||||
Builder.ParseResult result = builder.parse(this, link);
|
||||
return result == Builder.ParseResult.SUCCESS ? builder.build() : null;
|
||||
}
|
||||
|
||||
public Builder newBuilder() {
|
||||
@@ -584,11 +586,13 @@ public final class HttpUrl {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@code OkUrl} representing {@code url} if it is a well-formed HTTP or HTTPS URL,
|
||||
* or null if it isn't.
|
||||
* Returns a new {@code HttpUrl} representing {@code url} if it is a well-formed HTTP or HTTPS
|
||||
* URL, or null if it isn't.
|
||||
*/
|
||||
public static HttpUrl parse(String url) {
|
||||
return new Builder().parse(null, url);
|
||||
Builder builder = new Builder();
|
||||
Builder.ParseResult result = builder.parse(null, url);
|
||||
return result == Builder.ParseResult.SUCCESS ? builder.build() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -599,6 +603,29 @@ public final class HttpUrl {
|
||||
return parse(url.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@code HttpUrl} representing {@code url} if it is a well-formed HTTP or HTTPS
|
||||
* URL, or throws an exception if it isn't.
|
||||
*
|
||||
* @throws MalformedURLException if there was a non-host related URL issue
|
||||
* @throws UnknownHostException if the host was invalid
|
||||
*/
|
||||
static HttpUrl getChecked(String url) throws MalformedURLException, UnknownHostException {
|
||||
Builder builder = new Builder();
|
||||
Builder.ParseResult result = builder.parse(null, url);
|
||||
switch (result) {
|
||||
case SUCCESS:
|
||||
return builder.build();
|
||||
case INVALID_HOST:
|
||||
throw new UnknownHostException("Invalid host: " + url);
|
||||
case UNSUPPORTED_SCHEME:
|
||||
case MISSING_SCHEME:
|
||||
case INVALID_PORT:
|
||||
default:
|
||||
throw new MalformedURLException("Invalid URL: " + result + " for " + url);
|
||||
}
|
||||
}
|
||||
|
||||
public static HttpUrl get(URI uri) {
|
||||
return parse(uri.toString());
|
||||
}
|
||||
@@ -883,7 +910,15 @@ public final class HttpUrl {
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
HttpUrl parse(HttpUrl base, String input) {
|
||||
enum ParseResult {
|
||||
SUCCESS,
|
||||
MISSING_SCHEME,
|
||||
UNSUPPORTED_SCHEME,
|
||||
INVALID_PORT,
|
||||
INVALID_HOST,
|
||||
}
|
||||
|
||||
ParseResult parse(HttpUrl base, String input) {
|
||||
int pos = skipLeadingAsciiWhitespace(input, 0, input.length());
|
||||
int limit = skipTrailingAsciiWhitespace(input, pos, input.length());
|
||||
|
||||
@@ -897,12 +932,12 @@ public final class HttpUrl {
|
||||
this.scheme = "http";
|
||||
pos += "http:".length();
|
||||
} else {
|
||||
return null; // Not an HTTP scheme.
|
||||
return ParseResult.UNSUPPORTED_SCHEME; // Not an HTTP scheme.
|
||||
}
|
||||
} else if (base != null) {
|
||||
this.scheme = base.scheme;
|
||||
} else {
|
||||
return null; // No scheme.
|
||||
return ParseResult.MISSING_SCHEME; // No scheme.
|
||||
}
|
||||
|
||||
// Authority.
|
||||
@@ -960,12 +995,12 @@ public final class HttpUrl {
|
||||
if (portColonOffset + 1 < componentDelimiterOffset) {
|
||||
this.host = canonicalizeHost(input, pos, portColonOffset);
|
||||
this.port = parsePort(input, portColonOffset + 1, componentDelimiterOffset);
|
||||
if (this.port == -1) return null; // Invalid port.
|
||||
if (this.port == -1) return ParseResult.INVALID_PORT; // Invalid port.
|
||||
} else {
|
||||
this.host = canonicalizeHost(input, pos, portColonOffset);
|
||||
this.port = defaultPort(this.scheme);
|
||||
}
|
||||
if (this.host == null) return null; // Invalid host.
|
||||
if (this.host == null) return ParseResult.INVALID_HOST; // Invalid host.
|
||||
pos = componentDelimiterOffset;
|
||||
break authority;
|
||||
}
|
||||
@@ -1002,7 +1037,7 @@ public final class HttpUrl {
|
||||
input, pos + 1, limit, FRAGMENT_ENCODE_SET, true, false);
|
||||
}
|
||||
|
||||
return build();
|
||||
return ParseResult.SUCCESS;
|
||||
}
|
||||
|
||||
private void resolvePath(String input, int pos, int limit) {
|
||||
|
||||
@@ -27,9 +27,11 @@ import com.squareup.okhttp.internal.http.Transport;
|
||||
import com.squareup.okhttp.internal.tls.OkHostnameVerifier;
|
||||
import java.io.IOException;
|
||||
import java.net.CookieHandler;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.Proxy;
|
||||
import java.net.ProxySelector;
|
||||
import java.net.URLConnection;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -157,6 +159,11 @@ public class OkHttpClient implements Cloneable {
|
||||
public void apply(ConnectionSpec tlsConfiguration, SSLSocket sslSocket, boolean isFallback) {
|
||||
tlsConfiguration.apply(sslSocket, isFallback);
|
||||
}
|
||||
|
||||
@Override public HttpUrl getHttpUrlChecked(String url)
|
||||
throws MalformedURLException, UnknownHostException {
|
||||
return HttpUrl.getChecked(url);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.squareup.okhttp.Connection;
|
||||
import com.squareup.okhttp.ConnectionPool;
|
||||
import com.squareup.okhttp.ConnectionSpec;
|
||||
import com.squareup.okhttp.Headers;
|
||||
import com.squareup.okhttp.HttpUrl;
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
import com.squareup.okhttp.Protocol;
|
||||
import com.squareup.okhttp.Request;
|
||||
@@ -28,6 +29,8 @@ import com.squareup.okhttp.internal.http.HttpEngine;
|
||||
import com.squareup.okhttp.internal.http.RouteException;
|
||||
import com.squareup.okhttp.internal.http.Transport;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.logging.Logger;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import okio.BufferedSink;
|
||||
@@ -85,6 +88,9 @@ public abstract class Internal {
|
||||
public abstract void apply(ConnectionSpec tlsConfiguration, SSLSocket sslSocket,
|
||||
boolean isFallback);
|
||||
|
||||
public abstract HttpUrl getHttpUrlChecked(String url)
|
||||
throws MalformedURLException, UnknownHostException;
|
||||
|
||||
// TODO delete the following when web sockets move into the main package.
|
||||
public abstract void callEnqueue(Call call, Callback responseCallback, boolean forWebSocket);
|
||||
public abstract void callEngineReleaseConnection(Call call) throws IOException;
|
||||
|
||||
Reference in New Issue
Block a user