diff --git a/mockwebserver/src/main/java/com/squareup/okhttp/mockwebserver/MockWebServer.java b/mockwebserver/src/main/java/com/squareup/okhttp/mockwebserver/MockWebServer.java index 259cf3e36..e79831a9a 100644 --- a/mockwebserver/src/main/java/com/squareup/okhttp/mockwebserver/MockWebServer.java +++ b/mockwebserver/src/main/java/com/squareup/okhttp/mockwebserver/MockWebServer.java @@ -654,8 +654,10 @@ public final class MockWebServer { }; // Adapt the request and response into our Request and Response domain model. + String scheme = request.getTlsVersion() != null ? "https" : "http"; + String authority = request.getHeader("Host"); // Has host and port. final Request fancyRequest = new Request.Builder() - .get().url(request.getPath()) + .url(scheme + "://" + authority + "/") .headers(request.getHeaders()) .build(); final Response fancyResponse = new Response.Builder() diff --git a/okcurl/src/test/java/com/squareup/okhttp/curl/MainTest.java b/okcurl/src/test/java/com/squareup/okhttp/curl/MainTest.java index 80b866517..0e2e3ae1f 100644 --- a/okcurl/src/test/java/com/squareup/okhttp/curl/MainTest.java +++ b/okcurl/src/test/java/com/squareup/okhttp/curl/MainTest.java @@ -29,14 +29,14 @@ public class MainTest { @Test public void simple() { Request request = fromArgs("http://example.com").createRequest(); assertEquals("GET", request.method()); - assertEquals("http://example.com", request.urlString()); + assertEquals("http://example.com/", request.urlString()); assertNull(request.body()); } @Test public void put() throws IOException { Request request = fromArgs("-X", "PUT", "-d", "foo", "http://example.com").createRequest(); assertEquals("PUT", request.method()); - assertEquals("http://example.com", request.urlString()); + assertEquals("http://example.com/", request.urlString()); assertEquals(3, request.body().contentLength()); } @@ -44,7 +44,7 @@ public class MainTest { Request request = fromArgs("-d", "foo", "http://example.com").createRequest(); RequestBody body = request.body(); assertEquals("POST", request.method()); - assertEquals("http://example.com", request.urlString()); + assertEquals("http://example.com/", request.urlString()); assertEquals("application/x-form-urlencoded; charset=utf-8", body.contentType().toString()); assertEquals("foo", bodyAsString(body)); } @@ -53,7 +53,7 @@ public class MainTest { Request request = fromArgs("-d", "foo", "-X", "PUT", "http://example.com").createRequest(); RequestBody body = request.body(); assertEquals("PUT", request.method()); - assertEquals("http://example.com", request.urlString()); + assertEquals("http://example.com/", request.urlString()); assertEquals("application/x-form-urlencoded; charset=utf-8", body.contentType().toString()); assertEquals("foo", bodyAsString(body)); } @@ -63,7 +63,7 @@ public class MainTest { "http://example.com").createRequest(); RequestBody body = request.body(); assertEquals("POST", request.method()); - assertEquals("http://example.com", request.urlString()); + assertEquals("http://example.com/", request.urlString()); assertEquals("application/json; charset=utf-8", body.contentType().toString()); assertEquals("foo", bodyAsString(body)); } @@ -71,7 +71,7 @@ public class MainTest { @Test public void referer() { Request request = fromArgs("-e", "foo", "http://example.com").createRequest(); assertEquals("GET", request.method()); - assertEquals("http://example.com", request.urlString()); + assertEquals("http://example.com/", request.urlString()); assertEquals("foo", request.header("Referer")); assertNull(request.body()); } @@ -79,7 +79,7 @@ public class MainTest { @Test public void userAgent() { Request request = fromArgs("-A", "foo", "http://example.com").createRequest(); assertEquals("GET", request.method()); - assertEquals("http://example.com", request.urlString()); + assertEquals("http://example.com/", request.urlString()); assertEquals("foo", request.header("User-Agent")); assertNull(request.body()); } diff --git a/okhttp-tests/src/test/java/com/squareup/okhttp/CallTest.java b/okhttp-tests/src/test/java/com/squareup/okhttp/CallTest.java index 93f2b5b6e..bc653f256 100644 --- a/okhttp-tests/src/test/java/com/squareup/okhttp/CallTest.java +++ b/okhttp-tests/src/test/java/com/squareup/okhttp/CallTest.java @@ -62,7 +62,6 @@ import okio.GzipSink; import okio.Okio; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -73,7 +72,6 @@ import static com.squareup.okhttp.internal.Internal.logger; import static java.net.CookiePolicy.ACCEPT_ORIGINAL_SERVER; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -127,40 +125,36 @@ public final class CallTest { assertNull(recordedRequest.getHeader("Content-Length")); } - @Test public void lazilyEvaluateRequestUrl() throws Exception { - server.enqueue(new MockResponse().setBody("abc")); + @Test public void buildRequestUsingHttpUrl() throws Exception { + server.enqueue(new MockResponse()); - Request request1 = new Request.Builder() - .url("foo://bar?baz") + HttpUrl httpUrl = HttpUrl.get(server.getUrl("/")); + Request request = new Request.Builder() + .url(httpUrl) .build(); - Request request2 = request1.newBuilder() - .url(server.getUrl("/")) - .build(); - executeSynchronously(request2) - .assertCode(200) - .assertSuccessful() - .assertBody("abc"); + assertEquals(httpUrl, request.httpUrl()); + + executeSynchronously(request).assertSuccessful(); } - @Ignore // TODO(jwilson): fix. @Test public void invalidScheme() throws Exception { + Request.Builder requestBuilder = new Request.Builder(); try { - Request request = new Request.Builder() - .url("ftp://hostname/path") - .build(); - executeSynchronously(request); + requestBuilder.url("ftp://hostname/path"); fail(); } catch (IllegalArgumentException expected) { + assertEquals(expected.getMessage(), "unexpected url: ftp://hostname/path"); } } @Test public void invalidPort() throws Exception { - Request request = new Request.Builder() - .url("http://localhost:65536/") - .build(); - client.newCall(request).enqueue(callback); - callback.await(request.url()) - .assertFailure("No route to localhost:65536; port is out of range"); + Request.Builder requestBuilder = new Request.Builder(); + try { + requestBuilder.url("http://localhost:65536/"); + fail(); + } catch (IllegalArgumentException expected) { + assertEquals(expected.getMessage(), "unexpected url: http://localhost:65536/"); + } } @Test public void getReturns500() throws Exception { diff --git a/okhttp/src/main/java/com/squareup/okhttp/Request.java b/okhttp/src/main/java/com/squareup/okhttp/Request.java index 84fd0454b..8b98a5adf 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/Request.java +++ b/okhttp/src/main/java/com/squareup/okhttp/Request.java @@ -15,12 +15,9 @@ */ package com.squareup.okhttp; -import com.squareup.okhttp.internal.Platform; import com.squareup.okhttp.internal.http.HttpMethod; import java.io.IOException; -import java.net.MalformedURLException; import java.net.URI; -import java.net.URISyntaxException; import java.net.URL; import java.util.List; @@ -29,45 +26,44 @@ import java.util.List; * is null or itself immutable. */ public final class Request { - private final String urlString; + private final HttpUrl url; private final String method; private final Headers headers; private final RequestBody body; private final Object tag; - private volatile URL url; // Lazily initialized. - private volatile URI uri; // Lazily initialized. + private volatile URL javaNetUrl; // Lazily initialized. + private volatile URI javaNetUri; // Lazily initialized. private volatile CacheControl cacheControl; // Lazily initialized. private Request(Builder builder) { - this.urlString = builder.urlString; + this.url = builder.url; this.method = builder.method; this.headers = builder.headers.build(); this.body = builder.body; this.tag = builder.tag != null ? builder.tag : this; - this.url = builder.url; + } + + public HttpUrl httpUrl() { + return url; } public URL url() { - try { - URL result = url; - return result != null ? result : (url = new URL(urlString)); - } catch (MalformedURLException e) { - throw new RuntimeException("Malformed URL: " + urlString, e); - } + URL result = javaNetUrl; + return result != null ? result : (javaNetUrl = url.url()); } public URI uri() throws IOException { try { - URI result = uri; - return result != null ? result : (uri = Platform.get().toUriLenient(url())); - } catch (URISyntaxException e) { + URI result = javaNetUri; + return result != null ? result : (javaNetUri = url.uri()); + } catch (IllegalStateException e) { throw new IOException(e.getMessage()); } } public String urlString() { - return urlString; + return url.toString(); } public String method() { @@ -108,22 +104,21 @@ public final class Request { } public boolean isHttps() { - return url().getProtocol().equals("https"); + return url.isHttps(); } @Override public String toString() { return "Request{method=" + method + ", url=" - + urlString + + url + ", tag=" + (tag != this ? tag : null) + '}'; } public static class Builder { - private String urlString; - private URL url; + private HttpUrl url; private String method; private Headers.Builder headers; private RequestBody body; @@ -135,7 +130,6 @@ public final class Request { } private Builder(Request request) { - this.urlString = request.urlString; this.url = request.url; this.method = request.method; this.body = request.body; @@ -143,18 +137,24 @@ public final class Request { this.headers = request.headers.newBuilder(); } + public Builder url(HttpUrl url) { + if (url == null) throw new IllegalArgumentException("url == null"); + this.url = url; + return this; + } + public Builder url(String url) { if (url == null) throw new IllegalArgumentException("url == null"); - this.urlString = url; - this.url = null; - return this; + HttpUrl parsed = HttpUrl.parse(url); + if (parsed == null) throw new IllegalArgumentException("unexpected url: " + url); + return url(parsed); } public Builder url(URL url) { if (url == null) throw new IllegalArgumentException("url == null"); - this.url = url; - this.urlString = url.toString(); - return this; + HttpUrl parsed = HttpUrl.get(url); + if (parsed == null) throw new IllegalArgumentException("unexpected url: " + url); + return url(parsed); } /** @@ -251,7 +251,7 @@ public final class Request { } public Request build() { - if (urlString == null) throw new IllegalStateException("url == null"); + if (url == null) throw new IllegalStateException("url == null"); return new Request(this); } } diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/Platform.java b/okhttp/src/main/java/com/squareup/okhttp/internal/Platform.java index 073f75f9c..b9064959e 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/Platform.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/Platform.java @@ -25,9 +25,6 @@ import java.lang.reflect.Proxy; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; @@ -76,10 +73,6 @@ public class Platform { public void untagSocket(Socket socket) throws SocketException { } - public URI toUriLenient(URL url) throws URISyntaxException { - return url.toURI(); // this isn't as good as the built-in toUriLenient - } - /** * Configure TLS extensions on {@code sslSocket} for {@code route}. * diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/http/AuthenticatorAdapter.java b/okhttp/src/main/java/com/squareup/okhttp/internal/http/AuthenticatorAdapter.java index a517ada7c..9ccbb032c 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/http/AuthenticatorAdapter.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/http/AuthenticatorAdapter.java @@ -20,6 +20,7 @@ import com.squareup.okhttp.Challenge; import com.squareup.okhttp.Credentials; import com.squareup.okhttp.Request; import com.squareup.okhttp.Response; +import com.squareup.okhttp.internal.Util; import java.io.IOException; import java.net.Authenticator.RequestorType; import java.net.InetAddress; @@ -43,8 +44,9 @@ public final class AuthenticatorAdapter implements Authenticator { if (!"Basic".equalsIgnoreCase(challenge.getScheme())) continue; PasswordAuthentication auth = java.net.Authenticator.requestPasswordAuthentication( - url.getHost(), getConnectToInetAddress(proxy, url), url.getPort(), url.getProtocol(), - challenge.getRealm(), challenge.getScheme(), url, RequestorType.SERVER); + url.getHost(), getConnectToInetAddress(proxy, url), Util.getEffectivePort(url), + url.getProtocol(), challenge.getRealm(), challenge.getScheme(), url, + RequestorType.SERVER); if (auth == null) continue; String credential = Credentials.basic(auth.getUserName(), new String(auth.getPassword())); diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/http/SocketConnector.java b/okhttp/src/main/java/com/squareup/okhttp/internal/http/SocketConnector.java index aba3af44f..c1159bc19 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/http/SocketConnector.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/http/SocketConnector.java @@ -178,7 +178,7 @@ public class SocketConnector { HttpConnection tunnelConnection = new HttpConnection(connectionPool, connection, socket); tunnelConnection.setTimeouts(readTimeout, writeTimeout); URL url = tunnelRequest.url(); - String requestLine = "CONNECT " + url.getHost() + ":" + url.getPort() + " HTTP/1.1"; + String requestLine = "CONNECT " + url.getHost() + ":" + getEffectivePort(url) + " HTTP/1.1"; while (true) { tunnelConnection.writeRequest(tunnelRequest.headers(), requestLine); tunnelConnection.flush();