diff --git a/okhttp-android/src/androidTest/kotlin/okhttp3/android/AndroidAsyncDnsTest.kt b/okhttp-android/src/androidTest/kotlin/okhttp3/android/AndroidAsyncDnsTest.kt index 3b8330007..d9a76270b 100644 --- a/okhttp-android/src/androidTest/kotlin/okhttp3/android/AndroidAsyncDnsTest.kt +++ b/okhttp-android/src/androidTest/kotlin/okhttp3/android/AndroidAsyncDnsTest.kt @@ -26,6 +26,7 @@ import mockwebserver3.MockResponse import mockwebserver3.MockWebServer import mockwebserver3.junit5.internal.MockWebServerExtension import okhttp3.AsyncDns +import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.tls.HandshakeCertificates @@ -74,7 +75,7 @@ class AndroidAsyncDnsTest(val server: MockWebServer) { fun testRequest() { server.enqueue(MockResponse()) - val call = client.newCall(Request.Builder().url(server.url("/")).build()) + val call = client.newCall(Request(server.url("/"))) call.execute().use { response -> assertThat(response.code).isEqualTo(200) @@ -85,7 +86,7 @@ class AndroidAsyncDnsTest(val server: MockWebServer) { fun testRequestExternal() { assumeNetwork() - val call = client.newCall(Request.Builder().url("https://google.com/robots.txt").build()) + val call = client.newCall(Request("https://google.com/robots.txt".toHttpUrl())) call.execute().use { response -> assertThat(response.code).isEqualTo(200) @@ -94,7 +95,7 @@ class AndroidAsyncDnsTest(val server: MockWebServer) { @Test fun testRequestInvalid() { - val call = client.newCall(Request.Builder().url("https://google.invalid/").build()) + val call = client.newCall(Request("https://google.invalid/".toHttpUrl())) try { call.execute() @@ -171,7 +172,7 @@ class AndroidAsyncDnsTest(val server: MockWebServer) { .build() val call = - client.newCall(Request.Builder().url("https://google.com/robots.txt").build()) + client.newCall(Request("https://google.com/robots.txt".toHttpUrl())) call.execute().use { response -> assertThat(response.code).isEqualTo(200) diff --git a/okhttp-coroutines/src/jvmTest/kotlin/okhttp3/SuspendCallTest.kt b/okhttp-coroutines/src/jvmTest/kotlin/okhttp3/SuspendCallTest.kt index 7277deb71..999984588 100644 --- a/okhttp-coroutines/src/jvmTest/kotlin/okhttp3/SuspendCallTest.kt +++ b/okhttp-coroutines/src/jvmTest/kotlin/okhttp3/SuspendCallTest.kt @@ -49,7 +49,7 @@ class SuspendCallTest( private var client = clientTestRule.newClientBuilder().build() - val request = Request.Builder().url(server.url("/")).build() + val request = Request(server.url("/")) @Test fun suspendCall() { diff --git a/okhttp-testing-support/src/main/kotlin/okhttp3/TestValueFactory.kt b/okhttp-testing-support/src/main/kotlin/okhttp3/TestValueFactory.kt index b62a68477..f6ef42ac7 100644 --- a/okhttp-testing-support/src/main/kotlin/okhttp3/TestValueFactory.kt +++ b/okhttp-testing-support/src/main/kotlin/okhttp3/TestValueFactory.kt @@ -171,17 +171,11 @@ class TestValueFactory : Closeable { ) } - fun newRequest(address: Address): Request { - return Request.Builder() - .url(address.url) - .build() - } - fun newRoutePlanner( client: OkHttpClient, address: Address = newAddress(), ): RealRoutePlanner { - val call = RealCall(client, newRequest(address), forWebSocket = false) + val call = RealCall(client, Request(address.url), forWebSocket = false) return RealRoutePlanner(client, address, call, newChain(call)) } diff --git a/okhttp/api/okhttp.api b/okhttp/api/okhttp.api index 1477d10eb..daf1f011b 100644 --- a/okhttp/api/okhttp.api +++ b/okhttp/api/okhttp.api @@ -999,6 +999,8 @@ public final class okhttp3/Request { public final fun -deprecated_headers ()Lokhttp3/Headers; public final fun -deprecated_method ()Ljava/lang/String; public final fun -deprecated_url ()Lokhttp3/HttpUrl; + public fun (Lokhttp3/HttpUrl;Lokhttp3/Headers;Ljava/lang/String;Lokhttp3/RequestBody;)V + public synthetic fun (Lokhttp3/HttpUrl;Lokhttp3/Headers;Ljava/lang/String;Lokhttp3/RequestBody;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun body ()Lokhttp3/RequestBody; public final fun cacheControl ()Lokhttp3/CacheControl; public final fun header (Ljava/lang/String;)Ljava/lang/String; diff --git a/okhttp/src/commonMain/kotlin/okhttp3/Request.kt b/okhttp/src/commonMain/kotlin/okhttp3/Request.kt index a298636a6..be491f333 100644 --- a/okhttp/src/commonMain/kotlin/okhttp3/Request.kt +++ b/okhttp/src/commonMain/kotlin/okhttp3/Request.kt @@ -22,7 +22,7 @@ import okhttp3.internal.commonEmptyRequestBody * An HTTP request. Instances of this class are immutable if their [body] is null or itself * immutable. */ -expect class Request { +expect class Request private constructor(builder: Builder) { val url: HttpUrlRepresentation val method: String val headers: Headers diff --git a/okhttp/src/jvmMain/kotlin/okhttp3/Cache.kt b/okhttp/src/jvmMain/kotlin/okhttp3/Cache.kt index 93d6a135e..78bc29aa3 100644 --- a/okhttp/src/jvmMain/kotlin/okhttp3/Cache.kt +++ b/okhttp/src/jvmMain/kotlin/okhttp3/Cache.kt @@ -15,6 +15,15 @@ */ package okhttp3 +import java.io.Closeable +import java.io.File +import java.io.Flushable +import java.io.IOException +import java.security.cert.Certificate +import java.security.cert.CertificateEncodingException +import java.security.cert.CertificateException +import java.security.cert.CertificateFactory +import java.util.TreeSet import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.internal.EMPTY_HEADERS @@ -23,6 +32,7 @@ import okhttp3.internal.cache.CacheStrategy import okhttp3.internal.cache.DiskLruCache import okhttp3.internal.closeQuietly import okhttp3.internal.concurrent.TaskRunner +import okhttp3.internal.http.HttpMethod import okhttp3.internal.http.StatusLine import okhttp3.internal.platform.Platform import okhttp3.internal.platform.Platform.Companion.WARN @@ -41,17 +51,6 @@ import okio.Path.Companion.toOkioPath import okio.Sink import okio.Source import okio.buffer -import java.io.Closeable -import java.io.File -import java.io.Flushable -import java.io.IOException -import java.security.cert.Certificate -import java.security.cert.CertificateEncodingException -import java.security.cert.CertificateException -import java.security.cert.CertificateFactory -import java.util.NoSuchElementException -import java.util.TreeSet -import okhttp3.internal.http.HttpMethod /** * Caches HTTP and HTTPS responses to the filesystem so they may be reused, saving time and @@ -648,11 +647,7 @@ class Cache( fun response(snapshot: DiskLruCache.Snapshot): Response { val contentType = responseHeaders["Content-Type"] val contentLength = responseHeaders["Content-Length"] - val cacheRequest = Request.Builder() - .url(url) - .method(requestMethod, null) - .headers(varyHeaders) - .build() + val cacheRequest = Request(url, varyHeaders, requestMethod) return Response.Builder() .request(cacheRequest) .protocol(protocol) diff --git a/okhttp/src/jvmMain/kotlin/okhttp3/Request.kt b/okhttp/src/jvmMain/kotlin/okhttp3/Request.kt index 205164492..15303d1d5 100644 --- a/okhttp/src/jvmMain/kotlin/okhttp3/Request.kt +++ b/okhttp/src/jvmMain/kotlin/okhttp3/Request.kt @@ -32,18 +32,52 @@ import okhttp3.internal.commonPut import okhttp3.internal.commonRemoveHeader import okhttp3.internal.toImmutableMap -actual class Request internal constructor( - @get:JvmName("url") actual val url: HttpUrl, - @get:JvmName("method") actual val method: String, - @get:JvmName("headers") actual val headers: Headers, - @get:JvmName("body") actual val body: RequestBody?, - internal val tags: Map, Any> -) { +actual class Request internal actual constructor(builder: Builder) { + @get:JvmName("url") + actual val url: HttpUrl = checkNotNull(builder.url) { "url == null" } + + @get:JvmName("method") + actual val method: String = builder.method + + @get:JvmName("headers") + actual val headers: Headers = builder.headers.build() + + @get:JvmName("body") + actual val body: RequestBody? = builder.body + + internal val tags: Map, Any> = builder.tags.toImmutableMap() + internal actual var lazyCacheControl: CacheControl? = null actual val isHttps: Boolean get() = url.isHttps + /** + * Constructs a new request. + * + * Use [Builder] for more fluent construction, including helper methods for various HTTP methods. + * + * @param method defaults to "GET" if [body] is null, and "POST" otherwise. + */ + constructor( + url: HttpUrl, + headers: Headers = Headers.headersOf(), + method: String = "\u0000", // Sentinel value chooses based on what the body is. + body: RequestBody? = null, + ) : this( + Builder() + .url(url) + .headers(headers) + .method( + when { + method != "\u0000" -> method + body != null -> "POST" + else -> "GET" + }, + body + ) + ) + actual fun header(name: String): String? = commonHeader(name) actual fun headers(name: String): List = commonHeaders(name) @@ -222,14 +256,6 @@ actual class Request internal constructor( } } - actual open fun build(): Request { - return Request( - checkNotNull(url) { "url == null" }, - method, - headers.build(), - body, - tags.toImmutableMap() - ) - } + actual open fun build() = Request(this) } } diff --git a/okhttp/src/jvmMain/kotlin/okhttp3/internal/http1/Http1ExchangeCodec.kt b/okhttp/src/jvmMain/kotlin/okhttp3/internal/http1/Http1ExchangeCodec.kt index eac6e533b..694173287 100644 --- a/okhttp/src/jvmMain/kotlin/okhttp3/internal/http1/Http1ExchangeCodec.kt +++ b/okhttp/src/jvmMain/kotlin/okhttp3/internal/http1/Http1ExchangeCodec.kt @@ -88,7 +88,7 @@ class Http1ExchangeCodec( override fun createRequestBody(request: Request, contentLength: Long): Sink { return when { - request.body != null && request.body.isDuplex() -> throw ProtocolException( + request.body?.isDuplex() == true -> throw ProtocolException( "Duplex connections are not supported for HTTP/1") request.isChunked -> newChunkedSink() // Stream a request body of unknown length. contentLength != -1L -> newKnownLengthSink() // Stream a request body of a known length. diff --git a/okhttp/src/jvmTest/java/okhttp3/CacheCorruptionTest.kt b/okhttp/src/jvmTest/java/okhttp3/CacheCorruptionTest.kt index 8781d2972..bbee27ff0 100644 --- a/okhttp/src/jvmTest/java/okhttp3/CacheCorruptionTest.kt +++ b/okhttp/src/jvmTest/java/okhttp3/CacheCorruptionTest.kt @@ -161,7 +161,7 @@ class CacheCorruptionTest( ) .hostnameVerifier(NULL_HOSTNAME_VERIFIER) .build() - val request: Request = Request.Builder().url(server.url("/")).build() + val request: Request = Request(server.url("/")) val response1: Response = client.newCall(request).execute() val bodySource = response1.body.source() assertThat(bodySource.readUtf8()).isEqualTo("ABC.1") diff --git a/okhttp/src/jvmTest/java/okhttp3/CallHandshakeTest.kt b/okhttp/src/jvmTest/java/okhttp3/CallHandshakeTest.kt index b51043634..5d45bd7c1 100644 --- a/okhttp/src/jvmTest/java/okhttp3/CallHandshakeTest.kt +++ b/okhttp/src/jvmTest/java/okhttp3/CallHandshakeTest.kt @@ -274,7 +274,7 @@ class CallHandshakeTest { } private fun makeRequest(client: OkHttpClient): Handshake { - val call = client.newCall(Request.Builder().url(server.url("/")).build()) + val call = client.newCall(Request(server.url("/"))) return call.execute().use { it.handshake!! } } } diff --git a/okhttp/src/jvmTest/java/okhttp3/CallKotlinTest.kt b/okhttp/src/jvmTest/java/okhttp3/CallKotlinTest.kt index 0a0e3024a..3b43ad2ca 100644 --- a/okhttp/src/jvmTest/java/okhttp3/CallKotlinTest.kt +++ b/okhttp/src/jvmTest/java/okhttp3/CallKotlinTest.kt @@ -65,9 +65,7 @@ class CallKotlinTest( server.enqueue(MockResponse().setBody("abc")) server.enqueue(MockResponse().setBody("def")) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) val call = client.newCall(request) val response1 = call.execute() @@ -204,9 +202,7 @@ class CallKotlinTest( .setSocketPolicy(SocketPolicy.SHUTDOWN_OUTPUT_AT_END)) server.enqueue(MockResponse().setBody("b")) - val requestA = Request.Builder() - .url(server.url("/")) - .build() + val requestA = Request(server.url("/")) val responseA = client.newCall(requestA).execute() assertThat(responseA.body.string()).isEqualTo("a") @@ -216,10 +212,10 @@ class CallKotlinTest( connection!!.idleAtNs -= IDLE_CONNECTION_HEALTHY_NS Thread.sleep(250) - val requestB = Request.Builder() - .url(server.url("/")) - .post("b".toRequestBody("text/plain".toMediaType())) - .build() + val requestB = Request( + url = server.url("/"), + body = "b".toRequestBody("text/plain".toMediaType()), + ) val responseB = client.newCall(requestB).execute() assertThat(responseB.body.string()).isEqualTo("b") assertThat(server.takeRequest().sequenceNumber).isEqualTo(0) @@ -238,7 +234,7 @@ class CallKotlinTest( .connectTimeout(Duration.ofMillis(100)) .build() - val request = Request.Builder().url(server.url("/")).build() + val request = Request(server.url("/")) try { client.newCall(request).execute() fail("") @@ -260,7 +256,7 @@ class CallKotlinTest( .dns(DoubleInetAddressDns()) // Two routes so we get two failures. .build() - val request = Request.Builder().url(server.url("/")).build() + val request = Request(server.url("/")) try { client.newCall(request).execute() fail("") @@ -282,10 +278,7 @@ class CallKotlinTest( ) server.enqueue(MockResponse()) - val request = Request.Builder() - .url(server.url("/")) - .build() - + val request = Request(server.url("/")) val call = client.newCall(request) val response = call.execute() diff --git a/okhttp/src/jvmTest/java/okhttp3/CallTest.kt b/okhttp/src/jvmTest/java/okhttp3/CallTest.kt index 434eee54e..75c030bb1 100644 --- a/okhttp/src/jvmTest/java/okhttp3/CallTest.kt +++ b/okhttp/src/jvmTest/java/okhttp3/CallTest.kt @@ -265,9 +265,7 @@ open class CallTest( val response = client.newCall(headRequest).execute() assertThat(response.code).isEqualTo(200) assertArrayEquals(ByteArray(0), response.body.bytes()) - val getRequest = Request.Builder() - .url(server.url("/")) - .build() + val getRequest = Request(server.url("/")) executeSynchronously(getRequest) .assertCode(200) .assertBody("abc") @@ -293,9 +291,7 @@ open class CallTest( .assertCode(200) .assertHeader("Content-Encoding", "chunked") .assertBody("") - val getRequest = Request.Builder() - .url(server.url("/")) - .build() + val getRequest = Request(server.url("/")) executeSynchronously(getRequest) .assertCode(200) .assertBody("abc") @@ -315,10 +311,10 @@ open class CallTest( @Test fun post() { server.enqueue(MockResponse().setBody("abc")) - val request = Request.Builder() - .url(server.url("/")) - .post("def".toRequestBody("text/plain".toMediaType())) - .build() + val request = Request( + url = server.url("/"), + body = "def".toRequestBody("text/plain".toMediaType()), + ) executeSynchronously(request) .assertCode(200) .assertBody("abc") @@ -651,9 +647,7 @@ open class CallTest( @Test fun legalToExecuteTwiceCloning() { server.enqueue(MockResponse().setBody("abc")) server.enqueue(MockResponse().setBody("def")) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) val call = client.newCall(request) val response1 = call.execute() val cloned = call.clone() @@ -665,9 +659,7 @@ open class CallTest( @Test fun legalToExecuteTwiceCloning_Async() { server.enqueue(MockResponse().setBody("abc")) server.enqueue(MockResponse().setBody("def")) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) val call = client.newCall(request) call.enqueue(callback) val cloned = call.clone() @@ -701,9 +693,7 @@ open class CallTest( @Test fun exceptionThrownByOnResponseIsRedactedAndLogged() { server.enqueue(MockResponse()) - val request = Request.Builder() - .url(server.url("/secret")) - .build() + val request = Request(server.url("/secret")) client.newCall(request).enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { fail() @@ -915,9 +905,7 @@ open class CallTest( } }) .build() - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) executeSynchronously(request) .assertCode(200) } @@ -942,9 +930,7 @@ open class CallTest( response }) .build() - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) executeSynchronously(request).assertBody("abc") } @@ -1068,9 +1054,7 @@ open class CallTest( .setBody("abc") .addHeader("Content-Type: text/plain") ) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) client.newCall(request).enqueue(callback) callback.await(request.url).assertHandshake() } @@ -1224,9 +1208,7 @@ open class CallTest( handshakeCertificates.trustManager ) .build() - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) client.newCall(request).enqueue(callback) callback.await(request.url).assertBody("abc") } @@ -1339,11 +1321,7 @@ open class CallTest( .build() server.useHttps(handshakeCertificates.sslSocketFactory(), false) server.enqueue(MockResponse()) - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) try { call.execute() fail() @@ -1422,10 +1400,10 @@ open class CallTest( @Test fun post_Async() { server.enqueue(MockResponse().setBody("abc")) - val request = Request.Builder() - .url(server.url("/")) - .post("def".toRequestBody("text/plain".toMediaType())) - .build() + val request = Request( + url = server.url("/"), + body = "def".toRequestBody("text/plain".toMediaType()) + ) client.newCall(request).enqueue(callback) callback.await(request.url) .assertCode(200) @@ -1452,10 +1430,10 @@ open class CallTest( listener.clearAllEvents() - val request2 = Request.Builder() - .url(server.url("/")) - .post("body!".toRequestBody("text/plain".toMediaType())) - .build() + val request2 = Request( + url = server.url("/"), + body = "body!".toRequestBody("text/plain".toMediaType()), + ) try { client.newCall(request2).execute() fail() @@ -1500,10 +1478,10 @@ open class CallTest( val request1 = Request.Builder().url(server.url("/")).build() val response1 = client.newCall(request1).execute() assertThat(response1.body.string()).isEqualTo("abc") - val request2 = Request.Builder() - .url(server.url("/")) - .post("body!".toRequestBody("text/plain".toMediaType())) - .build() + val request2 = Request( + server.url("/"), + body = "body!".toRequestBody("text/plain".toMediaType()), + ) val response2 = client.newCall(request2).execute() assertThat(response2.body.string()).isEqualTo("def") val get = server.takeRequest() @@ -1664,15 +1642,11 @@ open class CallTest( client = client.newBuilder() .cache(cache) .build() - val request1 = Request.Builder() - .url(server.url("/")) - .build() + val request1 = Request(server.url("/")) client.newCall(request1).enqueue(callback) callback.await(request1.url).assertCode(200).assertBody("A") assertThat(server.takeRequest().getHeader("If-None-Match")).isNull() - val request2 = Request.Builder() - .url(server.url("/")) - .build() + val request2 = Request(server.url("/")) client.newCall(request2).enqueue(callback) callback.await(request2.url).assertCode(200).assertBody("A") assertThat(server.takeRequest().getHeader("If-None-Match")).isEqualTo("v1") @@ -1743,15 +1717,11 @@ open class CallTest( client = client.newBuilder() .cache(cache) .build() - val request1 = Request.Builder() - .url(server.url("/")) - .build() + val request1 = Request(server.url("/")) client.newCall(request1).enqueue(callback) callback.await(request1.url).assertCode(200).assertBody("A") assertThat(server.takeRequest().getHeader("If-None-Match")).isNull() - val request2 = Request.Builder() - .url(server.url("/")) - .build() + val request2 = Request(server.url("/")) client.newCall(request2).enqueue(callback) callback.await(request2.url).assertCode(200).assertBody("B") assertThat(server.takeRequest().getHeader("If-None-Match")).isEqualTo("v1") @@ -1830,10 +1800,10 @@ open class CallTest( ) server.enqueue(MockResponse().setBody("Page 2")) val response = client.newCall( - Request.Builder() - .url(server.url("/page1")) - .post("Request Body".toRequestBody("text/plain".toMediaType())) - .build() + Request( + url = server.url("/page1"), + body = "Request Body".toRequestBody("text/plain".toMediaType()), + ) ).execute() assertThat(response.body.string()).isEqualTo("Page 2") val page1 = server.takeRequest() @@ -1852,9 +1822,7 @@ open class CallTest( .setBody("You took too long!") ) server.enqueue(MockResponse().setBody("Body")) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) val response = client.newCall(request).execute() assertThat(response.body.string()).isEqualTo("Body") } @@ -1868,9 +1836,7 @@ open class CallTest( .setHeader("Retry-After", "1") .setBody("You took too long!") ) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) val response = client.newCall(request).execute() assertThat(response.body.string()).isEqualTo("You took too long!") } @@ -1884,10 +1850,10 @@ open class CallTest( .setBody("You took too long!") ) server.enqueue(MockResponse().setBody("Body")) - val request = Request.Builder() - .url(server.url("/")) - .post("Hello".toRequestBody("text/plain".toMediaType())) - .build() + val request = Request( + server.url("/"), + body = "Hello".toRequestBody("text/plain".toMediaType()), + ) val response = client.newCall(request).execute() assertThat(response.body.string()).isEqualTo("Body") val request1 = server.takeRequest() @@ -1907,9 +1873,7 @@ open class CallTest( client = client.newBuilder() .retryOnConnectionFailure(false) .build() - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) val response = client.newCall(request).execute() assertThat(response.code).isEqualTo(408) assertThat(response.body!!.string()).isEqualTo("You took too long!") @@ -1930,9 +1894,7 @@ open class CallTest( .setHeader("Connection", "Close") .setBody("You took too long!") ) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) val response = client.newCall(request).execute() assertThat(response.code).isEqualTo(408) assertThat(response.body.string()).isEqualTo("You took too long!") @@ -1956,9 +1918,7 @@ open class CallTest( .setHeader("Retry-After", "0") .setBody("You took too long!") ) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) val response = client.newCall(request).execute() assertThat(response.code).isEqualTo(503) assertThat(response.body.string()).isEqualTo("You took too long!") @@ -1975,9 +1935,7 @@ open class CallTest( .setBody("You took too long!") ) server.enqueue(MockResponse().setBody("Body")) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) val response = client.newCall(request).execute() assertThat(response.body.string()).isEqualTo("Body") } @@ -1993,9 +1951,9 @@ open class CallTest( MockResponse() .setBody("thank you for retrying") ) - val request = Request.Builder() - .url(server.url("/")) - .post(object : RequestBody() { + val request = Request( + url = server.url("/"), + body = object : RequestBody() { var attempt = 0 override fun contentType(): MediaType? { return null @@ -2004,8 +1962,8 @@ open class CallTest( override fun writeTo(sink: BufferedSink) { sink.writeUtf8("attempt " + attempt++) } - }) - .build() + }, + ) val response = client.newCall(request).execute() assertThat(response.code).isEqualTo(200) assertThat(response.body.string()).isEqualTo("thank you for retrying") @@ -2025,9 +1983,9 @@ open class CallTest( MockResponse() .setBody("thank you for retrying") ) - val request = Request.Builder() - .url(server.url("/")) - .post(object : RequestBody() { + val request = Request( + url = server.url("/"), + body = object : RequestBody() { var attempt = 0 override fun contentType(): MediaType? { return null @@ -2040,8 +1998,8 @@ open class CallTest( override fun isOneShot(): Boolean { return true } - }) - .build() + }, + ) val response = client.newCall(request).execute() assertThat(response.code).isEqualTo(503) assertThat(response.body.string()).isEqualTo("please retry") @@ -2128,11 +2086,7 @@ open class CallTest( client = client.newBuilder() .cookieJar(JavaNetCookieJar(cookieManager)) .build() - val response = client.newCall( - Request.Builder() - .url(server.url("/page1")) - .build() - ).execute() + val response = client.newCall(Request(server.url("/page1"))).execute() assertThat(response.body.string()).isEqualTo("Page 2") val request1 = server.takeRequest() assertThat(request1.getHeader("Cookie")).isEqualTo("c=cookie") @@ -2331,11 +2285,7 @@ open class CallTest( .setSocketPolicy(SocketPolicy.STALL_SOCKET_AT_START) ) val cancelDelayMillis = 300L - val call = client.newCall( - Request.Builder() - .url(server.url("/").newBuilder().scheme(scheme!!).build()) - .build() - ) + val call = client.newCall(Request(server.url("/").newBuilder().scheme(scheme!!).build())) cancelLater(call, cancelDelayMillis) val startNanos = System.nanoTime() try { @@ -2361,11 +2311,7 @@ open class CallTest( chain.proceed(chain.request()) }) .build() - val call = client.newCall( - Request.Builder() - .url(server.url("/a")) - .build() - ) + val call = client.newCall(Request(server.url("/a"))) call.enqueue(callback) call.cancel() latch.countDown() @@ -2373,11 +2319,7 @@ open class CallTest( } @Test fun cancelAll() { - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) call.enqueue(callback) client.dispatcher.cancelAll() callback.await(server.url("/")).assertFailure("Canceled", "Socket closed", "Socket is closed") @@ -2396,7 +2338,7 @@ open class CallTest( } } client = client.newBuilder().eventListener(listener).build() - val call = client.newCall(Request.Builder().url(server.url("/a")).build()) + val call = client.newCall(Request(server.url("/a"))) try { call.execute() fail() @@ -2411,7 +2353,7 @@ open class CallTest( @Test fun cancelBeforeBodyIsRead() { server.enqueue(MockResponse().setBody("def").throttleBody(1, 750, TimeUnit.MILLISECONDS)) - val call = client.newCall(Request.Builder().url(server.url("/a")).build()) + val call = client.newCall(Request(server.url("/a"))) val executor = Executors.newSingleThreadExecutor() val result = executor.submit { call.execute() } Thread.sleep(100) // wait for it to go in flight. @@ -2425,7 +2367,7 @@ open class CallTest( } @Test fun cancelInFlightBeforeResponseReadThrowsIOE() { - val request = Request.Builder().url(server.url("/a")).build() + val request = Request(server.url("/a")) val call = client.newCall(request) server.dispatcher = object : mockwebserver3.Dispatcher() { override fun dispatch(request: RecordedRequest): MockResponse { @@ -2462,8 +2404,8 @@ open class CallTest( client = client.newBuilder() .dispatcher(dispatcher) .build() - val requestA = Request.Builder().url(server.url("/a")).build() - val requestB = Request.Builder().url(server.url("/b")).build() + val requestA = Request(server.url("/a")) + val requestB = Request(server.url("/b")) val callA = client.newCall(requestA) val callB = client.newCall(requestB) server.dispatcher = object : mockwebserver3.Dispatcher() { @@ -2492,7 +2434,7 @@ open class CallTest( } @Test fun canceledBeforeResponseReadSignalsOnFailure() { - val requestA = Request.Builder().url(server.url("/a")).build() + val requestA = Request(server.url("/a")) val call = client.newCall(requestA) server.dispatcher = object : mockwebserver3.Dispatcher() { override fun dispatch(request: RecordedRequest): MockResponse { @@ -2527,7 +2469,7 @@ open class CallTest( val latch = CountDownLatch(1) val bodyRef = AtomicReference() val failureRef = AtomicBoolean() - val request = Request.Builder().url(server.url("/a")).build() + val request = Request(server.url("/a")) val call = client.newCall(request) call.enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { @@ -2571,7 +2513,7 @@ open class CallTest( throw AssertionError() // We expect an exception. }) .build() - val call = client.newCall(Request.Builder().url(server.url("/a")).build()) + val call = client.newCall(Request(server.url("/a"))) call.cancel() try { call.execute() @@ -2782,10 +2724,10 @@ open class CallTest( MockResponse() .add100Continue() ) - val request = Request.Builder() - .url(server.url("/")) - .post("abc".toRequestBody("text/plain".toMediaType())) - .build() + val request = Request( + url = server.url("/"), + body = "abc".toRequestBody("text/plain".toMediaType()), + ) executeSynchronously(request) .assertCode(200) .assertSuccessful() @@ -2807,10 +2749,10 @@ open class CallTest( MockResponse() .setStatus("HTTP/1.1 100 Continue") ) - val request = Request.Builder() - .url(server.url("/")) - .post("abc".toRequestBody("text/plain".toMediaType())) - .build() + val request = Request( + url = server.url("/"), + body = "abc".toRequestBody("text/plain".toMediaType()), + ) val call = client.newCall(request) try { call.execute() @@ -2840,11 +2782,7 @@ open class CallTest( .post("abc".toRequestBody("text/plain".toMediaType())) .build() ) - executeSynchronously( - Request.Builder() - .url(server.url("/")) - .build() - ) + executeSynchronously(Request(server.url("/"))) assertThat(server.takeRequest().sequenceNumber).isEqualTo(0) assertThat(server.takeRequest().sequenceNumber).isEqualTo(1) } @@ -2866,11 +2804,7 @@ open class CallTest( .post("abc".toRequestBody("text/plain".toMediaType())) .build() ) - executeSynchronously( - Request.Builder() - .url(server.url("/")) - .build() - ) + executeSynchronously(Request(server.url("/"))) assertThat(server.takeRequest().sequenceNumber).isEqualTo(0) assertThat(server.takeRequest().sequenceNumber).isEqualTo(0) } @@ -2887,11 +2821,7 @@ open class CallTest( .post("abc".toRequestBody("text/plain".toMediaType())) .build() ) - executeSynchronously( - Request.Builder() - .url(server.url("/")) - .build() - ) + executeSynchronously(Request(server.url("/"))) assertThat(server.takeRequest().sequenceNumber).isEqualTo(0) assertThat(server.takeRequest().sequenceNumber).isEqualTo(1) } @@ -2919,9 +2849,7 @@ open class CallTest( .dns(dns) .build() server.enqueue(MockResponse()) - val request = Request.Builder() - .url(server.url("/").newBuilder().host("android.com").build()) - .build() + val request = Request(server.url("/").newBuilder().host("android.com").build()) executeSynchronously(request).assertCode(200) dns.assertRequests("android.com") } @@ -2935,9 +2863,7 @@ open class CallTest( .dns(dns) .build() server.enqueue(MockResponse()) - val request = Request.Builder() - .url(server.url("/").newBuilder().host("android.com").build()) - .build() + val request = Request(server.url("/").newBuilder().host("android.com").build()) executeSynchronously(request).assertFailure("$dns returned no addresses for android.com") dns.assertRequests("android.com") } @@ -2962,10 +2888,10 @@ open class CallTest( } } val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .post(requestBody) - .build() + Request( + url = server.url("/"), + body = requestBody + ) ) call.execute().use { response -> assertThat(response.code).isEqualTo(200) @@ -3040,9 +2966,7 @@ open class CallTest( .proxy(server.toProxyAddress()) .hostnameVerifier(hostnameVerifier) .build() - val request = Request.Builder() - .url("https://android.com/foo") - .build() + val request = Request("https://android.com/foo".toHttpUrl()) try { client.newCall(request).execute() fail() @@ -3077,9 +3001,7 @@ open class CallTest( .proxyAuthenticator(RecordingOkAuthenticator("password", "Basic")) .hostnameVerifier(RecordingHostnameVerifier()) .build() - val request = Request.Builder() - .url("https://android.com/foo") - .build() + val request = Request("https://android.com/foo".toHttpUrl()) val response = client.newCall(request).execute() assertThat(response.body.string()).isEqualTo("response body") val connect1 = server.takeRequest() @@ -3108,9 +3030,7 @@ open class CallTest( .proxy(server.toProxyAddress()) .proxyAuthenticator(RecordingOkAuthenticator("password", "Basic")) .build() - val request = Request.Builder() - .url("http://android.com/foo") - .build() + val request = Request("http://android.com/foo".toHttpUrl()) val response = client.newCall(request).execute() assertThat(response.body.string()).isEqualTo("response body") val get1 = server.takeRequest() @@ -3152,9 +3072,7 @@ open class CallTest( .proxyAuthenticator(RecordingOkAuthenticator("password", "Basic")) .hostnameVerifier(RecordingHostnameVerifier()) .build() - val request = Request.Builder() - .url("https://android.com/foo") - .build() + val request = Request("https://android.com/foo".toHttpUrl()) val response = client.newCall(request).execute() assertThat(response.body.string()).isEqualTo("response body") @@ -3188,9 +3106,7 @@ open class CallTest( .proxyAuthenticator(RecordingOkAuthenticator("password", "Basic")) .hostnameVerifier(RecordingHostnameVerifier()) .build() - val request = Request.Builder() - .url("https://android.com/foo") - .build() + val request = Request("https://android.com/foo".toHttpUrl()) try { client.newCall(request).execute() fail() @@ -3265,9 +3181,7 @@ open class CallTest( .build() } .build() - val request = Request.Builder() - .url("https://android.com/foo") - .build() + val request = Request("https://android.com/foo".toHttpUrl()) executeSynchronously(request).assertSuccessful() val connect = server.takeRequest() assertThat(connect.method).isEqualTo("CONNECT") @@ -3310,9 +3224,7 @@ open class CallTest( .build() } .build() - val request = Request.Builder() - .url("https://android.com/foo") - .build() + val request = Request("https://android.com/foo".toHttpUrl()) executeSynchronously(request).assertSuccessful() val connect1 = server.takeRequest() assertThat(connect1.method).isEqualTo("CONNECT") @@ -3337,9 +3249,7 @@ open class CallTest( ) .proxy(server.toProxyAddress()) .build() - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) try { client.newCall(request).execute() fail() @@ -3428,7 +3338,7 @@ open class CallTest( .addHeader("content-length: 0") .addHeaderLenient("a b", "c") ) - val call = client.newCall(Request.Builder().url(server.url("/")).build()) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() assertThat(response.header("a b")).isEqualTo("c") } @@ -3440,7 +3350,7 @@ open class CallTest( .addHeader("content-length: 0") .addHeaderLenient("a\tb", "c") ) - val call = client.newCall(Request.Builder().url(server.url("/")).build()) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() assertThat(response.header("a\tb")).isEqualTo("c") } @@ -3463,19 +3373,17 @@ open class CallTest( ) .build() server2.shutdown() - val request = Request.Builder() - .url(server.url("/")) - .post("abc".toRequestBody("text/plain".toMediaType())) - .build() + val request = Request( + url = server.url("/"), + body = "abc".toRequestBody("text/plain".toMediaType()), + ) executeSynchronously(request) assertThat(server.takeRequest().body.readUtf8()).isEqualTo("abc") } @Disabled // This may fail in DNS lookup, which we don't have timeouts for. @Test fun invalidHost() { - val request = Request.Builder() - .url("http://1234.1.1.1/".toHttpUrl()) - .build() + val request = Request("http://1234.1.1.1/".toHttpUrl()) executeSynchronously(request) .assertFailure(UnknownHostException::class.java) } @@ -3511,10 +3419,10 @@ open class CallTest( private fun upload(chunked: Boolean, size: Int, writeSize: Int) { server.enqueue(MockResponse()) executeSynchronously( - Request.Builder() - .url(server.url("/")) - .post(requestBody(chunked, size.toLong(), writeSize)) - .build() + Request( + url = server.url("/"), + body = requestBody(chunked, size.toLong(), writeSize), + ) ) } @@ -3530,9 +3438,7 @@ open class CallTest( .host("::1") .port(port) .build() - val request = Request.Builder() - .url(url) - .build() + val request = Request(url) val response = client.newCall(request).execute() assertThat(response.body.string()).isEqualTo("response body") val connect = server.takeRequest() @@ -3557,9 +3463,7 @@ open class CallTest( .host("::1") .port(port) .build() - val request = Request.Builder() - .url(url) - .build() + val request = Request(url) val response = client.newCall(request).execute() assertThat(response.body.string()).isEqualTo("response body") val connect = server.takeRequest() @@ -3590,9 +3494,7 @@ open class CallTest( .host("127.0.0.1") .port(port) .build() - val request = Request.Builder() - .url(url) - .build() + val request = Request(url) val response = client.newCall(request).execute() assertThat(response.body.string()).isEqualTo("response body") val connect = server.takeRequest() @@ -3623,9 +3525,7 @@ open class CallTest( .host("127.0.0.1") .port(port) .build() - val request = Request.Builder() - .url(url) - .build() + val request = Request(url) val response = client.newCall(request).execute() assertThat(response.body.string()).isEqualTo("response body") val connect = server.takeRequest() @@ -3650,9 +3550,7 @@ open class CallTest( .host("any-host-name") .port(port) .build() - val request = Request.Builder() - .url(url) - .build() + val request = Request(url) val response = client.newCall(request).execute() assertThat(response.body.string()).isEqualTo("response body") val connect = server.takeRequest() @@ -3677,9 +3575,7 @@ open class CallTest( .host("any-host-name") .port(port) .build() - val request = Request.Builder() - .url(url) - .build() + val request = Request(url) val response = client.newCall(request).execute() assertThat(response.body.string()).isEqualTo("response body") val connect = server.takeRequest() @@ -3753,9 +3649,7 @@ open class CallTest( client = clientTestRule.newClientBuilder() .connectionPool(ConnectionPool(0, 10, TimeUnit.MILLISECONDS)) .build() - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) client.newCall(request).execute() // Ignore the response so it gets leaked then GC'd. awaitGarbageCollection() val message = testLogHandler.take() @@ -3773,9 +3667,7 @@ open class CallTest( client = clientTestRule.newClientBuilder() .connectionPool(ConnectionPool(0, 10, TimeUnit.MILLISECONDS)) .build() - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) val latch = CountDownLatch(1) client.newCall(request).enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { @@ -3806,9 +3698,7 @@ open class CallTest( client = client.newBuilder() .authenticator { _: Route?, _: Response -> throw IOException("IOException!") } .build() - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) executeSynchronously(request) .assertFailure(IOException::class.java) assertThat(client.connectionPool.idleConnectionCount()).isEqualTo(1) @@ -3824,9 +3714,7 @@ open class CallTest( throw IOException("IOException!") } .build() - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) executeSynchronously(request) .assertFailure(IOException::class.java) assertThat(client.connectionPool.idleConnectionCount()).isEqualTo(1) @@ -3860,9 +3748,7 @@ open class CallTest( val url = server.url("/").newBuilder() .host(localIpAddress) .build() - val request = Request.Builder() - .url(url) - .build() + val request = Request(url) executeSynchronously(request) .assertCode(200) @@ -3881,10 +3767,10 @@ open class CallTest( throw FileNotFoundException() } } - val request = Request.Builder() - .url(server.url("/")) - .post(body) - .build() + val request = Request( + url = server.url("/"), + body = body, + ) client = client.newBuilder() .dns(DoubleInetAddressDns()) .build() @@ -3901,11 +3787,7 @@ open class CallTest( .setChunkedBody("HelloBonjour", 1024) .setTrailers(headersOf("trailers", "boom")) server.enqueue(mockResponse) - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() val source = response.body.source() assertThat(response.header("h1")).isEqualTo("v1") @@ -3928,11 +3810,7 @@ open class CallTest( .setTrailers(headersOf("trailers", "boom")) server.enqueue(mockResponse) enableProtocol(Protocol.HTTP_2) - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) call.execute().use { response -> val source = response.body.source() assertThat(response.header("h1")).isEqualTo("v1") @@ -3960,9 +3838,9 @@ open class CallTest( @Test fun requestBodyThrowsUnrelatedToNetwork() { server.enqueue(MockResponse()) - val request = Request.Builder() - .url(server.url("/")) - .post(object : RequestBody() { + val request = Request( + url = server.url("/"), + body = object : RequestBody() { override fun contentType(): MediaType? { return null } @@ -3971,8 +3849,8 @@ open class CallTest( sink.flush() // For determinism, always send a partial request to the server. throw IOException("boom") } - }) - .build() + }, + ) executeSynchronously(request).assertFailure("boom") assertThat(server.takeRequest().failure).isNotNull } @@ -4001,11 +3879,7 @@ open class CallTest( } }) .build() - val call = cancelClient.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = cancelClient.newCall(Request(server.url("/"))) val response = call.execute() assertThat(response.body.string()).isEqualTo("abc") executeSynchronously("/").assertCode(200) @@ -4049,9 +3923,7 @@ open class CallTest( server.enqueue(MockResponse() .setBody("this is the redirect target")) - val call = client.newCall(Request.Builder() - .url(server.url("/")) - .build()) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() assertThat(response.body.string()).isEqualTo("this is the redirect target") assertThat(response.priorResponse?.body?.contentType()) @@ -4079,10 +3951,10 @@ open class CallTest( .retryOnConnectionFailure(false) .build() val call = nonRetryingClient.newCall( - Request.Builder() - .url(server.url("/")) - .post(requestBody) - .build() + Request( + url = server.url("/"), + body = requestBody, + ) ) try { call.execute() diff --git a/okhttp/src/jvmTest/java/okhttp3/ConnectionReuseTest.kt b/okhttp/src/jvmTest/java/okhttp3/ConnectionReuseTest.kt index 8022310be..36d68d559 100644 --- a/okhttp/src/jvmTest/java/okhttp3/ConnectionReuseTest.kt +++ b/okhttp/src/jvmTest/java/okhttp3/ConnectionReuseTest.kt @@ -55,19 +55,17 @@ class ConnectionReuseTest { @Test fun connectionsAreReused() { server.enqueue(MockResponse().setBody("a")) server.enqueue(MockResponse().setBody("b")) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) assertConnectionReused(request, request) } @Test fun connectionsAreReusedForPosts() { server.enqueue(MockResponse().setBody("a")) server.enqueue(MockResponse().setBody("b")) - val request = Request.Builder() - .url(server.url("/")) - .post("request body".toRequestBody("text/plain".toMediaType())) - .build() + val request = Request( + url = server.url("/"), + body ="request body".toRequestBody("text/plain".toMediaType()), + ) assertConnectionReused(request, request) } @@ -76,9 +74,7 @@ class ConnectionReuseTest { enableHttp2() server.enqueue(MockResponse().setBody("a")) server.enqueue(MockResponse().setBody("b")) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) assertConnectionReused(request, request) } @@ -89,9 +85,7 @@ class ConnectionReuseTest { .url(server.url("/")) .header("Connection", "close") .build() - val requestB = Request.Builder() - .url(server.url("/")) - .build() + val requestB = Request(server.url("/")) assertConnectionNotReused(requestA, requestB) } @@ -102,12 +96,8 @@ class ConnectionReuseTest { .setBody("a") ) server.enqueue(MockResponse().setBody("b")) - val requestA = Request.Builder() - .url(server.url("/")) - .build() - val requestB = Request.Builder() - .url(server.url("/")) - .build() + val requestA = Request(server.url("/")) + val requestB = Request(server.url("/")) assertConnectionNotReused(requestA, requestB) } @@ -119,9 +109,7 @@ class ConnectionReuseTest { .clearHeaders() ) server.enqueue(MockResponse().setBody("b")) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) assertConnectionNotReused(request, request) } @@ -131,9 +119,7 @@ class ConnectionReuseTest { .build() server.enqueue(MockResponse().setBody("a")) server.enqueue(MockResponse().setBody("b")) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) assertConnectionNotReused(request, request) } @@ -148,9 +134,7 @@ class ConnectionReuseTest { .setBody("a") ) server.enqueue(MockResponse().setBody("b")) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) val response = client.newCall(request).execute() assertThat(response.body.string()).isEqualTo("b") assertThat(server.takeRequest().sequenceNumber).isEqualTo(0) @@ -169,9 +153,7 @@ class ConnectionReuseTest { .setBody("a") ) server.enqueue(MockResponse().setBody("b")) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) val response = client.newCall(request).execute() assertThat(response.body.string()).isEqualTo("b") assertThat(server.takeRequest().sequenceNumber).isEqualTo(0) @@ -182,9 +164,7 @@ class ConnectionReuseTest { server.enqueue(MockResponse().setBody("a")) server.enqueue(MockResponse().setSocketPolicy(SocketPolicy.DISCONNECT_AFTER_REQUEST)) server.enqueue(MockResponse().setBody("b")) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) val responseA = client.newCall(request).execute() assertThat(responseA.body.string()).isEqualTo("a") assertThat(server.takeRequest().sequenceNumber).isEqualTo(0) @@ -199,9 +179,7 @@ class ConnectionReuseTest { enableHttp2() server.enqueue(MockResponse().setBody("a")) server.enqueue(MockResponse().setBody("b")) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) val response1 = client.newCall(request).execute() val response2 = client.newCall(request).execute() response1.body.string() // Discard the response body. @@ -216,9 +194,7 @@ class ConnectionReuseTest { client = client.newBuilder() .connectionPool(ConnectionPool(5, 250, TimeUnit.MILLISECONDS)) .build() - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) val response1 = client.newCall(request).execute() assertThat(response1.body.string()).isEqualTo("a") @@ -235,9 +211,7 @@ class ConnectionReuseTest { enableHttps() server.enqueue(MockResponse()) server.enqueue(MockResponse()) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) val response = client.newCall(request).execute() response.body.close() @@ -262,9 +236,7 @@ class ConnectionReuseTest { enableHttps() server.enqueue(MockResponse()) server.enqueue(MockResponse()) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) val response1 = client.newCall(request).execute() response1.body.close() @@ -317,9 +289,7 @@ class ConnectionReuseTest { MockResponse() .setBody("/b is here") ) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) val call = client.newCall(request) call.execute().use { response -> assertThat( diff --git a/okhttp/src/jvmTest/java/okhttp3/FastFallbackTest.kt b/okhttp/src/jvmTest/java/okhttp3/FastFallbackTest.kt index dbb9401d9..da9ac4bb0 100644 --- a/okhttp/src/jvmTest/java/okhttp3/FastFallbackTest.kt +++ b/okhttp/src/jvmTest/java/okhttp3/FastFallbackTest.kt @@ -121,11 +121,7 @@ class FastFallbackTest { .setBody("hello from IPv6") ) - val call = client.newCall( - Request.Builder() - .url(url) - .build() - ) + val call = client.newCall(Request(url)) val response = call.execute() assertThat(response.body.string()).isEqualTo("hello from IPv6") @@ -150,11 +146,7 @@ class FastFallbackTest { .setBody("hello from IPv6") ) - val call = client.newCall( - Request.Builder() - .url(url) - .build() - ) + val call = client.newCall(Request(url)) val response = call.execute() assertThat(response.body.string()).isEqualTo("hello from IPv6") @@ -171,11 +163,7 @@ class FastFallbackTest { .setBody("hello from IPv4") ) - val call = client.newCall( - Request.Builder() - .url(url) - .build() - ) + val call = client.newCall(Request(url)) val response = call.execute() assertThat(response.body.string()).isEqualTo("hello from IPv4") @@ -193,11 +181,7 @@ class FastFallbackTest { .setBody("hello from IPv6") ) - val call = client.newCall( - Request.Builder() - .url(url) - .build() - ) + val call = client.newCall(Request(url)) val response = call.execute() assertThat(response.body.string()).isEqualTo("hello from IPv6") @@ -212,11 +196,7 @@ class FastFallbackTest { serverIpv4.shutdown() serverIpv6.shutdown() - val call = client.newCall( - Request.Builder() - .url(url) - .build() - ) + val call = client.newCall(Request(url)) assertFailsWith { call.execute() } @@ -239,11 +219,7 @@ class FastFallbackTest { .setBody("hello from IPv4") ) - val call = client.newCall( - Request.Builder() - .url(url) - .build() - ) + val call = client.newCall(Request(url)) val response = call.execute() assertThat(response.body.string()).isEqualTo("hello from IPv4") @@ -268,11 +244,7 @@ class FastFallbackTest { .fastFallback(false) .callTimeout(1_000, TimeUnit.MILLISECONDS) .build() - val call = client.newCall( - Request.Builder() - .url(url) - .build() - ) + val call = client.newCall(Request(url)) try { call.execute() fail("expected a timeout") @@ -341,11 +313,7 @@ class FastFallbackTest { ) // Confirm the retry succeeds on the same connection. - val call = client.newCall( - Request.Builder() - .url(url) - .build() - ) + val call = client.newCall(Request(url)) val response = call.execute() assertThat(response.body.string()).isEqualTo("this was the 2nd request on IPv4") assertThat(serverIpv4.takeRequest().sequenceNumber).isEqualTo(0) diff --git a/okhttp/src/jvmTest/java/okhttp3/InsecureForHostTest.kt b/okhttp/src/jvmTest/java/okhttp3/InsecureForHostTest.kt index f9c3b7f6a..9a4f713a1 100644 --- a/okhttp/src/jvmTest/java/okhttp3/InsecureForHostTest.kt +++ b/okhttp/src/jvmTest/java/okhttp3/InsecureForHostTest.kt @@ -47,9 +47,7 @@ class InsecureForHostTest( .sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager) .build() - val call = client.newCall(Request.Builder() - .url(server.url("/")) - .build()) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() assertThat(response.code).isEqualTo(200) assertThat(response.handshake!!.cipherSuite).isNotNull() @@ -79,9 +77,7 @@ class InsecureForHostTest( .sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager) .build() - val call = client.newCall(Request.Builder() - .url(server.url("/")) - .build()) + val call = client.newCall(Request(server.url("/"))) try { call.execute() fail("") @@ -103,9 +99,7 @@ class InsecureForHostTest( .sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager) .build() - val call = client.newCall(Request.Builder() - .url(server.url("/")) - .build()) + val call = client.newCall(Request(server.url("/"))) try { call.execute() fail("") diff --git a/okhttp/src/jvmTest/java/okhttp3/JSSETest.kt b/okhttp/src/jvmTest/java/okhttp3/JSSETest.kt index ed7681f5a..65c9eb420 100644 --- a/okhttp/src/jvmTest/java/okhttp3/JSSETest.kt +++ b/okhttp/src/jvmTest/java/okhttp3/JSSETest.kt @@ -62,7 +62,7 @@ class JSSETest( server.enqueue(MockResponse().setBody("abc")) - val request = Request.Builder().url(server.url("/")).build() + val request = Request(server.url("/")) val response = client.newCall(request).execute() diff --git a/okhttp/src/jvmTest/java/okhttp3/KotlinSourceModernTest.kt b/okhttp/src/jvmTest/java/okhttp3/KotlinSourceModernTest.kt index 8de87027f..4471bc13d 100644 --- a/okhttp/src/jvmTest/java/okhttp3/KotlinSourceModernTest.kt +++ b/okhttp/src/jvmTest/java/okhttp3/KotlinSourceModernTest.kt @@ -963,6 +963,17 @@ class KotlinSourceModernTest { val cacheControl: CacheControl = request.cacheControl } + @Test + fun requestConstructor() { + Request(url = "".toHttpUrl()) + Request( + url = "".toHttpUrl(), + headers = headersOf(), + method = "", + body = "".toRequestBody(null), + ) + } + @Test fun requestBuilder() { val requestBody = "".toRequestBody(null) diff --git a/okhttp/src/jvmTest/java/okhttp3/OkHttpClientTest.kt b/okhttp/src/jvmTest/java/okhttp3/OkHttpClientTest.kt index f461e8795..cfa314f24 100644 --- a/okhttp/src/jvmTest/java/okhttp3/OkHttpClientTest.kt +++ b/okhttp/src/jvmTest/java/okhttp3/OkHttpClientTest.kt @@ -220,9 +220,7 @@ class OkHttpClientTest { server!!.enqueue(MockResponse().setBody("abc")) ProxySelector.setDefault(null) val client = clientTestRule.newClient() - val request = Request.Builder() - .url(server!!.url("/")) - .build() + val request = Request(server!!.url("/")) val response = client.newCall(request).execute() assertThat(response.body.string()).isEqualTo("abc") } diff --git a/okhttp/src/jvmTest/java/okhttp3/OpenJSSETest.kt b/okhttp/src/jvmTest/java/okhttp3/OpenJSSETest.kt index 21e209c6b..b6c616ff9 100644 --- a/okhttp/src/jvmTest/java/okhttp3/OpenJSSETest.kt +++ b/okhttp/src/jvmTest/java/okhttp3/OpenJSSETest.kt @@ -53,7 +53,7 @@ class OpenJSSETest( server.enqueue(MockResponse().setBody("abc")) - val request = Request.Builder().url(server.url("/")).build() + val request = Request(server.url("/")) val response = client.newCall(request).execute() diff --git a/okhttp/src/jvmTest/java/okhttp3/RequestTest.java b/okhttp/src/jvmTest/java/okhttp3/RequestTest.java deleted file mode 100644 index eb9ff1af1..000000000 --- a/okhttp/src/jvmTest/java/okhttp3/RequestTest.java +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (C) 2013 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okhttp3; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.net.URI; -import java.util.UUID; -import okio.Buffer; -import okio.ByteString; -import org.junit.jupiter.api.Test; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.fail; - -public final class RequestTest { - @Test public void string() throws Exception { - MediaType contentType = MediaType.get("text/plain; charset=utf-8"); - RequestBody body = RequestBody.create("abc".getBytes(UTF_8), contentType); - assertThat(body.contentType()).isEqualTo(contentType); - assertThat(body.contentLength()).isEqualTo(3); - assertThat(bodyToHex(body)).isEqualTo("616263"); - assertThat(bodyToHex(body)).overridingErrorMessage("Retransmit body").isEqualTo( - "616263"); - } - - @Test public void stringWithDefaultCharsetAdded() throws Exception { - MediaType contentType = MediaType.get("text/plain"); - RequestBody body = RequestBody.create("\u0800", contentType); - assertThat(body.contentType()).isEqualTo(MediaType.get("text/plain; charset=utf-8")); - assertThat(body.contentLength()).isEqualTo(3); - assertThat(bodyToHex(body)).isEqualTo("e0a080"); - } - - @Test public void stringWithNonDefaultCharsetSpecified() throws Exception { - MediaType contentType = MediaType.get("text/plain; charset=utf-16be"); - RequestBody body = RequestBody.create("\u0800", contentType); - assertThat(body.contentType()).isEqualTo(contentType); - assertThat(body.contentLength()).isEqualTo(2); - assertThat(bodyToHex(body)).isEqualTo("0800"); - } - - @Test public void byteArray() throws Exception { - MediaType contentType = MediaType.get("text/plain"); - RequestBody body = RequestBody.create("abc".getBytes(UTF_8), contentType); - assertThat(body.contentType()).isEqualTo(contentType); - assertThat(body.contentLength()).isEqualTo(3); - assertThat(bodyToHex(body)).isEqualTo("616263"); - assertThat(bodyToHex(body)).overridingErrorMessage("Retransmit body").isEqualTo( - "616263"); - } - - @Test public void byteArrayRange() throws Exception { - MediaType contentType = MediaType.get("text/plain"); - RequestBody body = RequestBody.create(".abcd".getBytes(UTF_8), contentType, 1, 3); - assertThat(body.contentType()).isEqualTo(contentType); - assertThat(body.contentLength()).isEqualTo(3); - assertThat(bodyToHex(body)).isEqualTo("616263"); - assertThat(bodyToHex(body)).overridingErrorMessage("Retransmit body").isEqualTo( - "616263"); - } - - @Test public void byteString() throws Exception { - MediaType contentType = MediaType.get("text/plain"); - RequestBody body = RequestBody.create(ByteString.encodeUtf8("Hello"), contentType); - assertThat(body.contentType()).isEqualTo(contentType); - assertThat(body.contentLength()).isEqualTo(5); - assertThat(bodyToHex(body)).isEqualTo("48656c6c6f"); - assertThat(bodyToHex(body)).overridingErrorMessage("Retransmit body").isEqualTo( - "48656c6c6f"); - } - - @Test public void file() throws Exception { - File file = File.createTempFile("RequestTest", "tmp"); - FileWriter writer = new FileWriter(file); - writer.write("abc"); - writer.close(); - - MediaType contentType = MediaType.get("text/plain"); - RequestBody body = RequestBody.create(file, contentType); - assertThat(body.contentType()).isEqualTo(contentType); - assertThat(body.contentLength()).isEqualTo(3); - assertThat(bodyToHex(body)).isEqualTo("616263"); - assertThat(bodyToHex(body)).overridingErrorMessage("Retransmit body").isEqualTo( - "616263"); - } - - /** Common verbs used for apis such as GitHub, AWS, and Google Cloud. */ - @Test public void crudVerbs() throws IOException { - MediaType contentType = MediaType.get("application/json"); - RequestBody body = RequestBody.create("{}", contentType); - - Request get = new Request.Builder().url("http://localhost/api").get().build(); - assertThat(get.method()).isEqualTo("GET"); - assertThat(get.body()).isNull(); - - Request head = new Request.Builder().url("http://localhost/api").head().build(); - assertThat(head.method()).isEqualTo("HEAD"); - assertThat(head.body()).isNull(); - - Request delete = new Request.Builder().url("http://localhost/api").delete().build(); - assertThat(delete.method()).isEqualTo("DELETE"); - assertThat(delete.body().contentLength()).isEqualTo(0L); - - Request post = new Request.Builder().url("http://localhost/api").post(body).build(); - assertThat(post.method()).isEqualTo("POST"); - assertThat(post.body()).isEqualTo(body); - - Request put = new Request.Builder().url("http://localhost/api").put(body).build(); - assertThat(put.method()).isEqualTo("PUT"); - assertThat(put.body()).isEqualTo(body); - - Request patch = new Request.Builder().url("http://localhost/api").patch(body).build(); - assertThat(patch.method()).isEqualTo("PATCH"); - assertThat(patch.body()).isEqualTo(body); - } - - @Test public void uninitializedURI() throws Exception { - Request request = new Request.Builder().url("http://localhost/api").build(); - assertThat(request.url().uri()).isEqualTo(new URI("http://localhost/api")); - assertThat(request.url()).isEqualTo(HttpUrl.get("http://localhost/api")); - } - - @Test public void newBuilderUrlResetsUrl() { - Request requestWithoutCache = new Request.Builder().url("http://localhost/api").build(); - Request builtRequestWithoutCache = - requestWithoutCache.newBuilder().url("http://localhost/api/foo").build(); - assertThat(builtRequestWithoutCache.url()).isEqualTo( - HttpUrl.get("http://localhost/api/foo")); - - Request requestWithCache = new Request.Builder().url("http://localhost/api").build(); - // cache url object - requestWithCache.url(); - Request builtRequestWithCache = requestWithCache.newBuilder().url( - "http://localhost/api/foo").build(); - assertThat(builtRequestWithCache.url()).isEqualTo( - HttpUrl.get("http://localhost/api/foo")); - } - - @Test public void cacheControl() { - Request request = new Request.Builder() - .cacheControl(new CacheControl.Builder().noCache().build()) - .url("https://square.com") - .build(); - assertThat(request.headers("Cache-Control")).containsExactly("no-cache"); - assertThat(request.cacheControl().noCache()).isTrue(); - } - - @Test public void emptyCacheControlClearsAllCacheControlHeaders() { - Request request = new Request.Builder() - .header("Cache-Control", "foo") - .cacheControl(new CacheControl.Builder().build()) - .url("https://square.com") - .build(); - assertThat(request.headers("Cache-Control")).isEmpty(); - } - - @Test public void headerAcceptsPermittedCharacters() { - Request.Builder builder = new Request.Builder(); - builder.header("AZab09~", "AZab09 ~"); - builder.addHeader("AZab09~", "AZab09 ~"); - } - - @Test public void emptyNameForbidden() { - Request.Builder builder = new Request.Builder(); - try { - builder.header("", "Value"); - fail(); - } catch (IllegalArgumentException expected) { - } - try { - builder.addHeader("", "Value"); - fail(); - } catch (IllegalArgumentException expected) { - } - } - - @Test public void headerForbidsNullArguments() { - Request.Builder builder = new Request.Builder(); - try { - builder.header(null, "Value"); - fail(); - } catch (NullPointerException expected) { - } - try { - builder.addHeader(null, "Value"); - fail(); - } catch (NullPointerException expected) { - } - try { - builder.header("Name", null); - fail(); - } catch (NullPointerException expected) { - } - try { - builder.addHeader("Name", null); - fail(); - } catch (NullPointerException expected) { - } - } - - @Test public void headerAllowsTabOnlyInValues() { - Request.Builder builder = new Request.Builder(); - builder.header("key", "sample\tvalue"); - try { - builder.header("sample\tkey", "value"); - fail(); - } catch (IllegalArgumentException expected) { - } - } - - @Test public void headerForbidsControlCharacters() { - assertForbiddenHeader("\u0000"); - assertForbiddenHeader("\r"); - assertForbiddenHeader("\n"); - assertForbiddenHeader("\u001f"); - assertForbiddenHeader("\u007f"); - assertForbiddenHeader("\u0080"); - assertForbiddenHeader("\ud83c\udf69"); - } - - private void assertForbiddenHeader(String s) { - Request.Builder builder = new Request.Builder(); - try { - builder.header(s, "Value"); - fail(); - } catch (IllegalArgumentException expected) { - } - try { - builder.addHeader(s, "Value"); - fail(); - } catch (IllegalArgumentException expected) { - } - try { - builder.header("Name", s); - fail(); - } catch (IllegalArgumentException expected) { - } - try { - builder.addHeader("Name", s); - fail(); - } catch (IllegalArgumentException expected) { - } - } - - @Test public void noTag() { - Request request = new Request.Builder() - .url("https://square.com") - .build(); - assertThat(request.tag()).isNull(); - assertThat(request.tag(Object.class)).isNull(); - assertThat(request.tag(UUID.class)).isNull(); - assertThat(request.tag(String.class)).isNull(); - } - - @Test public void defaultTag() { - UUID tag = UUID.randomUUID(); - Request request = new Request.Builder() - .url("https://square.com") - .tag(tag) - .build(); - assertThat(request.tag()).isSameAs(tag); - assertThat(request.tag(Object.class)).isSameAs(tag); - assertThat(request.tag(UUID.class)).isNull(); - assertThat(request.tag(String.class)).isNull(); - } - - @Test public void nullRemovesTag() { - Request request = new Request.Builder() - .url("https://square.com") - .tag("a") - .tag(null) - .build(); - assertThat(request.tag()).isNull(); - } - - @Test public void removeAbsentTag() { - Request request = new Request.Builder() - .url("https://square.com") - .tag(null) - .build(); - assertThat(request.tag()).isNull(); - } - - @Test public void objectTag() { - UUID tag = UUID.randomUUID(); - Request request = new Request.Builder() - .url("https://square.com") - .tag(Object.class, tag) - .build(); - assertThat(request.tag()).isSameAs(tag); - assertThat(request.tag(Object.class)).isSameAs(tag); - assertThat(request.tag(UUID.class)).isNull(); - assertThat(request.tag(String.class)).isNull(); - } - - @Test public void typedTag() { - UUID uuidTag = UUID.randomUUID(); - Request request = new Request.Builder() - .url("https://square.com") - .tag(UUID.class, uuidTag) - .build(); - assertThat(request.tag()).isNull(); - assertThat(request.tag(Object.class)).isNull(); - assertThat(request.tag(UUID.class)).isSameAs(uuidTag); - assertThat(request.tag(String.class)).isNull(); - } - - @Test public void replaceOnlyTag() { - UUID uuidTag1 = UUID.randomUUID(); - UUID uuidTag2 = UUID.randomUUID(); - Request request = new Request.Builder() - .url("https://square.com") - .tag(UUID.class, uuidTag1) - .tag(UUID.class, uuidTag2) - .build(); - assertThat(request.tag(UUID.class)).isSameAs(uuidTag2); - } - - @Test public void multipleTags() { - UUID uuidTag = UUID.randomUUID(); - String stringTag = "dilophosaurus"; - Long longTag = 20170815L; - Object objectTag = new Object(); - Request request = new Request.Builder() - .url("https://square.com") - .tag(Object.class, objectTag) - .tag(UUID.class, uuidTag) - .tag(String.class, stringTag) - .tag(Long.class, longTag) - .build(); - assertThat(request.tag()).isSameAs(objectTag); - assertThat(request.tag(Object.class)).isSameAs(objectTag); - assertThat(request.tag(UUID.class)).isSameAs(uuidTag); - assertThat(request.tag(String.class)).isSameAs(stringTag); - assertThat(request.tag(Long.class)).isSameAs(longTag); - } - - /** Confirm that we don't accidentally share the backing map between objects. */ - @Test public void tagsAreImmutable() { - Request.Builder builder = new Request.Builder() - .url("https://square.com"); - Request requestA = builder.tag(String.class, "a").build(); - Request requestB = builder.tag(String.class, "b").build(); - Request requestC = requestA.newBuilder().tag(String.class, "c").build(); - assertThat(requestA.tag(String.class)).isSameAs("a"); - assertThat(requestB.tag(String.class)).isSameAs("b"); - assertThat(requestC.tag(String.class)).isSameAs("c"); - } - - private String bodyToHex(RequestBody body) throws IOException { - Buffer buffer = new Buffer(); - body.writeTo(buffer); - return buffer.readByteString().hex(); - } -} diff --git a/okhttp/src/jvmTest/java/okhttp3/RequestTest.kt b/okhttp/src/jvmTest/java/okhttp3/RequestTest.kt new file mode 100644 index 000000000..fc95d9690 --- /dev/null +++ b/okhttp/src/jvmTest/java/okhttp3/RequestTest.kt @@ -0,0 +1,448 @@ +/* + * Copyright (C) 2013 Square, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package okhttp3 + +import java.io.File +import java.io.FileWriter +import java.net.URI +import java.util.UUID +import okhttp3.Headers.Companion.headersOf +import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.RequestBody.Companion.asRequestBody +import okhttp3.RequestBody.Companion.toRequestBody +import okio.Buffer +import okio.ByteString.Companion.encodeUtf8 +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.fail +import org.junit.jupiter.api.Test + +class RequestTest { + + @Test + fun constructor() { + val url = "https://example.com/".toHttpUrl() + val body = "hello".toRequestBody() + val headers = headersOf("User-Agent", "RequestTest") + val method = "PUT" + val request = Request( + url = url, + headers = headers, + method = method, + body = body + ) + assertThat(request.url).isEqualTo(url) + assertThat(request.headers).isEqualTo(headers) + assertThat(request.method).isEqualTo(method) + assertThat(request.body).isEqualTo(body) + assertThat(request.tags).isEmpty() + } + + @Test + fun constructorNoBodyNoMethod() { + val url = "https://example.com/".toHttpUrl() + val headers = headersOf("User-Agent", "RequestTest") + val request = Request( + url = url, + headers = headers, + ) + assertThat(request.url).isEqualTo(url) + assertThat(request.headers).isEqualTo(headers) + assertThat(request.method).isEqualTo("GET") + assertThat(request.body).isNull() + assertThat(request.tags).isEmpty() + } + + @Test + fun constructorNoMethod() { + val url = "https://example.com/".toHttpUrl() + val body = "hello".toRequestBody() + val headers = headersOf("User-Agent", "RequestTest") + val request = Request( + url = url, + headers = headers, + body = body + ) + assertThat(request.url).isEqualTo(url) + assertThat(request.headers).isEqualTo(headers) + assertThat(request.method).isEqualTo("POST") + assertThat(request.body).isEqualTo(body) + assertThat(request.tags).isEmpty() + } + + @Test + fun constructorNoBody() { + val url = "https://example.com/".toHttpUrl() + val headers = headersOf("User-Agent", "RequestTest") + val method = "DELETE" + val request = Request( + url = url, + headers = headers, + method = method, + ) + assertThat(request.url).isEqualTo(url) + assertThat(request.headers).isEqualTo(headers) + assertThat(request.method).isEqualTo(method) + assertThat(request.body).isNull() + assertThat(request.tags).isEmpty() + } + + @Test + fun string() { + val contentType = "text/plain; charset=utf-8".toMediaType() + val body = "abc".toByteArray().toRequestBody(contentType) + assertThat(body.contentType()).isEqualTo(contentType) + assertThat(body.contentLength()).isEqualTo(3) + assertThat(bodyToHex(body)).isEqualTo("616263") + assertThat(bodyToHex(body)) + .overridingErrorMessage("Retransmit body") + .isEqualTo("616263") + } + + @Test + fun stringWithDefaultCharsetAdded() { + val contentType = "text/plain".toMediaType() + val body = "\u0800".toRequestBody(contentType) + assertThat(body.contentType()).isEqualTo("text/plain; charset=utf-8".toMediaType()) + assertThat(body.contentLength()).isEqualTo(3) + assertThat(bodyToHex(body)).isEqualTo("e0a080") + } + + @Test + fun stringWithNonDefaultCharsetSpecified() { + val contentType = "text/plain; charset=utf-16be".toMediaType() + val body = "\u0800".toRequestBody(contentType) + assertThat(body.contentType()).isEqualTo(contentType) + assertThat(body.contentLength()).isEqualTo(2) + assertThat(bodyToHex(body)).isEqualTo("0800") + } + + @Test + fun byteArray() { + val contentType = "text/plain".toMediaType() + val body: RequestBody = "abc".toByteArray().toRequestBody(contentType) + assertThat(body.contentType()).isEqualTo(contentType) + assertThat(body.contentLength()).isEqualTo(3) + assertThat(bodyToHex(body)).isEqualTo("616263") + assertThat(bodyToHex(body)) + .overridingErrorMessage("Retransmit body") + .isEqualTo("616263") + } + + @Test + fun byteArrayRange() { + val contentType = "text/plain".toMediaType() + val body: RequestBody = ".abcd".toByteArray().toRequestBody(contentType, 1, 3) + assertThat(body.contentType()).isEqualTo(contentType) + assertThat(body.contentLength()).isEqualTo(3) + assertThat(bodyToHex(body)).isEqualTo("616263") + assertThat(bodyToHex(body)) + .overridingErrorMessage("Retransmit body") + .isEqualTo("616263") + } + + @Test + fun byteString() { + val contentType = "text/plain".toMediaType() + val body: RequestBody = "Hello".encodeUtf8().toRequestBody(contentType) + assertThat(body.contentType()).isEqualTo(contentType) + assertThat(body.contentLength()).isEqualTo(5) + assertThat(bodyToHex(body)).isEqualTo("48656c6c6f") + assertThat(bodyToHex(body)) + .overridingErrorMessage("Retransmit body") + .isEqualTo("48656c6c6f") + } + + @Test + fun file() { + val file = File.createTempFile("RequestTest", "tmp") + val writer = FileWriter(file) + writer.write("abc") + writer.close() + val contentType = "text/plain".toMediaType() + val body: RequestBody = file.asRequestBody(contentType) + assertThat(body.contentType()).isEqualTo(contentType) + assertThat(body.contentLength()).isEqualTo(3) + assertThat(bodyToHex(body)).isEqualTo("616263") + assertThat(bodyToHex(body)) + .overridingErrorMessage("Retransmit body") + .isEqualTo("616263") + } + + /** Common verbs used for apis such as GitHub, AWS, and Google Cloud. */ + @Test + fun crudVerbs() { + val contentType = "application/json".toMediaType() + val body = "{}".toRequestBody(contentType) + + val get = Request.Builder().url("http://localhost/api").get().build() + assertThat(get.method).isEqualTo("GET") + assertThat(get.body).isNull() + + val head = Request.Builder().url("http://localhost/api").head().build() + assertThat(head.method).isEqualTo("HEAD") + assertThat(head.body).isNull() + + val delete = Request.Builder().url("http://localhost/api").delete().build() + assertThat(delete.method).isEqualTo("DELETE") + assertThat(delete.body!!.contentLength()).isEqualTo(0L) + + val post = Request.Builder().url("http://localhost/api").post(body).build() + assertThat(post.method).isEqualTo("POST") + assertThat(post.body).isEqualTo(body) + + val put = Request.Builder().url("http://localhost/api").put(body).build() + assertThat(put.method).isEqualTo("PUT") + assertThat(put.body).isEqualTo(body) + + val patch = Request.Builder().url("http://localhost/api").patch(body).build() + assertThat(patch.method).isEqualTo("PATCH") + assertThat(patch.body).isEqualTo(body) + } + + @Test + fun uninitializedURI() { + val request = Request.Builder().url("http://localhost/api").build() + assertThat(request.url.toUri()).isEqualTo(URI("http://localhost/api")) + assertThat(request.url).isEqualTo("http://localhost/api".toHttpUrl()) + } + + @Test + fun newBuilderUrlResetsUrl() { + val requestWithoutCache = Request.Builder().url("http://localhost/api").build() + val builtRequestWithoutCache = requestWithoutCache.newBuilder().url("http://localhost/api/foo").build() + assertThat(builtRequestWithoutCache.url).isEqualTo( + "http://localhost/api/foo".toHttpUrl()) + val requestWithCache = Request.Builder() + .url("http://localhost/api") + .build() + // cache url object + requestWithCache.url + val builtRequestWithCache = requestWithCache.newBuilder() + .url("http://localhost/api/foo") + .build() + assertThat(builtRequestWithCache.url) + .isEqualTo("http://localhost/api/foo".toHttpUrl()) + } + + @Test + fun cacheControl() { + val request = Request.Builder() + .cacheControl(CacheControl.Builder().noCache().build()) + .url("https://square.com") + .build() + assertThat(request.headers("Cache-Control")).containsExactly("no-cache") + assertThat(request.cacheControl.noCache).isTrue + } + + @Test + fun emptyCacheControlClearsAllCacheControlHeaders() { + val request = Request.Builder() + .header("Cache-Control", "foo") + .cacheControl(CacheControl.Builder().build()) + .url("https://square.com") + .build() + assertThat(request.headers("Cache-Control")).isEmpty() + } + + @Test + fun headerAcceptsPermittedCharacters() { + val builder = Request.Builder() + builder.header("AZab09~", "AZab09 ~") + builder.addHeader("AZab09~", "AZab09 ~") + } + + @Test + fun emptyNameForbidden() { + val builder = Request.Builder() + try { + builder.header("", "Value") + fail("") + } catch (expected: IllegalArgumentException) { + } + try { + builder.addHeader("", "Value") + fail("") + } catch (expected: IllegalArgumentException) { + } + } + + @Test + fun headerAllowsTabOnlyInValues() { + val builder = Request.Builder() + builder.header("key", "sample\tvalue") + try { + builder.header("sample\tkey", "value") + fail("") + } catch (expected: IllegalArgumentException) { + } + } + + @Test + fun headerForbidsControlCharacters() { + assertForbiddenHeader("\u0000") + assertForbiddenHeader("\r") + assertForbiddenHeader("\n") + assertForbiddenHeader("\u001f") + assertForbiddenHeader("\u007f") + assertForbiddenHeader("\u0080") + assertForbiddenHeader("\ud83c\udf69") + } + + private fun assertForbiddenHeader(s: String) { + val builder = Request.Builder() + try { + builder.header(s, "Value") + fail("") + } catch (expected: IllegalArgumentException) { + } + try { + builder.addHeader(s, "Value") + fail("") + } catch (expected: IllegalArgumentException) { + } + try { + builder.header("Name", s) + fail("") + } catch (expected: IllegalArgumentException) { + } + try { + builder.addHeader("Name", s) + fail("") + } catch (expected: IllegalArgumentException) { + } + } + + @Test + fun noTag() { + val request = Request.Builder() + .url("https://square.com") + .build() + assertThat(request.tag()).isNull() + assertThat(request.tag(Any::class.java)).isNull() + assertThat(request.tag(UUID::class.java)).isNull() + assertThat(request.tag(String::class.java)).isNull() + } + + @Test + fun defaultTag() { + val tag = UUID.randomUUID() + val request = Request.Builder() + .url("https://square.com") + .tag(tag) + .build() + assertThat(request.tag()).isSameAs(tag) + assertThat(request.tag(Any::class.java)).isSameAs(tag) + assertThat(request.tag(UUID::class.java)).isNull() + assertThat(request.tag(String::class.java)).isNull() + } + + @Test + fun nullRemovesTag() { + val request = Request.Builder() + .url("https://square.com") + .tag("a") + .tag(null) + .build() + assertThat(request.tag()).isNull() + } + + @Test + fun removeAbsentTag() { + val request = Request.Builder() + .url("https://square.com") + .tag(null) + .build() + assertThat(request.tag()).isNull() + } + + @Test + fun objectTag() { + val tag = UUID.randomUUID() + val request = Request.Builder() + .url("https://square.com") + .tag(Any::class.java, tag) + .build() + assertThat(request.tag()).isSameAs(tag) + assertThat(request.tag(Any::class.java)).isSameAs(tag) + assertThat(request.tag(UUID::class.java)).isNull() + assertThat(request.tag(String::class.java)).isNull() + } + + @Test + fun typedTag() { + val uuidTag = UUID.randomUUID() + val request = Request.Builder() + .url("https://square.com") + .tag(UUID::class.java, uuidTag) + .build() + assertThat(request.tag()).isNull() + assertThat(request.tag(Any::class.java)).isNull() + assertThat(request.tag(UUID::class.java)).isSameAs(uuidTag) + assertThat(request.tag(String::class.java)).isNull() + } + + @Test + fun replaceOnlyTag() { + val uuidTag1 = UUID.randomUUID() + val uuidTag2 = UUID.randomUUID() + val request = Request.Builder() + .url("https://square.com") + .tag(UUID::class.java, uuidTag1) + .tag(UUID::class.java, uuidTag2) + .build() + assertThat(request.tag(UUID::class.java)).isSameAs(uuidTag2) + } + + @Test + fun multipleTags() { + val uuidTag = UUID.randomUUID() + val stringTag = "dilophosaurus" + val longTag = 20170815L as Long? + val objectTag = Any() + val request = Request.Builder() + .url("https://square.com") + .tag(Any::class.java, objectTag) + .tag(UUID::class.java, uuidTag) + .tag(String::class.java, stringTag) + .tag(Long::class.javaObjectType, longTag) + .build() + assertThat(request.tag()).isSameAs(objectTag) + assertThat(request.tag(Any::class.java)).isSameAs(objectTag) + assertThat(request.tag(UUID::class.java)).isSameAs(uuidTag) + assertThat(request.tag(String::class.java)).isSameAs(stringTag) + assertThat(request.tag(Long::class.javaObjectType)).isSameAs(longTag) + } + + /** Confirm that we don't accidentally share the backing map between objects. */ + @Test + fun tagsAreImmutable() { + val builder = Request.Builder() + .url("https://square.com") + val requestA = builder.tag(String::class.java, "a").build() + val requestB = builder.tag(String::class.java, "b").build() + val requestC = requestA.newBuilder().tag(String::class.java, "c").build() + assertThat(requestA.tag(String::class.java)).isSameAs("a") + assertThat(requestB.tag(String::class.java)).isSameAs("b") + assertThat(requestC.tag(String::class.java)).isSameAs("c") + } + + private fun bodyToHex(body: RequestBody): String { + val buffer = Buffer() + body.writeTo(buffer) + return buffer.readByteString().hex() + } +} diff --git a/okhttp/src/jvmTest/java/okhttp3/ServerTruncatesRequestTest.kt b/okhttp/src/jvmTest/java/okhttp3/ServerTruncatesRequestTest.kt index e18112a30..b76ccc0f8 100644 --- a/okhttp/src/jvmTest/java/okhttp3/ServerTruncatesRequestTest.kt +++ b/okhttp/src/jvmTest/java/okhttp3/ServerTruncatesRequestTest.kt @@ -73,10 +73,10 @@ class ServerTruncatesRequestTest( .apply { this.http2ErrorCode = ErrorCode.NO_ERROR.httpCode }) val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .post(SlowRequestBody) - .build() + Request( + url = server.url("/"), + body = SlowRequestBody, + ) ) call.execute().use { response -> @@ -129,10 +129,10 @@ class ServerTruncatesRequestTest( val requestBody = AsyncRequestBody() val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .post(requestBody) - .build() + Request( + url = server.url("/"), + body = requestBody, + ) ) call.execute().use { response -> @@ -181,10 +181,10 @@ class ServerTruncatesRequestTest( server.enqueue(mockResponse) val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .post(SlowRequestBody) - .build() + Request( + url = server.url("/"), + body = SlowRequestBody, + ) ) call.execute().use { response -> @@ -216,11 +216,7 @@ class ServerTruncatesRequestTest( } val localClient = client.newBuilder().eventListener(eventListener).build() - val call1 = localClient.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call1 = localClient.newCall(Request(server.url("/"))) call1.execute().use { response -> assertThat(response.body.string()).isEqualTo("Req1") @@ -230,11 +226,7 @@ class ServerTruncatesRequestTest( eventListener.closed = true - val call2 = localClient.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call2 = localClient.newCall(Request(server.url("/"))) assertThrows("fake socket failure") { call2.execute() @@ -253,10 +245,10 @@ class ServerTruncatesRequestTest( } val callA = client.newCall( - Request.Builder() - .url(server.url("/")) - .post(requestBody) - .build() + Request( + url = server.url("/"), + body = requestBody, + ) ) try { @@ -270,11 +262,7 @@ class ServerTruncatesRequestTest( // Confirm that the connection pool was not corrupted by making another call. This doesn't use // makeSimpleCall() because it uses the MockResponse enqueued above. - val callB = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val callB = client.newCall(Request(server.url("/"))) callB.execute().use { response -> assertThat(response.body.string()).isEqualTo("abc") } @@ -282,11 +270,7 @@ class ServerTruncatesRequestTest( private fun makeSimpleCall() { server.enqueue(MockResponse().setBody("healthy")) - val callB = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val callB = client.newCall(Request(server.url("/"))) callB.execute().use { response -> assertThat(response.body.string()).isEqualTo("healthy") } diff --git a/okhttp/src/jvmTest/java/okhttp3/SessionReuseTest.kt b/okhttp/src/jvmTest/java/okhttp3/SessionReuseTest.kt index a29722add..7b0a8e507 100644 --- a/okhttp/src/jvmTest/java/okhttp3/SessionReuseTest.kt +++ b/okhttp/src/jvmTest/java/okhttp3/SessionReuseTest.kt @@ -95,7 +95,7 @@ class SessionReuseTest( server.enqueue(MockResponse().setBody("abc1")) server.enqueue(MockResponse().setBody("abc2")) - val request = Request.Builder().url(server.url("/")).build() + val request = Request(server.url("/")) client.newCall(request).execute().use { response -> assertEquals(200, response.code) diff --git a/okhttp/src/jvmTest/java/okhttp3/URLConnectionTest.kt b/okhttp/src/jvmTest/java/okhttp3/URLConnectionTest.kt index 53044d1e1..ff1e5a84e 100644 --- a/okhttp/src/jvmTest/java/okhttp3/URLConnectionTest.kt +++ b/okhttp/src/jvmTest/java/okhttp3/URLConnectionTest.kt @@ -104,14 +104,16 @@ class URLConnectionTest { private var client = clientTestRule.newClient() private var cache: Cache? = null - @BeforeEach fun setUp(server: MockWebServer, server2: MockWebServer) { + @BeforeEach + fun setUp(server: MockWebServer, server2: MockWebServer) { this.server = server this.server2 = server2 platform.assumeNotBouncyCastle() server.protocolNegotiationEnabled = false } - @AfterEach fun tearDown() { + @AfterEach + fun tearDown() { java.net.Authenticator.setDefault(null) System.clearProperty("proxyHost") System.clearProperty("proxyPort") @@ -124,7 +126,8 @@ class URLConnectionTest { } } - @Test fun requestHeaders() { + @Test + fun requestHeaders() { server.enqueue(MockResponse()) val request = Request.Builder() .url(server.url("/")) @@ -144,7 +147,8 @@ class URLConnectionTest { assertThat(recordedRequest.getHeader("null")).isNull() } - @Test fun getRequestPropertyReturnsLastValue() { + @Test + fun getRequestPropertyReturnsLastValue() { val request = Request.Builder() .url(server.url("/")) .addHeader("A", "value1") @@ -153,7 +157,8 @@ class URLConnectionTest { assertThat(request.header("A")).isEqualTo("value2") } - @Test fun responseHeaders() { + @Test + fun responseHeaders() { server.enqueue( MockResponse() .setStatus("HTTP/1.0 200 Fantastic") @@ -178,7 +183,8 @@ class URLConnectionTest { response.body.close() } - @Test fun serverSendsInvalidStatusLine() { + @Test + fun serverSendsInvalidStatusLine() { server.enqueue(MockResponse().setStatus("HTP/1.1 200 OK")) val request = newRequest("/") try { @@ -188,7 +194,8 @@ class URLConnectionTest { } } - @Test fun serverSendsInvalidCodeTooLarge() { + @Test + fun serverSendsInvalidCodeTooLarge() { server.enqueue(MockResponse().setStatus("HTTP/1.1 2147483648 OK")) val request = newRequest("/") try { @@ -198,7 +205,8 @@ class URLConnectionTest { } } - @Test fun serverSendsInvalidCodeNotANumber() { + @Test + fun serverSendsInvalidCodeNotANumber() { server.enqueue(MockResponse().setStatus("HTTP/1.1 00a OK")) val request = newRequest("/") try { @@ -208,7 +216,8 @@ class URLConnectionTest { } } - @Test fun serverSendsUnnecessaryWhitespace() { + @Test + fun serverSendsUnnecessaryWhitespace() { server.enqueue(MockResponse().setStatus(" HTTP/1.1 2147483648 OK")) val request = newRequest("/") try { @@ -218,7 +227,8 @@ class URLConnectionTest { } } - @Test fun connectRetriesUntilConnectedOrFailed() { + @Test + fun connectRetriesUntilConnectedOrFailed() { val request = newRequest("/foo") server.shutdown() try { @@ -228,11 +238,13 @@ class URLConnectionTest { } } - @Test fun requestBodySurvivesRetriesWithFixedLength() { + @Test + fun requestBodySurvivesRetriesWithFixedLength() { testRequestBodySurvivesRetries(TransferKind.FIXED_LENGTH) } - @Test fun requestBodySurvivesRetriesWithChunkedStreaming() { + @Test + fun requestBodySurvivesRetriesWithChunkedStreaming() { testRequestBodySurvivesRetries(TransferKind.CHUNKED) } @@ -251,10 +263,10 @@ class URLConnectionTest { ) .build() server2.shutdown() - val request = Request.Builder() - .url(server.url("/def")) - .post(transferKind.newRequestBody("body")) - .build() + val request = Request( + url = server.url("/def"), + body = transferKind.newRequestBody("body"), + ) val response = getResponse(request) assertContent("abc", response) assertThat(server.takeRequest().body.readUtf8()).isEqualTo("body") @@ -263,7 +275,8 @@ class URLConnectionTest { // Check that if we don't read to the end of a response, the next request on the // recycled connection doesn't get the unread tail of the first request's response. // http://code.google.com/p/android/issues/detail?id=2939 - @Test fun bug2939() { + @Test + fun bug2939() { val response = MockResponse() .setChunkedBody("ABCDE\nFGHIJ\nKLMNO\nPQR", 8) server.enqueue(response) @@ -277,7 +290,8 @@ class URLConnectionTest { c2.close() } - @Test fun connectionsArePooled() { + @Test + fun connectionsArePooled() { val response = MockResponse() .setBody("ABCDEFGHIJKLMNOPQR") server.enqueue(response) @@ -291,7 +305,8 @@ class URLConnectionTest { assertThat(server.takeRequest().sequenceNumber).isEqualTo(2) } - @Test fun chunkedConnectionsArePooled() { + @Test + fun chunkedConnectionsArePooled() { val response = MockResponse() .setChunkedBody("ABCDEFGHIJKLMNOPQR", 5) server.enqueue(response) @@ -305,19 +320,23 @@ class URLConnectionTest { assertThat(server.takeRequest().sequenceNumber).isEqualTo(2) } - @Test fun serverClosesSocket() { + @Test + fun serverClosesSocket() { testServerClosesOutput(SocketPolicy.DISCONNECT_AT_END) } - @Test fun serverShutdownInput() { + @Test + fun serverShutdownInput() { testServerClosesOutput(SocketPolicy.SHUTDOWN_INPUT_AT_END) } - @Test fun serverShutdownOutput() { + @Test + fun serverShutdownOutput() { testServerClosesOutput(SocketPolicy.SHUTDOWN_OUTPUT_AT_END) } - @Test fun invalidHost() { + @Test + fun invalidHost() { // Note that 1234.1.1.1 is an invalid host in a URI, but URL isn't as strict. client = client.newBuilder() .dns(FakeDns()) @@ -373,27 +392,33 @@ class URLConnectionTest { LARGE_BUFFERS } - @Test fun chunkedUpload_byteByByte() { + @Test + fun chunkedUpload_byteByByte() { doUpload(TransferKind.CHUNKED, WriteKind.BYTE_BY_BYTE) } - @Test fun chunkedUpload_smallBuffers() { + @Test + fun chunkedUpload_smallBuffers() { doUpload(TransferKind.CHUNKED, WriteKind.SMALL_BUFFERS) } - @Test fun chunkedUpload_largeBuffers() { + @Test + fun chunkedUpload_largeBuffers() { doUpload(TransferKind.CHUNKED, WriteKind.LARGE_BUFFERS) } - @Test fun fixedLengthUpload_byteByByte() { + @Test + fun fixedLengthUpload_byteByByte() { doUpload(TransferKind.FIXED_LENGTH, WriteKind.BYTE_BY_BYTE) } - @Test fun fixedLengthUpload_smallBuffers() { + @Test + fun fixedLengthUpload_smallBuffers() { doUpload(TransferKind.FIXED_LENGTH, WriteKind.SMALL_BUFFERS) } - @Test fun fixedLengthUpload_largeBuffers() { + @Test + fun fixedLengthUpload_largeBuffers() { doUpload(TransferKind.FIXED_LENGTH, WriteKind.LARGE_BUFFERS) } @@ -427,10 +452,10 @@ class URLConnectionTest { } } val response = getResponse( - Request.Builder() - .url(server.url("/")) - .post(requestBody) - .build() + Request( + url = server.url("/"), + body = requestBody, + ) ) assertThat(response.code).isEqualTo(200) val request = server.takeRequest() @@ -442,7 +467,8 @@ class URLConnectionTest { } } - @Test fun connectViaHttps() { + @Test + fun connectViaHttps() { server.useHttps(handshakeCertificates.sslSocketFactory(), false) server.enqueue( MockResponse() @@ -460,11 +486,13 @@ class URLConnectionTest { assertThat(request.requestLine).isEqualTo("GET /foo HTTP/1.1") } - @Test fun connectViaHttpsReusingConnections() { + @Test + fun connectViaHttpsReusingConnections() { connectViaHttpsReusingConnections(false) } - @Test fun connectViaHttpsReusingConnectionsAfterRebuildingClient() { + @Test + fun connectViaHttpsReusingConnectionsAfterRebuildingClient() { connectViaHttpsReusingConnections(true) } @@ -508,7 +536,8 @@ class URLConnectionTest { assertThat(server.takeRequest().sequenceNumber).isEqualTo(1) } - @Test fun connectViaHttpsReusingConnectionsDifferentFactories() { + @Test + fun connectViaHttpsReusingConnectionsDifferentFactories() { server.useHttps(handshakeCertificates.sslSocketFactory(), false) server.enqueue( MockResponse() @@ -550,7 +579,8 @@ class URLConnectionTest { } // TODO(jwilson): tests below this marker need to be migrated to OkHttp's request/response API. - @Test fun connectViaHttpsWithSSLFallback() { + @Test + fun connectViaHttpsWithSSLFallback() { server.useHttps(handshakeCertificates.sslSocketFactory(), false) server.enqueue( MockResponse() @@ -578,7 +608,8 @@ class URLConnectionTest { assertThat(fallbackRequest.tlsVersion).isIn(TlsVersion.TLS_1_2, TlsVersion.TLS_1_3) } - @Test fun connectViaHttpsWithSSLFallbackFailuresRecorded() { + @Test + fun connectViaHttpsWithSSLFallbackFailuresRecorded() { server.useHttps(handshakeCertificates.sslSocketFactory(), false) server.enqueue( MockResponse() @@ -612,7 +643,8 @@ class URLConnectionTest { * * https://github.com/square/okhttp/issues/515 */ - @Test fun sslFallbackNotUsedWhenRecycledConnectionFails() { + @Test + fun sslFallbackNotUsedWhenRecycledConnectionFails() { server.useHttps(handshakeCertificates.sslSocketFactory(), false) server.enqueue( MockResponse() @@ -649,7 +681,9 @@ class URLConnectionTest { * * http://code.google.com/p/android/issues/detail?id=13178 */ - @Flaky @Test fun connectViaHttpsToUntrustedServer() { + @Flaky + @Test + fun connectViaHttpsToUntrustedServer() { // Flaky https://github.com/square/okhttp/issues/5222 server.useHttps(handshakeCertificates.sslSocketFactory(), false) server.enqueue(MockResponse()) // unused @@ -667,15 +701,18 @@ class URLConnectionTest { assertThat(server.requestCount).isEqualTo(0) } - @Test fun connectViaProxyUsingProxyArg() { + @Test + fun connectViaProxyUsingProxyArg() { testConnectViaProxy(ProxyConfig.CREATE_ARG) } - @Test fun connectViaProxyUsingProxySystemProperty() { + @Test + fun connectViaProxyUsingProxySystemProperty() { testConnectViaProxy(ProxyConfig.PROXY_SYSTEM_PROPERTY) } - @Test fun connectViaProxyUsingHttpProxySystemProperty() { + @Test + fun connectViaProxyUsingHttpProxySystemProperty() { testConnectViaProxy(ProxyConfig.HTTP_PROXY_SYSTEM_PROPERTY) } @@ -693,7 +730,8 @@ class URLConnectionTest { assertThat(request.getHeader("Host")).isEqualTo("android.com") } - @Test fun contentDisagreesWithContentLengthHeaderBodyTooLong() { + @Test + fun contentDisagreesWithContentLengthHeaderBodyTooLong() { server.enqueue( MockResponse() .setBody("abc\r\nYOU SHOULD NOT SEE THIS") @@ -703,7 +741,8 @@ class URLConnectionTest { assertContent("abc", getResponse(newRequest("/"))) } - @Test fun contentDisagreesWithContentLengthHeaderBodyTooShort() { + @Test + fun contentDisagreesWithContentLengthHeaderBodyTooShort() { server.enqueue( MockResponse() .setBody("abc") @@ -770,15 +809,18 @@ class URLConnectionTest { assertThat(response.code).isEqualTo(200) } - @Test fun connectHttpViaSocketFactory() { + @Test + fun connectHttpViaSocketFactory() { testConnectViaSocketFactory(false) } - @Test fun connectHttpsViaSocketFactory() { + @Test + fun connectHttpsViaSocketFactory() { testConnectViaSocketFactory(true) } - @Test fun contentDisagreesWithChunkedHeaderBodyTooLong() { + @Test + fun contentDisagreesWithChunkedHeaderBodyTooLong() { val mockResponse = MockResponse() .setChunkedBody("abc", 3) val buffer = mockResponse.getBody() @@ -790,7 +832,8 @@ class URLConnectionTest { assertContent("abc", getResponse(newRequest("/"))) } - @Test fun contentDisagreesWithChunkedHeaderBodyTooShort() { + @Test + fun contentDisagreesWithChunkedHeaderBodyTooShort() { val mockResponse = MockResponse() .setChunkedBody("abcdefg", 5) val truncatedBody = Buffer() @@ -809,11 +852,13 @@ class URLConnectionTest { } } - @Test fun connectViaHttpProxyToHttpsUsingProxyArgWithNoProxy() { + @Test + fun connectViaHttpProxyToHttpsUsingProxyArgWithNoProxy() { testConnectViaDirectProxyToHttps(ProxyConfig.NO_PROXY) } - @Test fun connectViaHttpProxyToHttpsUsingHttpProxySystemProperty() { + @Test + fun connectViaHttpProxyToHttpsUsingHttpProxySystemProperty() { // https should not use http proxy testConnectViaDirectProxyToHttps(ProxyConfig.HTTP_PROXY_SYSTEM_PROPERTY) } @@ -837,7 +882,8 @@ class URLConnectionTest { assertThat(request.requestLine).isEqualTo("GET /foo HTTP/1.1") } - @Test fun connectViaHttpProxyToHttpsUsingProxyArg() { + @Test + fun connectViaHttpProxyToHttpsUsingProxyArg() { testConnectViaHttpProxyToHttps(ProxyConfig.CREATE_ARG) } @@ -845,11 +891,13 @@ class URLConnectionTest { * We weren't honoring all of the appropriate proxy system properties when connecting via HTTPS. * http://b/3097518 */ - @Test fun connectViaHttpProxyToHttpsUsingProxySystemProperty() { + @Test + fun connectViaHttpProxyToHttpsUsingProxySystemProperty() { testConnectViaHttpProxyToHttps(ProxyConfig.PROXY_SYSTEM_PROPERTY) } - @Test fun connectViaHttpProxyToHttpsUsingHttpsProxySystemProperty() { + @Test + fun connectViaHttpProxyToHttpsUsingHttpsProxySystemProperty() { testConnectViaHttpProxyToHttps(ProxyConfig.HTTPS_PROXY_SYSTEM_PROPERTY) } @@ -892,7 +940,8 @@ class URLConnectionTest { } /** Tolerate bad https proxy response when using HttpResponseCache. Android bug 6754912. */ - @Test fun connectViaHttpProxyToHttpsUsingBadProxyAndHttpResponseCache() { + @Test + fun connectViaHttpProxyToHttpsUsingBadProxyAndHttpResponseCache() { initResponseCache() server.useHttps(handshakeCertificates.sslSocketFactory(), true) // The inclusion of a body in the response to a CONNECT is key to reproducing b/6754912. @@ -936,7 +985,8 @@ class URLConnectionTest { } /** Test which headers are sent unencrypted to the HTTP proxy. */ - @Test fun proxyConnectIncludesProxyHeadersOnly() { + @Test + fun proxyConnectIncludesProxyHeadersOnly() { val hostnameVerifier = RecordingHostnameVerifier() server.useHttps(handshakeCertificates.sslSocketFactory(), true) server.enqueue( @@ -975,7 +1025,8 @@ class URLConnectionTest { assertThat(hostnameVerifier.calls).isEqualTo(listOf("verify android.com")) } - @Test fun proxyAuthenticateOnConnect() { + @Test + fun proxyAuthenticateOnConnect() { java.net.Authenticator.setDefault(RecordingAuthenticator()) server.useHttps(handshakeCertificates.sslSocketFactory(), true) server.enqueue( @@ -1020,7 +1071,8 @@ class URLConnectionTest { // Don't disconnect after building a tunnel with CONNECT // http://code.google.com/p/android/issues/detail?id=37221 - @Test fun proxyWithConnectionClose() { + @Test + fun proxyWithConnectionClose() { server.useHttps(handshakeCertificates.sslSocketFactory(), true) server.enqueue( MockResponse() @@ -1047,7 +1099,8 @@ class URLConnectionTest { assertContent("this response comes via a proxy", response) } - @Test fun proxyWithConnectionReuse() { + @Test + fun proxyWithConnectionReuse() { val socketFactory = handshakeCertificates.sslSocketFactory() val hostnameVerifier = RecordingHostnameVerifier() server.useHttps(socketFactory, true) @@ -1069,11 +1122,12 @@ class URLConnectionTest { .sslSocketFactory(socketFactory, handshakeCertificates.trustManager) .hostnameVerifier(hostnameVerifier) .build() - assertContent("response 1", getResponse(newRequest("https://android.com/foo".toHttpUrl()))) - assertContent("response 2", getResponse(newRequest("https://android.com/foo".toHttpUrl()))) + assertContent("response 1", getResponse(Request("https://android.com/foo".toHttpUrl()))) + assertContent("response 2", getResponse(Request("https://android.com/foo".toHttpUrl()))) } - @Test fun proxySelectorHttpWithConnectionReuse() { + @Test + fun proxySelectorHttpWithConnectionReuse() { server.enqueue( MockResponse() .setBody("response 1") @@ -1089,11 +1143,12 @@ class URLConnectionTest { } }).build() val url = "http://android.com/foo".toHttpUrl() - assertContent("response 1", getResponse(newRequest(url))) - assertThat(getResponse(newRequest(url)).code).isEqualTo(407) + assertContent("response 1", getResponse(Request(url))) + assertThat(getResponse(Request(url)).code).isEqualTo(407) } - @Test fun disconnectedConnection() { + @Test + fun disconnectedConnection() { server.enqueue( MockResponse() .throttleBody(2, 100, TimeUnit.MILLISECONDS) @@ -1116,7 +1171,8 @@ class URLConnectionTest { inputStream.close() } - @Test fun disconnectDuringConnect_cookieJar() { + @Test + fun disconnectDuringConnect_cookieJar() { val callReference = AtomicReference() class DisconnectingCookieJar : CookieJar { @@ -1139,7 +1195,8 @@ class URLConnectionTest { } } - @Test fun disconnectBeforeConnect() { + @Test + fun disconnectBeforeConnect() { server.enqueue( MockResponse() .setBody("A") @@ -1153,7 +1210,8 @@ class URLConnectionTest { } } - @Test fun defaultRequestProperty() { + @Test + fun defaultRequestProperty() { URLConnection.setDefaultRequestProperty("X-testSetDefaultRequestProperty", "A") assertThat(URLConnection.getDefaultRequestProperty("X-setDefaultRequestProperty")).isNull() } @@ -1175,15 +1233,18 @@ class URLConnectionTest { return result.toString() } - @Test fun markAndResetWithContentLengthHeader() { + @Test + fun markAndResetWithContentLengthHeader() { testMarkAndReset(TransferKind.FIXED_LENGTH) } - @Test fun markAndResetWithChunkedEncoding() { + @Test + fun markAndResetWithChunkedEncoding() { testMarkAndReset(TransferKind.CHUNKED) } - @Test fun markAndResetWithNoLengthHeaders() { + @Test + fun markAndResetWithNoLengthHeaders() { testMarkAndReset(TransferKind.END_OF_STREAM) } @@ -1214,7 +1275,8 @@ class URLConnectionTest { * We've had a bug where we forget the HTTP response when we see response code 401. This causes a * new HTTP request to be issued for every call into the URLConnection. */ - @Test fun unauthorizedResponseHandling() { + @Test + fun unauthorizedResponseHandling() { val mockResponse = MockResponse() .addHeader("WWW-Authenticate: challenge") .setResponseCode(HttpURLConnection.HTTP_UNAUTHORIZED) @@ -1230,7 +1292,8 @@ class URLConnectionTest { response.body.close() } - @Test fun nonHexChunkSize() { + @Test + fun nonHexChunkSize() { server.enqueue( MockResponse() .setBody("5\r\nABCDE\r\nG\r\nFGHIJKLMNOPQRSTU\r\n0\r\n\r\n") @@ -1246,7 +1309,8 @@ class URLConnectionTest { } } - @Test fun malformedChunkSize() { + @Test + fun malformedChunkSize() { server.enqueue( MockResponse() .setBody("5:x\r\nABCDE\r\n0\r\n\r\n") @@ -1262,7 +1326,8 @@ class URLConnectionTest { } } - @Test fun extensionAfterChunkSize() { + @Test + fun extensionAfterChunkSize() { server.enqueue( MockResponse() .setBody("5;x\r\nABCDE\r\n0\r\n\r\n") @@ -1272,7 +1337,8 @@ class URLConnectionTest { getResponse(newRequest("/")).use { response -> assertContent("ABCDE", response) } } - @Test fun missingChunkBody() { + @Test + fun missingChunkBody() { server.enqueue( MockResponse() .setBody("5") @@ -1293,7 +1359,8 @@ class URLConnectionTest { * This test checks whether connections are gzipped by default. This behavior in not required by * the API, so a failure of this test does not imply a bug in the implementation. */ - @Test fun gzipEncodingEnabledByDefault() { + @Test + fun gzipEncodingEnabledByDefault() { server.enqueue( MockResponse() .setBody(gzip("ABCABCABC")) @@ -1309,7 +1376,8 @@ class URLConnectionTest { assertThat(request.getHeader("Accept-Encoding")).isEqualTo("gzip") } - @Test fun clientConfiguredGzipContentEncoding() { + @Test + fun clientConfiguredGzipContentEncoding() { val bodyBytes = gzip("ABCDEFGHIJKLMNOPQRSTUVWXYZ") server.enqueue( MockResponse() @@ -1329,23 +1397,28 @@ class URLConnectionTest { assertThat(request.getHeader("Accept-Encoding")).isEqualTo("gzip") } - @Test fun gzipAndConnectionReuseWithFixedLength() { + @Test + fun gzipAndConnectionReuseWithFixedLength() { testClientConfiguredGzipContentEncodingAndConnectionReuse(TransferKind.FIXED_LENGTH, false) } - @Test fun gzipAndConnectionReuseWithChunkedEncoding() { + @Test + fun gzipAndConnectionReuseWithChunkedEncoding() { testClientConfiguredGzipContentEncodingAndConnectionReuse(TransferKind.CHUNKED, false) } - @Test fun gzipAndConnectionReuseWithFixedLengthAndTls() { + @Test + fun gzipAndConnectionReuseWithFixedLengthAndTls() { testClientConfiguredGzipContentEncodingAndConnectionReuse(TransferKind.FIXED_LENGTH, true) } - @Test fun gzipAndConnectionReuseWithChunkedEncodingAndTls() { + @Test + fun gzipAndConnectionReuseWithChunkedEncodingAndTls() { testClientConfiguredGzipContentEncodingAndConnectionReuse(TransferKind.CHUNKED, true) } - @Test fun clientConfiguredCustomContentEncoding() { + @Test + fun clientConfiguredCustomContentEncoding() { server.enqueue( MockResponse() .setBody("ABCDE") @@ -1405,7 +1478,8 @@ class URLConnectionTest { assertThat(server.takeRequest().sequenceNumber).isEqualTo(1) } - @Test fun transparentGzipWorksAfterExceptionRecovery() { + @Test + fun transparentGzipWorksAfterExceptionRecovery() { server.enqueue( MockResponse() .setBody("a") @@ -1430,7 +1504,8 @@ class URLConnectionTest { assertThat(server.takeRequest().sequenceNumber).isEqualTo(0) } - @Test fun endOfStreamResponseIsNotPooled() { + @Test + fun endOfStreamResponseIsNotPooled() { client.connectionPool.evictAll() server.enqueue( MockResponse() @@ -1443,11 +1518,13 @@ class URLConnectionTest { assertThat(client.connectionPool.idleConnectionCount()).isEqualTo(0) } - @Test fun earlyDisconnectDoesntHarmPoolingWithChunkedEncoding() { + @Test + fun earlyDisconnectDoesntHarmPoolingWithChunkedEncoding() { testEarlyDisconnectDoesntHarmPooling(TransferKind.CHUNKED) } - @Test fun earlyDisconnectDoesntHarmPoolingWithFixedLengthEncoding() { + @Test + fun earlyDisconnectDoesntHarmPoolingWithFixedLengthEncoding() { testEarlyDisconnectDoesntHarmPooling(TransferKind.FIXED_LENGTH) } @@ -1475,7 +1552,8 @@ class URLConnectionTest { assertThat(server.takeRequest().sequenceNumber).isEqualTo(1) } - @Test fun streamDiscardingIsTimely() { + @Test + fun streamDiscardingIsTimely() { // This response takes at least a full second to serve: 10,000 bytes served 100 bytes at a time. server.enqueue( MockResponse() @@ -1505,13 +1583,14 @@ class URLConnectionTest { assertThat(server.takeRequest().sequenceNumber).isEqualTo(0) } - @Test fun setChunkedStreamingMode() { + @Test + fun setChunkedStreamingMode() { server.enqueue(MockResponse()) val response = getResponse( - Request.Builder() - .url(server.url("/")) - .post(TransferKind.CHUNKED.newRequestBody("ABCDEFGHIJKLMNOPQ")) - .build() + Request( + url = server.url("/"), + body = TransferKind.CHUNKED.newRequestBody("ABCDEFGHIJKLMNOPQ"), + ) ) assertThat(response.code).isEqualTo(200) val request = server.takeRequest() @@ -1521,11 +1600,13 @@ class URLConnectionTest { ) } - @Test fun authenticateWithFixedLengthStreaming() { + @Test + fun authenticateWithFixedLengthStreaming() { testAuthenticateWithStreamingPost(TransferKind.FIXED_LENGTH) } - @Test fun authenticateWithChunkedStreaming() { + @Test + fun authenticateWithChunkedStreaming() { testAuthenticateWithStreamingPost(TransferKind.CHUNKED) } @@ -1544,10 +1625,10 @@ class URLConnectionTest { client = client.newBuilder() .authenticator(JavaNetAuthenticator()) .build() - val request = Request.Builder() - .url(server.url("/")) - .post(streamingMode.newRequestBody("ABCD")) - .build() + val request = Request( + url = server.url("/"), + body = streamingMode.newRequestBody("ABCD"), + ) val response = getResponse(request) assertThat(response.code).isEqualTo(200) assertContent("Authenticated!", response) @@ -1558,22 +1639,26 @@ class URLConnectionTest { assertThat(recordedRequest.body.readUtf8()).isEqualTo("ABCD") } - @Test fun postBodyRetransmittedAfterAuthorizationFail() { + @Test + fun postBodyRetransmittedAfterAuthorizationFail() { postBodyRetransmittedAfterAuthorizationFail("abc") } - @Test fun postBodyRetransmittedAfterAuthorizationFail_HTTP_2() { + @Test + fun postBodyRetransmittedAfterAuthorizationFail_HTTP_2() { platform.assumeHttp2Support() enableProtocol(Protocol.HTTP_2) postBodyRetransmittedAfterAuthorizationFail("abc") } /** Don't explode when resending an empty post. https://github.com/square/okhttp/issues/1131 */ - @Test fun postEmptyBodyRetransmittedAfterAuthorizationFail() { + @Test + fun postEmptyBodyRetransmittedAfterAuthorizationFail() { postBodyRetransmittedAfterAuthorizationFail("") } - @Test fun postEmptyBodyRetransmittedAfterAuthorizationFail_HTTP_2() { + @Test + fun postEmptyBodyRetransmittedAfterAuthorizationFail_HTTP_2() { platform.assumeHttp2Support() enableProtocol(Protocol.HTTP_2) postBodyRetransmittedAfterAuthorizationFail("") @@ -1590,10 +1675,10 @@ class URLConnectionTest { .authenticator(RecordingOkAuthenticator(credential, null)) .build() val response = getResponse( - Request.Builder() - .url(server.url("/")) - .post(body.toRequestBody()) - .build() + Request( + url = server.url("/"), + body = body.toRequestBody(), + ) ) assertThat(response.code).isEqualTo(200) response.body.byteStream().close() @@ -1607,19 +1692,22 @@ class URLConnectionTest { assertThat(recordedRequest2.getHeader("Authorization")).isEqualTo(credential) } - @Test fun nonStandardAuthenticationScheme() { + @Test + fun nonStandardAuthenticationScheme() { val calls = authCallsForHeader("WWW-Authenticate: Foo") assertThat(calls).isEqualTo(emptyList()) } - @Test fun nonStandardAuthenticationSchemeWithRealm() { + @Test + fun nonStandardAuthenticationSchemeWithRealm() { val calls = authCallsForHeader("WWW-Authenticate: Foo realm=\"Bar\"") assertThat(calls.size).isEqualTo(0) } // Digest auth is currently unsupported. Test that digest requests should fail reasonably. // http://code.google.com/p/android/issues/detail?id=11140 - @Test fun digestAuthentication() { + @Test + fun digestAuthentication() { val calls = authCallsForHeader( "WWW-Authenticate: Digest " + "realm=\"testrealm@host.com\", qop=\"auth,auth-int\", " @@ -1629,7 +1717,8 @@ class URLConnectionTest { assertThat(calls.size).isEqualTo(0) } - @Test fun allAttributesSetInServerAuthenticationCallbacks() { + @Test + fun allAttributesSetInServerAuthenticationCallbacks() { val calls = authCallsForHeader("WWW-Authenticate: Basic realm=\"Bar\"") assertThat(calls.size).isEqualTo(1) val url = server.url("/").toUrl() @@ -1645,7 +1734,8 @@ class URLConnectionTest { .contains("scheme=basic") // lowercase for the RI. } - @Test fun allAttributesSetInProxyAuthenticationCallbacks() { + @Test + fun allAttributesSetInProxyAuthenticationCallbacks() { val calls = authCallsForHeader("Proxy-Authenticate: Basic realm=\"Bar\"") assertThat(calls.size).isEqualTo(1) val url = server.url("/").toUrl() @@ -1677,7 +1767,7 @@ class URLConnectionTest { .proxy(server.toProxyAddress()) .proxyAuthenticator(JavaNetAuthenticator()) .build() - response = getResponse(newRequest("http://android.com/".toHttpUrl())) + response = getResponse(Request("http://android.com/".toHttpUrl())) } else { client = client.newBuilder() .authenticator(JavaNetAuthenticator()) @@ -1689,7 +1779,8 @@ class URLConnectionTest { return authenticator.calls } - @Test fun setValidRequestMethod() { + @Test + fun setValidRequestMethod() { assertMethodForbidsRequestBody("GET") assertMethodPermitsRequestBody("DELETE") assertMethodForbidsRequestBody("HEAD") @@ -1746,11 +1837,13 @@ class URLConnectionTest { } } - @Test fun setInvalidRequestMethodLowercase() { + @Test + fun setInvalidRequestMethodLowercase() { assertValidRequestMethod("get") } - @Test fun setInvalidRequestMethodConnect() { + @Test + fun setInvalidRequestMethodConnect() { assertValidRequestMethod("CONNECT") } @@ -1767,7 +1860,8 @@ class URLConnectionTest { assertThat(recordedRequest.method).isEqualTo(requestMethod) } - @Test fun shoutcast() { + @Test + fun shoutcast() { server.enqueue( MockResponse() .setStatus("ICY 200 OK") @@ -1794,11 +1888,13 @@ class URLConnectionTest { assertContent("mp3 data", response) } - @Test fun secureFixedLengthStreaming() { + @Test + fun secureFixedLengthStreaming() { testSecureStreamingPost(TransferKind.FIXED_LENGTH) } - @Test fun secureChunkedStreaming() { + @Test + fun secureChunkedStreaming() { testSecureStreamingPost(TransferKind.CHUNKED) } @@ -1819,10 +1915,10 @@ class URLConnectionTest { .hostnameVerifier(RecordingHostnameVerifier()) .build() val response = getResponse( - Request.Builder() - .url(server.url("/")) - .post(streamingMode.newRequestBody("ABCD")) - .build() + Request( + url = server.url("/"), + body = streamingMode.newRequestBody("ABCD"), + ) ) assertThat(readAscii(response.body.byteStream(), Int.MAX_VALUE)).isEqualTo( "Success!" @@ -1837,7 +1933,8 @@ class URLConnectionTest { assertThat(request.body.readUtf8()).isEqualTo("ABCD") } - @Test fun authenticateWithPost() { + @Test + fun authenticateWithPost() { val pleaseAuthenticate = MockResponse() .setResponseCode(401) .addHeader("WWW-Authenticate: Basic realm=\"protected area\"") @@ -1856,10 +1953,10 @@ class URLConnectionTest { .authenticator(JavaNetAuthenticator()) .build() val response = getResponse( - Request.Builder() - .url(server.url("/")) - .post("ABCD".toRequestBody(null)) - .build() + Request( + url = server.url("/"), + body = "ABCD".toRequestBody(null), + ) ) assertThat(readAscii(response.body.byteStream(), Int.MAX_VALUE)).isEqualTo( "Successful auth!" @@ -1880,7 +1977,8 @@ class URLConnectionTest { } } - @Test fun authenticateWithGet() { + @Test + fun authenticateWithGet() { val pleaseAuthenticate = MockResponse() .setResponseCode(401) .addHeader("WWW-Authenticate: Basic realm=\"protected area\"") @@ -1915,7 +2013,8 @@ class URLConnectionTest { } } - @Test fun authenticateWithCharset() { + @Test + fun authenticateWithCharset() { server.enqueue( MockResponse() .setResponseCode(401) @@ -1961,7 +2060,8 @@ class URLConnectionTest { } /** https://code.google.com/p/android/issues/detail?id=74026 */ - @Test fun authenticateWithGetAndTransparentGzip() { + @Test + fun authenticateWithGetAndTransparentGzip() { val pleaseAuthenticate = MockResponse() .setResponseCode(401) .addHeader("WWW-Authenticate: Basic realm=\"protected area\"") @@ -1998,7 +2098,8 @@ class URLConnectionTest { } /** https://github.com/square/okhttp/issues/342 */ - @Test fun authenticateRealmUppercase() { + @Test + fun authenticateRealmUppercase() { server.enqueue( MockResponse() .setResponseCode(401) @@ -2018,15 +2119,18 @@ class URLConnectionTest { .isEqualTo("Successful auth!") } - @Test fun redirectedWithChunkedEncoding() { + @Test + fun redirectedWithChunkedEncoding() { testRedirected(TransferKind.CHUNKED, true) } - @Test fun redirectedWithContentLengthHeader() { + @Test + fun redirectedWithContentLengthHeader() { testRedirected(TransferKind.FIXED_LENGTH, true) } - @Test fun redirectedWithNoLengthHeaders() { + @Test + fun redirectedWithNoLengthHeaders() { testRedirected(TransferKind.END_OF_STREAM, false) } @@ -2055,7 +2159,8 @@ class URLConnectionTest { } } - @Test fun redirectedOnHttps() { + @Test + fun redirectedOnHttps() { server.useHttps(handshakeCertificates.sslSocketFactory(), false) server.enqueue( MockResponse() @@ -2086,7 +2191,8 @@ class URLConnectionTest { .isEqualTo(1) } - @Test fun notRedirectedFromHttpsToHttp() { + @Test + fun notRedirectedFromHttpsToHttp() { server.useHttps(handshakeCertificates.sslSocketFactory(), false) server.enqueue( MockResponse() @@ -2106,7 +2212,8 @@ class URLConnectionTest { .isEqualTo("This page has moved!") } - @Test fun notRedirectedFromHttpToHttps() { + @Test + fun notRedirectedFromHttpToHttps() { server.enqueue( MockResponse() .setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP) @@ -2121,7 +2228,8 @@ class URLConnectionTest { .isEqualTo("This page has moved!") } - @Test fun redirectedFromHttpsToHttpFollowingProtocolRedirects() { + @Test + fun redirectedFromHttpsToHttpFollowingProtocolRedirects() { server2.enqueue( MockResponse() .setBody("This is insecure HTTP!") @@ -2145,7 +2253,8 @@ class URLConnectionTest { assertThat(response.handshake).isNull() } - @Test fun redirectedFromHttpToHttpsFollowingProtocolRedirects() { + @Test + fun redirectedFromHttpToHttpsFollowingProtocolRedirects() { server2.useHttps(handshakeCertificates.sslSocketFactory(), false) server2.enqueue( MockResponse() @@ -2168,11 +2277,13 @@ class URLConnectionTest { assertContent("This is secure HTTPS!", response) } - @Test fun redirectToAnotherOriginServer() { + @Test + fun redirectToAnotherOriginServer() { redirectToAnotherOriginServer(false) } - @Test fun redirectToAnotherOriginServerWithHttps() { + @Test + fun redirectToAnotherOriginServerWithHttps() { redirectToAnotherOriginServer(true) } @@ -2213,8 +2324,8 @@ class URLConnectionTest { ) // make sure the first server was careful to recycle the connection - assertContent("This is the first server again!", getResponse(newRequest(server.url("/")))) - assertContent("This is the 2nd server, again!", getResponse(newRequest(server2.url("/")))) + assertContent("This is the first server again!", getResponse(Request(server.url("/")))) + assertContent("This is the 2nd server, again!", getResponse(Request(server2.url("/")))) val server1Host = server.hostName + ":" + server.port val server2Host = server2.hostName + ":" + server2.port assertThat(server.takeRequest().getHeader("Host")).isEqualTo(server1Host) @@ -2227,7 +2338,8 @@ class URLConnectionTest { .isEqualTo(1) } - @Test fun redirectWithProxySelector() { + @Test + fun redirectWithProxySelector() { val proxySelectionRequests: MutableList = ArrayList() client = client.newBuilder() .proxySelector(object : ProxySelector() { @@ -2261,7 +2373,8 @@ class URLConnectionTest { ) } - @Test fun redirectWithAuthentication() { + @Test + fun redirectWithAuthentication() { server2.enqueue( MockResponse() .setBody("Page 2") @@ -2284,28 +2397,34 @@ class URLConnectionTest { assertThat(redirectRequest.path).isEqualTo("/b") } - @Test fun response300MultipleChoiceWithPost() { + @Test + fun response300MultipleChoiceWithPost() { // Chrome doesn't follow the redirect, but Firefox and the RI both do testResponseRedirectedWithPost(HttpURLConnection.HTTP_MULT_CHOICE, TransferKind.END_OF_STREAM) } - @Test fun response301MovedPermanentlyWithPost() { + @Test + fun response301MovedPermanentlyWithPost() { testResponseRedirectedWithPost(HttpURLConnection.HTTP_MOVED_PERM, TransferKind.END_OF_STREAM) } - @Test fun response302MovedTemporarilyWithPost() { + @Test + fun response302MovedTemporarilyWithPost() { testResponseRedirectedWithPost(HttpURLConnection.HTTP_MOVED_TEMP, TransferKind.END_OF_STREAM) } - @Test fun response303SeeOtherWithPost() { + @Test + fun response303SeeOtherWithPost() { testResponseRedirectedWithPost(HttpURLConnection.HTTP_SEE_OTHER, TransferKind.END_OF_STREAM) } - @Test fun postRedirectToGetWithChunkedRequest() { + @Test + fun postRedirectToGetWithChunkedRequest() { testResponseRedirectedWithPost(HttpURLConnection.HTTP_MOVED_TEMP, TransferKind.CHUNKED) } - @Test fun postRedirectToGetWithStreamedRequest() { + @Test + fun postRedirectToGetWithStreamedRequest() { testResponseRedirectedWithPost(HttpURLConnection.HTTP_MOVED_TEMP, TransferKind.FIXED_LENGTH) } @@ -2321,10 +2440,10 @@ class URLConnectionTest { .setBody("Page 2") ) val response = getResponse( - Request.Builder() - .url(server.url("/page1")) - .post(transferKind.newRequestBody("ABCD")) - .build() + Request( + url = server.url("/page1"), + body = transferKind.newRequestBody("ABCD"), + ) ) assertThat(readAscii(response.body.byteStream(), Int.MAX_VALUE)) .isEqualTo("Page 2") @@ -2335,7 +2454,8 @@ class URLConnectionTest { assertThat(page2.requestLine).isEqualTo("GET /page2 HTTP/1.1") } - @Test fun redirectedPostStripsRequestBodyHeaders() { + @Test + fun redirectedPostStripsRequestBodyHeaders() { server.enqueue( MockResponse() .setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP) @@ -2363,7 +2483,8 @@ class URLConnectionTest { assertThat(page2.getHeader("Transfer-Encoding")).isNull() } - @Test fun response305UseProxy() { + @Test + fun response305UseProxy() { server.enqueue( MockResponse() .setResponseCode(HttpURLConnection.HTTP_USE_PROXY) @@ -2383,35 +2504,43 @@ class URLConnectionTest { assertThat(server.requestCount).isEqualTo(1) } - @Test fun response307WithGet() { + @Test + fun response307WithGet() { testRedirect(true, "GET") } - @Test fun response307WithHead() { + @Test + fun response307WithHead() { testRedirect(true, "HEAD") } - @Test fun response307WithOptions() { + @Test + fun response307WithOptions() { testRedirect(true, "OPTIONS") } - @Test fun response307WithPost() { + @Test + fun response307WithPost() { testRedirect(true, "POST") } - @Test fun response308WithGet() { + @Test + fun response308WithGet() { testRedirect(false, "GET") } - @Test fun response308WithHead() { + @Test + fun response308WithHead() { testRedirect(false, "HEAD") } - @Test fun response308WithOptions() { + @Test + fun response308WithOptions() { testRedirect(false, "OPTIONS") } - @Test fun response308WithPost() { + @Test + fun response308WithPost() { testRedirect(false, "POST") } @@ -2446,7 +2575,8 @@ class URLConnectionTest { } } - @Test fun response307WithPostReverted() { + @Test + fun response307WithPostReverted() { client = client.newBuilder() .addNetworkInterceptor(LegacyRedirectInterceptor()) .build() @@ -2455,10 +2585,11 @@ class URLConnectionTest { .setBody("This page has moved!") .addHeader("Location: /page2") server.enqueue(response1) - val requestBuilder = Request.Builder() - .url(server.url("/page1")) - requestBuilder.post("ABCD".toRequestBody(null)) - val response = getResponse(requestBuilder.build()) + val request = Request( + url = server.url("/page1"), + body = "ABCD".toRequestBody(null), + ) + val response = getResponse(request) val responseString = readAscii(response.body.byteStream(), Int.MAX_VALUE) val page1 = server.takeRequest() assertThat(page1.requestLine).isEqualTo("POST /page1 HTTP/1.1") @@ -2467,7 +2598,8 @@ class URLConnectionTest { assertThat(responseString).isEqualTo("This page has moved!") } - @Test fun response308WithPostReverted() { + @Test + fun response308WithPostReverted() { client = client.newBuilder() .addNetworkInterceptor(LegacyRedirectInterceptor()) .build() @@ -2476,10 +2608,11 @@ class URLConnectionTest { .setBody("This page has moved!") .addHeader("Location: /page2") server.enqueue(response1) - val requestBuilder = Request.Builder() - .url(server.url("/page1")) - requestBuilder.post("ABCD".toRequestBody(null)) - val response = getResponse(requestBuilder.build()) + val request = Request( + url = server.url("/page1"), + body = "ABCD".toRequestBody(null), + ) + val response = getResponse(request) val responseString = readAscii(response.body.byteStream(), Int.MAX_VALUE) val page1 = server.takeRequest() assertThat(page1.requestLine).isEqualTo("POST /page1 HTTP/1.1") @@ -2526,7 +2659,8 @@ class URLConnectionTest { .isEqualTo("$method /page2 HTTP/1.1") } - @Test fun follow20Redirects() { + @Test + fun follow20Redirects() { for (i in 0..19) { server.enqueue( MockResponse() @@ -2545,7 +2679,8 @@ class URLConnectionTest { .isEqualTo(server.url("/20")) } - @Test fun doesNotFollow21Redirects() { + @Test + fun doesNotFollow21Redirects() { for (i in 0..20) { server.enqueue( MockResponse() @@ -2564,7 +2699,8 @@ class URLConnectionTest { } } - @Test fun httpsWithCustomTrustManager() { + @Test + fun httpsWithCustomTrustManager() { val hostnameVerifier = RecordingHostnameVerifier() val trustManager = RecordingTrustManager(handshakeCertificates.trustManager) val sslContext = get().newSSLContext() @@ -2595,7 +2731,8 @@ class URLConnectionTest { .isEqualTo(listOf("checkServerTrusted [CN=localhost 1]")) } - @Test fun getClientRequestTimeout() { + @Test + fun getClientRequestTimeout() { enqueueClientRequestTimeoutResponses() val response = getResponse(newRequest("/")) assertThat(response.code).isEqualTo(200) @@ -2617,13 +2754,14 @@ class URLConnectionTest { ) } - @Test fun bufferedBodyWithClientRequestTimeout() { + @Test + fun bufferedBodyWithClientRequestTimeout() { enqueueClientRequestTimeoutResponses() val response = getResponse( - Request.Builder() - .url(server.url("/")) - .post("Hello".toRequestBody(null)) - .build() + Request( + url = server.url("/"), + body = "Hello".toRequestBody(null), + ) ) assertThat(response.code).isEqualTo(200) assertThat(readAscii(response.body.byteStream(), Int.MAX_VALUE)) @@ -2634,13 +2772,14 @@ class URLConnectionTest { assertThat(request2.body.readUtf8()).isEqualTo("Hello") } - @Test fun streamedBodyWithClientRequestTimeout() { + @Test + fun streamedBodyWithClientRequestTimeout() { enqueueClientRequestTimeoutResponses() val response = getResponse( - Request.Builder() - .url(server.url("/")) - .post(TransferKind.CHUNKED.newRequestBody("Hello")) - .build() + Request( + url = server.url("/"), + body = TransferKind.CHUNKED.newRequestBody("Hello"), + ) ) assertThat(response.code).isEqualTo(200) assertContent("Body", response) @@ -2648,7 +2787,8 @@ class URLConnectionTest { assertThat(server.requestCount).isEqualTo(2) } - @Test fun readTimeouts() { + @Test + fun readTimeouts() { // This relies on the fact that MockWebServer doesn't close the // connection after a response has been sent. This causes the client to // try to read more bytes than are sent, which results in a timeout. @@ -2677,7 +2817,8 @@ class URLConnectionTest { } /** Confirm that an unacknowledged write times out. */ - @Test fun writeTimeouts() { + @Test + fun writeTimeouts() { val server = MockWebServer() // Sockets on some platforms can have large buffers that mean writes do not block when // required. These socket factories explicitly set the buffer sizes on sockets created. @@ -2703,9 +2844,9 @@ class URLConnectionTest { MockResponse() .throttleBody(1, 1, TimeUnit.SECONDS) ) // Prevent the server from reading! - val request = Request.Builder() - .url(server.url("/")) - .post(object : RequestBody() { + val request = Request( + url = server.url("/"), + body = object : RequestBody() { override fun contentType(): MediaType? { return null } @@ -2714,8 +2855,8 @@ class URLConnectionTest { val data = ByteArray(2 * 1024 * 1024) // 2 MiB. sink.write(data) } - }) - .build() + }, + ) try { getResponse(request) fail() @@ -2723,7 +2864,8 @@ class URLConnectionTest { } } - @Test fun setChunkedEncodingAsRequestProperty() { + @Test + fun setChunkedEncodingAsRequestProperty() { server.enqueue(MockResponse()) val response = getResponse( Request.Builder() @@ -2737,7 +2879,8 @@ class URLConnectionTest { assertThat(request.body.readUtf8()).isEqualTo("ABC") } - @Test fun connectionCloseInRequest() { + @Test + fun connectionCloseInRequest() { server.enqueue(MockResponse()) // Server doesn't honor the connection: close header! server.enqueue(MockResponse()) val a = getResponse( @@ -2757,7 +2900,8 @@ class URLConnectionTest { .isEqualTo(0L) } - @Test fun connectionCloseInResponse() { + @Test + fun connectionCloseInResponse() { server.enqueue( MockResponse() .addHeader("Connection: close") @@ -2775,7 +2919,8 @@ class URLConnectionTest { .isEqualTo(0L) } - @Test fun connectionCloseWithRedirect() { + @Test + fun connectionCloseWithRedirect() { server.enqueue( MockResponse() .setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP) @@ -2802,7 +2947,8 @@ class URLConnectionTest { * Retry redirects if the socket is closed. * https://code.google.com/p/android/issues/detail?id=41576 */ - @Test fun sameConnectionRedirectAndReuse() { + @Test + fun sameConnectionRedirectAndReuse() { server.enqueue( MockResponse() .setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP) @@ -2818,7 +2964,8 @@ class URLConnectionTest { assertThat(server.takeRequest().sequenceNumber).isEqualTo(0) } - @Test fun responseCodeDisagreesWithHeaders() { + @Test + fun responseCodeDisagreesWithHeaders() { server.enqueue( MockResponse() .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT) @@ -2832,7 +2979,8 @@ class URLConnectionTest { } } - @Test fun singleByteReadIsSigned() { + @Test + fun singleByteReadIsSigned() { server.enqueue( MockResponse() .setBody( @@ -2848,15 +2996,18 @@ class URLConnectionTest { assertThat(inputStream.read()).isEqualTo(-1) } - @Test fun flushAfterStreamTransmittedWithChunkedEncoding() { + @Test + fun flushAfterStreamTransmittedWithChunkedEncoding() { testFlushAfterStreamTransmitted(TransferKind.CHUNKED) } - @Test fun flushAfterStreamTransmittedWithFixedLength() { + @Test + fun flushAfterStreamTransmittedWithFixedLength() { testFlushAfterStreamTransmitted(TransferKind.FIXED_LENGTH) } - @Test fun flushAfterStreamTransmittedWithNoLengthHeaders() { + @Test + fun flushAfterStreamTransmittedWithNoLengthHeaders() { testFlushAfterStreamTransmitted(TransferKind.END_OF_STREAM) } @@ -2872,15 +3023,15 @@ class URLConnectionTest { ) val sinkReference = AtomicReference() val response = getResponse( - Request.Builder() - .url(server.url("/")) - .post(object : ForwardingRequestBody(transferKind.newRequestBody("def")) { + Request( + url = server.url("/"), + body = object : ForwardingRequestBody(transferKind.newRequestBody("def")) { override fun writeTo(sink: BufferedSink) { sinkReference.set(sink) super.writeTo(sink) } - }) - .build() + }, + ) ) assertThat(readAscii(response.body.byteStream(), Int.MAX_VALUE)) .isEqualTo("abc") @@ -2897,7 +3048,8 @@ class URLConnectionTest { } } - @Test fun getHeadersThrows() { + @Test + fun getHeadersThrows() { server.enqueue( MockResponse() .setSocketPolicy(SocketPolicy.DISCONNECT_AT_START) @@ -2909,27 +3061,30 @@ class URLConnectionTest { } } - @Test fun dnsFailureThrowsIOException() { + @Test + fun dnsFailureThrowsIOException() { client = client.newBuilder() .dns(FakeDns()) .build() try { - getResponse(newRequest("http://host.unlikelytld".toHttpUrl())) + getResponse(Request("http://host.unlikelytld".toHttpUrl())) fail() } catch (expected: IOException) { } } - @Test fun malformedUrlThrowsUnknownHostException() { + @Test + fun malformedUrlThrowsUnknownHostException() { try { - getResponse(newRequest("http://./foo.html".toHttpUrl())) + getResponse(Request("http://./foo.html".toHttpUrl())) fail() } catch (expected: UnknownHostException) { } } // The request should work once and then fail. - @Test fun getKeepAlive() { + @Test + fun getKeepAlive() { server.enqueue( MockResponse() .setBody("ABC") @@ -2949,7 +3104,8 @@ class URLConnectionTest { } /** http://code.google.com/p/android/issues/detail?id=14562 */ - @Test fun readAfterLastByte() { + @Test + fun readAfterLastByte() { server.enqueue( MockResponse() .setBody("ABC") @@ -2965,7 +3121,8 @@ class URLConnectionTest { assertThat(`in`.read()).isEqualTo(-1) } - @Test fun getOutputStreamOnGetFails() { + @Test + fun getOutputStreamOnGetFails() { try { Request.Builder() .url(server.url("/")) @@ -2976,16 +3133,17 @@ class URLConnectionTest { } } - @Test fun clientSendsContentLength() { + @Test + fun clientSendsContentLength() { server.enqueue( MockResponse() .setBody("A") ) val response = getResponse( - Request.Builder() - .url(server.url("/")) - .post("ABC".toRequestBody(null)) - .build() + Request( + url = server.url("/"), + body = "ABC".toRequestBody(null), + ) ) assertThat(readAscii(response.body.byteStream(), Int.MAX_VALUE)).isEqualTo("A") val request = server.takeRequest() @@ -2993,7 +3151,8 @@ class URLConnectionTest { response.body.close() } - @Test fun getContentLengthConnects() { + @Test + fun getContentLengthConnects() { server.enqueue( MockResponse() .setBody("ABC") @@ -3003,7 +3162,8 @@ class URLConnectionTest { response.body.close() } - @Test fun getContentTypeConnects() { + @Test + fun getContentTypeConnects() { server.enqueue( MockResponse() .addHeader("Content-Type: text/plain") @@ -3016,7 +3176,8 @@ class URLConnectionTest { response.body.close() } - @Test fun getContentEncodingConnects() { + @Test + fun getContentEncodingConnects() { server.enqueue( MockResponse() .addHeader("Content-Encoding: identity") @@ -3027,19 +3188,21 @@ class URLConnectionTest { response.body.close() } - @Test fun urlContainsQueryButNoPath() { + @Test + fun urlContainsQueryButNoPath() { server.enqueue( MockResponse() .setBody("A") ) val url = server.url("?query") - val response = getResponse(newRequest(url)) + val response = getResponse(Request(url)) assertThat(readAscii(response.body.byteStream(), Int.MAX_VALUE)).isEqualTo("A") val request = server.takeRequest() assertThat(request.requestLine).isEqualTo("GET /?query HTTP/1.1") } - @Test fun doOutputForMethodThatDoesntSupportOutput() { + @Test + fun doOutputForMethodThatDoesntSupportOutput() { try { Request.Builder() .url(server.url("/")) @@ -3051,15 +3214,18 @@ class URLConnectionTest { } // http://code.google.com/p/android/issues/detail?id=20442 - @Test fun inputStreamAvailableWithChunkedEncoding() { + @Test + fun inputStreamAvailableWithChunkedEncoding() { testInputStreamAvailable(TransferKind.CHUNKED) } - @Test fun inputStreamAvailableWithContentLengthHeader() { + @Test + fun inputStreamAvailableWithContentLengthHeader() { testInputStreamAvailable(TransferKind.FIXED_LENGTH) } - @Test fun inputStreamAvailableWithNoLengthHeaders() { + @Test + fun inputStreamAvailableWithNoLengthHeaders() { testInputStreamAvailable(TransferKind.END_OF_STREAM) } @@ -3078,27 +3244,33 @@ class URLConnectionTest { assertThat(inputStream.read()).isEqualTo(-1) } - @Test fun postFailsWithBufferedRequestForSmallRequest() { + @Test + fun postFailsWithBufferedRequestForSmallRequest() { reusedConnectionFailsWithPost(TransferKind.END_OF_STREAM, 1024) } - @Test fun postFailsWithBufferedRequestForLargeRequest() { + @Test + fun postFailsWithBufferedRequestForLargeRequest() { reusedConnectionFailsWithPost(TransferKind.END_OF_STREAM, 16384) } - @Test fun postFailsWithChunkedRequestForSmallRequest() { + @Test + fun postFailsWithChunkedRequestForSmallRequest() { reusedConnectionFailsWithPost(TransferKind.CHUNKED, 1024) } - @Test fun postFailsWithChunkedRequestForLargeRequest() { + @Test + fun postFailsWithChunkedRequestForLargeRequest() { reusedConnectionFailsWithPost(TransferKind.CHUNKED, 16384) } - @Test fun postFailsWithFixedLengthRequestForSmallRequest() { + @Test + fun postFailsWithFixedLengthRequestForSmallRequest() { reusedConnectionFailsWithPost(TransferKind.FIXED_LENGTH, 1024) } - @Test fun postFailsWithFixedLengthRequestForLargeRequest() { + @Test + fun postFailsWithFixedLengthRequestForLargeRequest() { reusedConnectionFailsWithPost(TransferKind.FIXED_LENGTH, 16384) } @@ -3128,10 +3300,10 @@ class URLConnectionTest { for (j in 0..1) { try { val response = getResponse( - Request.Builder() - .url(server.url("/b")) - .post(transferKind.newRequestBody(requestBody)) - .build() + Request( + url = server.url("/b"), + body = transferKind.newRequestBody(requestBody), + ) ) assertContent("B", response) break @@ -3148,7 +3320,8 @@ class URLConnectionTest { assertThat(requestB.body.readUtf8()).isEqualTo(requestBody) } - @Test fun postBodyRetransmittedOnFailureRecovery() { + @Test + fun postBodyRetransmittedOnFailureRecovery() { server.enqueue( MockResponse() .setBody("abc") @@ -3165,10 +3338,10 @@ class URLConnectionTest { // Seed the connection pool so we have something that can fail. assertContent("abc", getResponse(newRequest("/"))) val post = getResponse( - Request.Builder() - .url(server.url("/")) - .post("body!".toRequestBody(null)) - .build() + Request( + url = server.url("/"), + body = "body!".toRequestBody(null), + ) ) assertContent("def", post) val get = server.takeRequest() @@ -3181,7 +3354,8 @@ class URLConnectionTest { assertThat(post2.sequenceNumber).isEqualTo(0) } - @Test fun fullyBufferedPostIsTooShort() { + @Test + fun fullyBufferedPostIsTooShort() { server.enqueue( MockResponse() .setBody("A") @@ -3197,17 +3371,18 @@ class URLConnectionTest { } try { getResponse( - Request.Builder() - .url(server.url("/b")) - .post(requestBody) - .build() + Request( + url = server.url("/b"), + body = requestBody, + ) ) fail() } catch (expected: IOException) { } } - @Test fun fullyBufferedPostIsTooLong() { + @Test + fun fullyBufferedPostIsTooLong() { server.enqueue( MockResponse() .setBody("A") @@ -3223,31 +3398,38 @@ class URLConnectionTest { } try { getResponse( - Request.Builder() - .url(server.url("/b")) - .post(requestBody) - .build() + Request( + url = server.url("/b"), + body = requestBody, + ) ) fail() } catch (expected: IOException) { } } - @Test @Disabled fun testPooledConnectionsDetectHttp10() { + @Test + @Disabled + fun testPooledConnectionsDetectHttp10() { // TODO: write a test that shows pooled connections detect HTTP/1.0 (vs. HTTP/1.1) fail("TODO") } - @Test @Disabled fun postBodiesRetransmittedOnAuthProblems() { + @Test + @Disabled + fun postBodiesRetransmittedOnAuthProblems() { fail("TODO") } - @Test @Disabled fun cookiesAndTrailers() { + @Test + @Disabled + fun cookiesAndTrailers() { // Do cookie headers get processed too many times? fail("TODO") } - @Test fun emptyRequestHeaderValueIsAllowed() { + @Test + fun emptyRequestHeaderValueIsAllowed() { server.enqueue( MockResponse() .setBody("body") @@ -3262,7 +3444,8 @@ class URLConnectionTest { assertThat(response.request.header("B")).isEqualTo("") } - @Test fun emptyResponseHeaderValueIsAllowed() { + @Test + fun emptyResponseHeaderValueIsAllowed() { server.enqueue( MockResponse() .addHeader("A:") @@ -3273,7 +3456,8 @@ class URLConnectionTest { assertThat(response.header("A")).isEqualTo("") } - @Test fun emptyRequestHeaderNameIsStrict() { + @Test + fun emptyRequestHeaderNameIsStrict() { try { Request.Builder() .url(server.url("/")) @@ -3284,7 +3468,8 @@ class URLConnectionTest { } } - @Test fun emptyResponseHeaderNameIsLenient() { + @Test + fun emptyResponseHeaderNameIsLenient() { val headers = Headers.Builder() addHeaderLenient(headers, ":A") server.enqueue( @@ -3298,7 +3483,8 @@ class URLConnectionTest { response.body.close() } - @Test fun requestHeaderValidationIsStrict() { + @Test + fun requestHeaderValidationIsStrict() { try { Request.Builder() .addHeader("a\tb", "Value") @@ -3331,7 +3517,8 @@ class URLConnectionTest { } } - @Test fun responseHeaderParsingIsLenient() { + @Test + fun responseHeaderParsingIsLenient() { val headersBuilder = Headers.Builder() headersBuilder.add("Content-Length", "0") addHeaderLenient(headersBuilder, "a\tb: c\u007fd") @@ -3349,19 +3536,26 @@ class URLConnectionTest { assertThat(response.header("")).isEqualTo("ef") } - @Test @Disabled fun deflateCompression() { + @Test + @Disabled + fun deflateCompression() { fail("TODO") } - @Test @Disabled fun postBodiesRetransmittedOnIpAddressProblems() { + @Test + @Disabled + fun postBodiesRetransmittedOnIpAddressProblems() { fail("TODO") } - @Test @Disabled fun pooledConnectionProblemsNotReportedToProxySelector() { + @Test + @Disabled + fun pooledConnectionProblemsNotReportedToProxySelector() { fail("TODO") } - @Test fun customBasicAuthenticator() { + @Test + fun customBasicAuthenticator() { server.enqueue( MockResponse() .setResponseCode(401) @@ -3386,7 +3580,8 @@ class URLConnectionTest { assertThat(response.challenges()).isEqualTo(listOf(Challenge("Basic", "protected area"))) } - @Test fun customTokenAuthenticator() { + @Test + fun customTokenAuthenticator() { server.enqueue( MockResponse() .setResponseCode(401) @@ -3411,7 +3606,8 @@ class URLConnectionTest { assertThat(response.challenges()).isEqualTo(listOf(Challenge("Bearer", "oauthed"))) } - @Test fun authenticateCallsTrackedAsRedirects() { + @Test + fun authenticateCallsTrackedAsRedirects() { server.enqueue( MockResponse() .setResponseCode(302) @@ -3439,7 +3635,8 @@ class URLConnectionTest { assertThat(redirectedBy!!.request.url.toUrl().path).isEqualTo("/a") } - @Test fun attemptAuthorization20Times() { + @Test + fun attemptAuthorization20Times() { for (i in 0..19) { server.enqueue( MockResponse() @@ -3458,7 +3655,8 @@ class URLConnectionTest { assertContent("Success!", response) } - @Test fun doesNotAttemptAuthorization21Times() { + @Test + fun doesNotAttemptAuthorization21Times() { for (i in 0..20) { server.enqueue( MockResponse() @@ -3477,7 +3675,8 @@ class URLConnectionTest { } } - @Test fun setsNegotiatedProtocolHeader_HTTP_2() { + @Test + fun setsNegotiatedProtocolHeader_HTTP_2() { platform.assumeHttp2Support() setsNegotiatedProtocolHeader(Protocol.HTTP_2) } @@ -3496,7 +3695,8 @@ class URLConnectionTest { assertContent("A", response) } - @Test fun http10SelectedProtocol() { + @Test + fun http10SelectedProtocol() { server.enqueue( MockResponse() .setStatus("HTTP/1.0 200 OK") @@ -3505,7 +3705,8 @@ class URLConnectionTest { assertThat(response.protocol).isEqualTo(Protocol.HTTP_1_0) } - @Test fun http11SelectedProtocol() { + @Test + fun http11SelectedProtocol() { server.enqueue( MockResponse() .setStatus("HTTP/1.1 200 OK") @@ -3515,21 +3716,25 @@ class URLConnectionTest { } /** For example, empty Protobuf RPC messages end up as a zero-length POST. */ - @Test fun zeroLengthPost() { + @Test + fun zeroLengthPost() { zeroLengthPayload("POST") } - @Test fun zeroLengthPost_HTTP_2() { + @Test + fun zeroLengthPost_HTTP_2() { enableProtocol(Protocol.HTTP_2) zeroLengthPost() } /** For example, creating an Amazon S3 bucket ends up as a zero-length POST. */ - @Test fun zeroLengthPut() { + @Test + fun zeroLengthPut() { zeroLengthPayload("PUT") } - @Test fun zeroLengthPut_HTTP_2() { + @Test + fun zeroLengthPut_HTTP_2() { enableProtocol(Protocol.HTTP_2) zeroLengthPut() } @@ -3549,7 +3754,8 @@ class URLConnectionTest { assertThat(zeroLengthPayload.bodySize).isEqualTo(0L) } - @Test fun setProtocols() { + @Test + fun setProtocols() { server.enqueue( MockResponse() .setBody("A") @@ -3560,7 +3766,8 @@ class URLConnectionTest { assertContent("A", getResponse(newRequest("/"))) } - @Test fun setProtocolsWithoutHttp11() { + @Test + fun setProtocolsWithoutHttp11() { try { OkHttpClient.Builder() .protocols(Arrays.asList(Protocol.HTTP_2)) @@ -3569,7 +3776,8 @@ class URLConnectionTest { } } - @Test fun setProtocolsWithNull() { + @Test + fun setProtocolsWithNull() { try { OkHttpClient.Builder() .protocols(Arrays.asList(Protocol.HTTP_1_1, null)) @@ -3578,14 +3786,15 @@ class URLConnectionTest { } } - @Test fun veryLargeFixedLengthRequest() { + @Test + fun veryLargeFixedLengthRequest() { server.bodyLimit = 0 server.enqueue(MockResponse()) val contentLength = Int.MAX_VALUE + 1L val response = getResponse( - Request.Builder() - .url(server.url("/")) - .post(object : RequestBody() { + Request( + url = server.url("/"), + body = object : RequestBody() { override fun contentType(): MediaType? = null override fun contentLength(): Long = contentLength @@ -3599,8 +3808,8 @@ class URLConnectionTest { sink.write(buffer, 0, byteCount) } } - }) - .build() + }, + ) ) assertContent("", response) val request = server.takeRequest() @@ -3609,7 +3818,8 @@ class URLConnectionTest { ) } - @Test fun testNoSslFallback() { + @Test + fun testNoSslFallback() { server.useHttps(handshakeCertificates.sslSocketFactory(), false /* tunnelProxy */) server.enqueue( MockResponse() @@ -3644,7 +3854,8 @@ class URLConnectionTest { * with 304s since that response code can include headers (like "Content-Encoding") without any * content to go along with it. https://github.com/square/okhttp/issues/358 */ - @Test fun noTransparentGzipFor304NotModified() { + @Test + fun noTransparentGzipFor304NotModified() { server.enqueue( MockResponse() .clearHeaders() @@ -3671,7 +3882,8 @@ class URLConnectionTest { * We had a bug where we weren't closing Gzip streams on redirects. * https://github.com/square/okhttp/issues/441 */ - @Test fun gzipWithRedirectAndConnectionReuse() { + @Test + fun gzipWithRedirectAndConnectionReuse() { server.enqueue( MockResponse() .setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP) @@ -3695,7 +3907,8 @@ class URLConnectionTest { * The RFC is unclear in this regard as it only specifies that this should invalidate the cache * entry (if any). */ - @Test fun bodyPermittedOnDelete() { + @Test + fun bodyPermittedOnDelete() { server.enqueue(MockResponse()) val response = getResponse( Request.Builder() @@ -3709,7 +3922,8 @@ class URLConnectionTest { assertThat(request.body.readUtf8()).isEqualTo("BODY") } - @Test fun userAgentDefaultsToOkHttpVersion() { + @Test + fun userAgentDefaultsToOkHttpVersion() { server.enqueue( MockResponse() .setBody("abc") @@ -3719,7 +3933,8 @@ class URLConnectionTest { assertThat(request.getHeader("User-Agent")).isEqualTo(userAgent) } - @Test fun urlWithSpaceInHost() { + @Test + fun urlWithSpaceInHost() { try { "http://and roid.com/".toHttpUrl() fail() @@ -3727,7 +3942,8 @@ class URLConnectionTest { } } - @Test fun urlWithSpaceInHostViaHttpProxy() { + @Test + fun urlWithSpaceInHostViaHttpProxy() { try { "http://and roid.com/".toHttpUrl() fail() @@ -3735,7 +3951,8 @@ class URLConnectionTest { } } - @Test fun urlHostWithNul() { + @Test + fun urlHostWithNul() { try { "http://host\u0000/".toHttpUrl() fail() @@ -3743,7 +3960,8 @@ class URLConnectionTest { } } - @Test fun urlRedirectToHostWithNul() { + @Test + fun urlRedirectToHostWithNul() { val redirectUrl = "http://host\u0000/" server.enqueue( MockResponse() @@ -3755,7 +3973,8 @@ class URLConnectionTest { assertThat(response.header("Location")).isEqualTo(redirectUrl) } - @Test fun urlWithBadAsciiHost() { + @Test + fun urlWithBadAsciiHost() { try { "http://host\u0001/".toHttpUrl() fail() @@ -3764,7 +3983,8 @@ class URLConnectionTest { } @Suppress("DEPRECATION_ERROR") - @Test fun setSslSocketFactoryFailsOnJdk9() { + @Test + fun setSslSocketFactoryFailsOnJdk9() { platform.assumeJdk9() try { client.newBuilder() @@ -3775,7 +3995,8 @@ class URLConnectionTest { } /** Confirm that runtime exceptions thrown inside of OkHttp propagate to the caller. */ - @Test fun unexpectedExceptionSync() { + @Test + fun unexpectedExceptionSync() { client = client.newBuilder() .dns { hostname: String? -> throw RuntimeException("boom!") } .build() @@ -3788,7 +4009,8 @@ class URLConnectionTest { } } - @Test fun streamedBodyIsRetriedOnHttp2Shutdown() { + @Test + fun streamedBodyIsRetriedOnHttp2Shutdown() { platform.assumeHttp2Support() enableProtocol(Protocol.HTTP_2) server.enqueue( @@ -3810,10 +4032,10 @@ class URLConnectionTest { assertContent( "def", getResponse( - Request.Builder() - .url(server.url("/")) - .post("123".toRequestBody(null)) - .build() + Request( + url = server.url("/"), + body = "123".toRequestBody(null), + ) ) ) val request1 = server.takeRequest() @@ -3823,7 +4045,8 @@ class URLConnectionTest { assertThat(request2.sequenceNumber).isEqualTo(0) } - @Test fun authenticateNoConnection() { + @Test + fun authenticateNoConnection() { server.enqueue( MockResponse() .addHeader("Connection: close") @@ -3838,13 +4061,7 @@ class URLConnectionTest { assertThat(response.code).isEqualTo(401) } - private fun newRequest(s: String): Request = newRequest(server.url(s)) - - private fun newRequest(url: HttpUrl): Request { - return Request.Builder() - .url(url) - .build() - } + private fun newRequest(s: String): Request = Request(server.url(s)) private fun getResponse(request: Request): Response { return client.newCall(request).execute() @@ -3976,10 +4193,8 @@ class URLConnectionTest { abstract fun connect(server: MockWebServer, client: OkHttpClient): Call.Factory fun connect(server: MockWebServer, client: OkHttpClient, url: HttpUrl): Call { - val request = Request.Builder() - .url(url) - .build() - return connect(server, client).newCall(request) + return connect(server, client) + .newCall(Request(url)) } } diff --git a/okhttp/src/jvmTest/java/okhttp3/internal/connection/ConnectionPoolTest.kt b/okhttp/src/jvmTest/java/okhttp3/internal/connection/ConnectionPoolTest.kt index 83cd42da2..c4e6ca33d 100644 --- a/okhttp/src/jvmTest/java/okhttp3/internal/connection/ConnectionPoolTest.kt +++ b/okhttp/src/jvmTest/java/okhttp3/internal/connection/ConnectionPoolTest.kt @@ -17,6 +17,7 @@ package okhttp3.internal.connection import okhttp3.ConnectionPool import okhttp3.OkHttpClient +import okhttp3.Request import okhttp3.TestUtil.awaitGarbageCollection import okhttp3.TestValueFactory import okhttp3.internal.concurrent.TaskRunner @@ -76,7 +77,7 @@ class ConnectionPoolTest { val client = OkHttpClient.Builder() .connectionPool(poolApi) .build() - val call = client.newCall(factory.newRequest(addressA)) as RealCall + val call = client.newCall(Request(addressA.url)) as RealCall call.enterNetworkInterceptorExchange(call.request(), true, factory.newChain(call)) synchronized(c1) { call.acquireConnectionNoEvents(c1) } @@ -188,7 +189,7 @@ class ConnectionPoolTest { val client = OkHttpClient.Builder() .connectionPool(pool) .build() - val call = client.newCall(factory.newRequest(connection.route().address)) as RealCall + val call = client.newCall(Request(connection.route().address.url)) as RealCall call.enterNetworkInterceptorExchange(call.request(), true, factory.newChain(call)) synchronized(connection) { call.acquireConnectionNoEvents(connection) } } diff --git a/okhttp/src/jvmTest/java/okhttp3/internal/http/CancelTest.kt b/okhttp/src/jvmTest/java/okhttp3/internal/http/CancelTest.kt index 9160ba3c3..e4e2b95cd 100644 --- a/okhttp/src/jvmTest/java/okhttp3/internal/http/CancelTest.kt +++ b/okhttp/src/jvmTest/java/okhttp3/internal/http/CancelTest.kt @@ -145,9 +145,9 @@ class CancelTest { setUp(mode) server.enqueue(MockResponse()) val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .post(object : RequestBody() { + Request( + url = server.url("/"), + body = object : RequestBody() { override fun contentType(): MediaType? { return null } @@ -162,8 +162,8 @@ class CancelTest { } fail("Expected connection to be closed") } - }) - .build() + }, + ) ) cancelLater(call, 500) try { @@ -187,11 +187,7 @@ class CancelTest { ) .throttleBody(64 * 1024, 125, MILLISECONDS) ) // 500 Kbps - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() cancelLater(call, 500) val responseBody = response.body.byteStream() @@ -254,7 +250,7 @@ class CancelTest { assertThat(events).contains("ResponseFailed") assertThat(events).contains("ConnectionReleased") - val call2 = client.newCall(Request.Builder().url(server.url("/")).build()) + val call2 = client.newCall(Request(server.url("/"))) call2.execute().use { assertEquals(".", it.body.string()) } diff --git a/okhttp/src/jvmTest/java/okhttp3/internal/http2/HttpOverHttp2Test.kt b/okhttp/src/jvmTest/java/okhttp3/internal/http2/HttpOverHttp2Test.kt index cdaecad3d..84ff3ac1a 100644 --- a/okhttp/src/jvmTest/java/okhttp3/internal/http2/HttpOverHttp2Test.kt +++ b/okhttp/src/jvmTest/java/okhttp3/internal/http2/HttpOverHttp2Test.kt @@ -45,6 +45,7 @@ import okhttp3.Cookie import okhttp3.Credentials.basic import okhttp3.EventListener import okhttp3.Headers.Companion.headersOf +import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.Interceptor import okhttp3.MediaType import okhttp3.MediaType.Companion.toMediaType @@ -160,11 +161,7 @@ class HttpOverHttp2Test { .setBody("ABCDE") .setStatus("HTTP/1.1 200 Sweet") ) - val call = client.newCall( - Request.Builder() - .url(server.url("/foo")) - .build() - ) + val call = client.newCall(Request(server.url("/foo"))) val response = call.execute() assertThat(response.body.string()).isEqualTo("ABCDE") assertThat(response.code).isEqualTo(200) @@ -183,11 +180,7 @@ class HttpOverHttp2Test { responseWithoutBody.status = "HTTP/1.1 204" responseWithoutBody.removeHeader("Content-Length") server.enqueue(responseWithoutBody) - val call = client.newCall( - Request.Builder() - .url(server.url("/foo")) - .build() - ) + val call = client.newCall(Request(server.url("/foo"))) val response = call.execute() // Body contains nothing. @@ -229,11 +222,7 @@ class HttpOverHttp2Test { fun emptyResponse(protocol: Protocol, mockWebServer: MockWebServer) { setUp(protocol, mockWebServer) server.enqueue(MockResponse()) - val call = client.newCall( - Request.Builder() - .url(server.url("/foo")) - .build() - ) + val call = client.newCall(Request(server.url("/foo"))) val response = call.execute() assertThat(response.body.byteStream().read()).isEqualTo(-1) response.body.close() @@ -245,16 +234,16 @@ class HttpOverHttp2Test { val postBytes = "FGHIJ".toByteArray() server.enqueue(MockResponse().setBody("ABCDE")) val call = client.newCall( - Request.Builder() - .url(server.url("/foo")) - .post(object : RequestBody() { + Request( + url = server.url("/foo"), + body = object : RequestBody() { override fun contentType(): MediaType = "text/plain; charset=utf-8".toMediaType() override fun writeTo(sink: BufferedSink) { sink.write(postBytes) } - }) - .build() + }, + ) ) val response = call.execute() assertThat(response.body.string()).isEqualTo("ABCDE") @@ -270,9 +259,9 @@ class HttpOverHttp2Test { val postBytes = "FGHIJ".toByteArray() server.enqueue(MockResponse().setBody("ABCDE")) val call = client.newCall( - Request.Builder() - .url(server.url("/foo")) - .post(object : RequestBody() { + Request( + url = server.url("/foo"), + body = object : RequestBody() { override fun contentType(): MediaType = "text/plain; charset=utf-8".toMediaType() override fun contentLength(): Long = postBytes.size.toLong() @@ -280,8 +269,8 @@ class HttpOverHttp2Test { override fun writeTo(sink: BufferedSink) { sink.write(postBytes) } - }) - .build() + }, + ) ) val response = call.execute() assertThat(response.body.string()).isEqualTo("ABCDE") @@ -301,9 +290,9 @@ class HttpOverHttp2Test { val postBytes = "FGHIJ".toByteArray() server.enqueue(MockResponse().setBody("ABCDE")) val call = client.newCall( - Request.Builder() - .url(server.url("/foo")) - .post(object : RequestBody() { + Request( + url = server.url("/foo"), + body = object : RequestBody() { override fun contentType(): MediaType = "text/plain; charset=utf-8".toMediaType() override fun contentLength(): Long = postBytes.size.toLong() @@ -313,8 +302,8 @@ class HttpOverHttp2Test { sink.flush() // Http2Connection.writeData subject to write window sink.close() // Http2Connection.writeData empty frame } - }) - .build() + }, + ) ) val response = call.execute() assertThat(response.body.string()).isEqualTo("ABCDE") @@ -330,16 +319,8 @@ class HttpOverHttp2Test { setUp(protocol, mockWebServer) server.enqueue(MockResponse().setBody("ABCDEF")) server.enqueue(MockResponse().setBody("GHIJKL")) - val call1 = client.newCall( - Request.Builder() - .url(server.url("/r1")) - .build() - ) - val call2 = client.newCall( - Request.Builder() - .url(server.url("/r1")) - .build() - ) + val call1 = client.newCall(Request(server.url("/r1"))) + val call2 = client.newCall(Request(server.url("/r1"))) val response1 = call1.execute() val response2 = call2.execute() assertThat(response1.body.source().readUtf8(3)).isEqualTo("ABC") @@ -363,11 +344,7 @@ class HttpOverHttp2Test { MockResponse() .setBody("abc") ) - val call1 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call1 = client.newCall(Request(server.url("/"))) val response1 = call1.execute() waitForDataFrames(Http2Connection.OKHTTP_CLIENT_WINDOW_SIZE) @@ -377,11 +354,7 @@ class HttpOverHttp2Test { assertThat(response1.body.source().discard(1, TimeUnit.SECONDS)) .overridingErrorMessage("Call should not have completed successfully.") .isFalse - val call2 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call2 = client.newCall(Request(server.url("/"))) val response2 = call2.execute() assertThat(response2.body.string()).isEqualTo("abc") } @@ -414,11 +387,7 @@ class HttpOverHttp2Test { MockResponse() .setBody("XXX") ) - val call1 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call1 = client.newCall(Request(server.url("/"))) val response1 = call1.execute() waitForDataFrames(Http2Connection.OKHTTP_CLIENT_WINDOW_SIZE) @@ -426,11 +395,7 @@ class HttpOverHttp2Test { // the connection flow-control window. call1.cancel() response1.close() - val call2 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call2 = client.newCall(Request(server.url("/"))) val response2 = call2.execute() assertThat(response2.body.string()).isEqualTo("abc") } @@ -448,11 +413,7 @@ class HttpOverHttp2Test { MockResponse() .setBody("abc") ) - val call1 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call1 = client.newCall(Request(server.url("/"))) val response1 = call1.execute() waitForDataFrames(Http2Connection.OKHTTP_CLIENT_WINDOW_SIZE) assertThat(response1.body.contentLength()).isEqualTo( @@ -463,11 +424,7 @@ class HttpOverHttp2Test { // Make a second call that should transmit the response headers. The response body won't be // transmitted until the flow-control window is updated from the first request. - val call2 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call2 = client.newCall(Request(server.url("/"))) val response2 = call2.execute() assertThat(response2.code).isEqualTo(200) @@ -501,11 +458,7 @@ class HttpOverHttp2Test { .addHeader("Content-Encoding: gzip") .setBody(gzip("ABCABCABC")) ) - val call = client.newCall( - Request.Builder() - .url(server.url("/r1")) - .build() - ) + val call = client.newCall(Request(server.url("/r1"))) val response = call.execute() assertThat(response.body.string()).isEqualTo("ABCABCABC") } @@ -527,11 +480,7 @@ class HttpOverHttp2Test { client = client.newBuilder() .authenticator(RecordingOkAuthenticator(credential, "Basic")) .build() - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() assertThat(response.body.string()).isEqualTo("Successful auth!") val denied = server.takeRequest() @@ -550,11 +499,7 @@ class HttpOverHttp2Test { .setBody("This page has moved!") ) server.enqueue(MockResponse().setBody("This is the new location!")) - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() assertThat(response.body.string()).isEqualTo("This is the new location!") val request1 = server.takeRequest() @@ -567,11 +512,7 @@ class HttpOverHttp2Test { fun readAfterLastByte(protocol: Protocol, mockWebServer: MockWebServer) { setUp(protocol, mockWebServer) server.enqueue(MockResponse().setBody("ABC")) - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() val inputStream = response.body.byteStream() assertThat(inputStream.read()).isEqualTo('A'.code) @@ -592,11 +533,7 @@ class HttpOverHttp2Test { .build() // Make a call expecting a timeout reading the response headers. - val call1 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call1 = client.newCall(Request(server.url("/"))) try { call1.execute() fail("Should have timed out!") @@ -605,11 +542,7 @@ class HttpOverHttp2Test { } // Confirm that a subsequent request on the same connection is not impacted. - val call2 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call2 = client.newCall(Request(server.url("/"))) val response2 = call2.execute() assertThat(response2.body.string()).isEqualTo("A") @@ -635,11 +568,7 @@ class HttpOverHttp2Test { client = client.newBuilder() .readTimeout(Duration.ofSeconds(2)) .build() - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() assertThat(response.body.string()).isEqualTo(String(body)) } @@ -668,11 +597,7 @@ class HttpOverHttp2Test { .build() // Make a call expecting a timeout reading the response body. - val call1 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call1 = client.newCall(Request(server.url("/"))) val response1 = call1.execute() try { response1.body.string() @@ -682,11 +607,7 @@ class HttpOverHttp2Test { } // Confirm that a subsequent request on the same connection is not impacted. - val call2 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call2 = client.newCall(Request(server.url("/"))) val response2 = call2.execute() assertThat(response2.body.string()).isEqualTo(body) @@ -745,28 +666,16 @@ class HttpOverHttp2Test { .addHeader("cache-control: max-age=60") .setBody("A") ) - val call1 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call1 = client.newCall(Request(server.url("/"))) val response1 = call1.execute() assertThat(response1.body.string()).isEqualTo("A") assertThat(cache.requestCount()).isEqualTo(1) assertThat(cache.networkCount()).isEqualTo(1) assertThat(cache.hitCount()).isEqualTo(0) - val call2 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call2 = client.newCall(Request(server.url("/"))) val response2 = call2.execute() assertThat(response2.body.string()).isEqualTo("A") - val call3 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call3 = client.newCall(Request(server.url("/"))) val response3 = call3.execute() assertThat(response3.body.string()).isEqualTo("A") assertThat(cache.requestCount()).isEqualTo(3) @@ -789,21 +698,13 @@ class HttpOverHttp2Test { MockResponse() .setResponseCode(HttpURLConnection.HTTP_NOT_MODIFIED) ) - val call1 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call1 = client.newCall(Request(server.url("/"))) val response1 = call1.execute() assertThat(response1.body.string()).isEqualTo("A") assertThat(cache.requestCount()).isEqualTo(1) assertThat(cache.networkCount()).isEqualTo(1) assertThat(cache.hitCount()).isEqualTo(0) - val call2 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call2 = client.newCall(Request(server.url("/"))) val response2 = call2.execute() assertThat(response2.body.string()).isEqualTo("A") assertThat(cache.requestCount()).isEqualTo(2) @@ -827,19 +728,11 @@ class HttpOverHttp2Test { .addHeader("cache-control: max-age=60") .setBody("EFGH") ) - val call1 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call1 = client.newCall(Request(server.url("/"))) val response1 = call1.execute() assertThat(response1.body.source().readUtf8(2)).isEqualTo("AB") response1.body.close() - val call2 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call2 = client.newCall(Request(server.url("/"))) val response2 = call2.execute() assertThat(response2.body.source().readUtf8()).isEqualTo("ABCD") response2.body.close() @@ -859,11 +752,7 @@ class HttpOverHttp2Test { .cookieJar(cookieJar) .build() server.enqueue(MockResponse()) - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() assertThat(response.body.string()).isEqualTo("") val request = server.takeRequest() @@ -881,11 +770,7 @@ class HttpOverHttp2Test { MockResponse() .addHeader("set-cookie: a=b") ) - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() assertThat(response.body.string()).isEqualTo("") cookieJar.assertResponseCookies("a=b; path=/") @@ -904,21 +789,13 @@ class HttpOverHttp2Test { ) // Disconnect before the stream is created. A connection is still established! - val call1 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call1 = client.newCall(Request(server.url("/"))) val response = call1.execute() call1.cancel() // That connection is pooled, and it works. assertThat(client.connectionPool.connectionCount()).isEqualTo(1) - val call2 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call2 = client.newCall(Request(server.url("/"))) val response2 = call2.execute() assertThat(response2.body.string()).isEqualTo("def") assertThat(server.takeRequest().sequenceNumber).isEqualTo(0) @@ -941,11 +818,7 @@ class HttpOverHttp2Test { MockResponse() .setBody("abc") ) - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) try { call.execute() fail() @@ -972,9 +845,7 @@ class HttpOverHttp2Test { .setBody("abc") ) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) val response = client.newCall(request).execute() assertThat(response.body.string()).isEqualTo("abc") assertThat(server.takeRequest().sequenceNumber).isEqualTo(0) @@ -1009,9 +880,7 @@ class HttpOverHttp2Test { .setHttp2ErrorCode(ErrorCode.REFUSED_STREAM.httpCode) ) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) try { client.newCall(request).execute() fail() @@ -1037,9 +906,7 @@ class HttpOverHttp2Test { MockResponse() .setBody("abc") ) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) // First call fails because it only has one route. try { @@ -1079,9 +946,7 @@ class HttpOverHttp2Test { MockResponse() .setBody("def") ) - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) // First call makes a new connection and fails because it is the only route. try { @@ -1127,11 +992,7 @@ class HttpOverHttp2Test { MockResponse() .setBody("abc") ) - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) try { call.execute() fail() @@ -1169,11 +1030,7 @@ class HttpOverHttp2Test { client = client.newBuilder() .dns(DoubleInetAddressDns()) .build() - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() assertThat(response.body.string()).isEqualTo("abc") @@ -1205,11 +1062,7 @@ class HttpOverHttp2Test { client = client.newBuilder() .dns(DoubleInetAddressDns()) .build() - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() assertThat(response.body.string()).isEqualTo("abc") @@ -1249,11 +1102,7 @@ class HttpOverHttp2Test { callAndCancel(0, responseDequeuedLatches[0], requestCanceledLatches[0]) // Make a second request to ensure the connection is reused. - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() assertThat(response.body.string()).isEqualTo("def") assertThat(server.takeRequest().sequenceNumber).isEqualTo(1) @@ -1295,11 +1144,7 @@ class HttpOverHttp2Test { callAndCancel(1, responseDequeuedLatches[1], requestCanceledLatches[1]) // Make a third request to ensure the connection is reused. - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() assertThat(response.body.string()).isEqualTo("ghi") assertThat(server.takeRequest().sequenceNumber).isEqualTo(2) @@ -1332,11 +1177,7 @@ class HttpOverHttp2Test { expectedSequenceNumber: Int, responseDequeuedLatch: CountDownLatch?, requestCanceledLatch: CountDownLatch? ) { - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) val latch = CountDownLatch(1) call.enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { @@ -1392,11 +1233,7 @@ class HttpOverHttp2Test { client = client.newBuilder() .retryOnConnectionFailure(false) .build() - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) try { call.execute() fail() @@ -1457,9 +1294,7 @@ class HttpOverHttp2Test { } // Make the first request waiting until we get our auth challenge. - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) blockingAuthClient.newCall(request).enqueue(callback) val response1 = responses.take() assertThat(response1).isEqualTo("") @@ -1490,11 +1325,7 @@ class HttpOverHttp2Test { .addHeaderLenient("Alpha", "α") .addHeaderLenient("β", "Beta") ) - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() response.close() assertThat(response.header("Alpha")).isEqualTo("α") @@ -1514,11 +1345,7 @@ class HttpOverHttp2Test { .setStatus("HTTP/1.1 200 Sweet") .withPush(pushPromise) ) - val call = client.newCall( - Request.Builder() - .url(server.url("/foo")) - .build() - ) + val call = client.newCall(Request(server.url("/foo"))) val response = call.execute() assertThat(response.body.string()).isEqualTo("ABCDE") assertThat(response.code).isEqualTo(200) @@ -1547,11 +1374,7 @@ class HttpOverHttp2Test { .setStatus("HTTP/1.1 200 Sweet") .withPush(pushPromise) ) - val call = client.newCall( - Request.Builder() - .url(server.url("/foo")) - .build() - ) + val call = client.newCall(Request(server.url("/foo"))) val response = call.execute() assertThat(response.body.string()).isEqualTo("ABCDE") assertThat(response.code).isEqualTo(200) @@ -1634,11 +1457,7 @@ class HttpOverHttp2Test { .setBodyDelay(750, TimeUnit.MILLISECONDS) .setBody("ABC") ) - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() assertThat(response.body.string()).isEqualTo("ABC") assertThat(response.protocol).isEqualTo(protocol) @@ -1678,11 +1497,7 @@ class HttpOverHttp2Test { ) // Make a call. It'll fail as soon as our pings detect a problem. - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) val executeAtNanos = System.nanoTime() try { call.execute() @@ -1725,11 +1540,7 @@ class HttpOverHttp2Test { ) // The first call times out. - val call1 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call1 = client.newCall(Request(server.url("/"))) try { call1.execute() fail() @@ -1738,11 +1549,7 @@ class HttpOverHttp2Test { } // The second call times out because it uses the same bad connection. - val call2 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call2 = client.newCall(Request(server.url("/"))) try { call2.execute() fail() @@ -1751,11 +1558,7 @@ class HttpOverHttp2Test { // But after the degraded pong timeout, that connection is abandoned. Thread.sleep(TimeUnit.NANOSECONDS.toMillis(Http2Connection.DEGRADED_PONG_TIMEOUT_NS.toLong())) - val call3 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call3 = client.newCall(Request(server.url("/"))) call3.execute().use { response -> assertThat( response.body.string() @@ -1784,11 +1587,7 @@ class HttpOverHttp2Test { ) // The first call times out. - val call1 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call1 = client.newCall(Request(server.url("/"))) try { call1.execute().use { response -> response.body.string() @@ -1798,11 +1597,7 @@ class HttpOverHttp2Test { } // The second call succeeds. - val call2 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call2 = client.newCall(Request(server.url("/"))) call2.execute().use { response -> assertThat( response.body.string() @@ -1811,11 +1606,7 @@ class HttpOverHttp2Test { // Calls succeed after the degraded pong timeout because the degraded pong was received. Thread.sleep(TimeUnit.NANOSECONDS.toMillis(Http2Connection.DEGRADED_PONG_TIMEOUT_NS.toLong())) - val call3 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call3 = client.newCall(Request(server.url("/"))) call3.execute().use { response -> assertThat( response.body.string() @@ -1859,11 +1650,7 @@ class HttpOverHttp2Test { // Read & write a full request to confirm settings are accepted. server.enqueue(MockResponse().withSettings(settings)) - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() assertThat(response.body.string()).isEqualTo("") server.enqueue( @@ -1878,23 +1665,11 @@ class HttpOverHttp2Test { MockResponse() .setBody("GHI") ) - val call1 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call1 = client.newCall(Request(server.url("/"))) val response1 = call1.execute() - val call2 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call2 = client.newCall(Request(server.url("/"))) val response2 = call2.execute() - val call3 = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call3 = client.newCall(Request(server.url("/"))) val response3 = call3.execute() assertThat(response1.body.string()).isEqualTo("ABC") assertThat(response2.body.string()).isEqualTo("DEF") @@ -1932,21 +1707,13 @@ class HttpOverHttp2Test { connections.add(connection as RealConnection) } }).build() - val call1 = localClient.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call1 = localClient.newCall(Request(server.url("/"))) val response1 = call1.execute() assertThat(response1.body.string()).isEqualTo("ABC") // Add delays for DISCONNECT_AT_END to propogate waitForConnectionShutdown(connections[0]) - val call2 = localClient.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call2 = localClient.newCall(Request(server.url("/"))) val response2 = call2.execute() assertThat(response2.body.string()).isEqualTo("DEF") assertThat(server.takeRequest().sequenceNumber).isEqualTo(0) @@ -2005,11 +1772,7 @@ class HttpOverHttp2Test { } }) .build() - val call = client2.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client2.newCall(Request(server.url("/"))) val response = call.execute() assertThat(response.body.string()).isEqualTo("DEF") assertThat(server.takeRequest().sequenceNumber).isEqualTo(0) @@ -2129,11 +1892,7 @@ class HttpOverHttp2Test { client = client.newBuilder() .proxy(server.toProxyAddress()) .build() - val call1 = client.newCall( - Request.Builder() - .url("https://android.com/call1") - .build() - ) + val call1 = client.newCall(Request("https://android.com/call1".toHttpUrl())) val response2 = call1.execute() assertThat(response2.body.string()).isEqualTo("call1 response") val call1Connect = server.takeRequest() @@ -2166,11 +1925,7 @@ class HttpOverHttp2Test { }) .build() server.enqueue(MockResponse()) - val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .build() - ) + val call = client.newCall(Request(server.url("/"))) val response = call.execute() assertThat(response.body.string()).isEqualTo("") val recordedRequest = server.takeRequest() @@ -2249,16 +2004,16 @@ class HttpOverHttp2Test { server.enqueue(MockResponse()) val callReference = AtomicReference() val call = client.newCall( - Request.Builder() - .url(server.url("/")) - .post(object : RequestBody() { + Request( + url = server.url("/"), + body = object : RequestBody() { override fun contentType() = "text/plain; charset=utf-8".toMediaType() override fun writeTo(sink: BufferedSink) { callReference.get()!!.cancel() } - }) - .build() + }, + ) ) callReference.set(call) try { diff --git a/okhttp/src/nonJvmMain/kotlin/okhttp3/Request.kt b/okhttp/src/nonJvmMain/kotlin/okhttp3/Request.kt index 082ad6dc4..77a117f1c 100644 --- a/okhttp/src/nonJvmMain/kotlin/okhttp3/Request.kt +++ b/okhttp/src/nonJvmMain/kotlin/okhttp3/Request.kt @@ -30,17 +30,43 @@ import okhttp3.internal.commonPost import okhttp3.internal.commonPut import okhttp3.internal.commonRemoveHeader -actual class Request internal constructor( - actual val url: String, - actual val method: String, - actual val headers: Headers, - actual val body: RequestBody?, -) { +actual class Request internal actual constructor(builder: Builder) { + actual val url: String = checkNotNull(builder.url) { "url == null" } + actual val method: String = builder.method + actual val headers: Headers = builder.headers.build() + actual val body: RequestBody? = builder.body + internal actual var lazyCacheControl: CacheControl? = null actual val isHttps: Boolean get() = url.startsWith("https://") + /** + * Constructs a new request. + * + * Use [Builder] for more fluent construction, including helper methods for various HTTP methods. + * + * @param method defaults to "GET" if [body] is null, and "POST" otherwise. + */ + constructor( + url: String, + headers: Headers = Headers.headersOf(), + method: String = "\u0000", // Sentinel value chooses based on what the body is. + body: RequestBody? = null, + ) : this( + Builder() + .url(url) + .headers(headers) + .method( + when { + method != "\u0000" -> method + body != null -> "POST" + else -> "GET" + }, + body + ) + ) + actual fun header(name: String): String? = commonHeader(name) actual fun headers(name: String): List = commonHeaders(name) @@ -153,13 +179,6 @@ actual class Request internal constructor( // } // } - actual open fun build(): Request { - return Request( - checkNotNull(url) { "url == null" }, - method, - headers.build(), - body, - ) - } + actual open fun build() = Request(this) } } diff --git a/samples/guide/src/main/java/okhttp3/recipes/kt/DevServer.kt b/samples/guide/src/main/java/okhttp3/recipes/kt/DevServer.kt index 50288f12d..a3c1b5812 100644 --- a/samples/guide/src/main/java/okhttp3/recipes/kt/DevServer.kt +++ b/samples/guide/src/main/java/okhttp3/recipes/kt/DevServer.kt @@ -46,9 +46,7 @@ class DevServer { fun run() { try { - val request = Request.Builder() - .url(server.url("/")) - .build() + val request = Request(server.url("/")) client.newCall(request).execute().use { response -> if (!response.isSuccessful) throw IOException("Unexpected code $response") diff --git a/samples/guide/src/main/java/okhttp3/recipes/kt/PostFile.kt b/samples/guide/src/main/java/okhttp3/recipes/kt/PostFile.kt index b55a4b31b..a1f9f55a4 100644 --- a/samples/guide/src/main/java/okhttp3/recipes/kt/PostFile.kt +++ b/samples/guide/src/main/java/okhttp3/recipes/kt/PostFile.kt @@ -17,6 +17,7 @@ package okhttp3.recipes.kt import java.io.File import java.io.IOException +import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient import okhttp3.Request @@ -28,10 +29,10 @@ class PostFile { fun run() { val file = File("README.md") - val request = Request.Builder() - .url("https://api.github.com/markdown/raw") - .post(file.asRequestBody(MEDIA_TYPE_MARKDOWN)) - .build() + val request = Request( + url = "https://api.github.com/markdown/raw".toHttpUrl(), + body = file.asRequestBody(MEDIA_TYPE_MARKDOWN), + ) client.newCall(request).execute().use { response -> if (!response.isSuccessful) throw IOException("Unexpected code $response") diff --git a/samples/guide/src/main/java/okhttp3/recipes/kt/PostForm.kt b/samples/guide/src/main/java/okhttp3/recipes/kt/PostForm.kt index 617b64818..ed38886a9 100644 --- a/samples/guide/src/main/java/okhttp3/recipes/kt/PostForm.kt +++ b/samples/guide/src/main/java/okhttp3/recipes/kt/PostForm.kt @@ -17,6 +17,7 @@ package okhttp3.recipes.kt import java.io.IOException import okhttp3.FormBody +import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.OkHttpClient import okhttp3.Request @@ -27,10 +28,10 @@ class PostForm { val formBody = FormBody.Builder() .add("search", "Jurassic Park") .build() - val request = Request.Builder() - .url("https://en.wikipedia.org/w/index.php") - .post(formBody) - .build() + val request = Request( + url = "https://en.wikipedia.org/w/index.php".toHttpUrl(), + body = formBody, + ) client.newCall(request).execute().use { response -> if (!response.isSuccessful) throw IOException("Unexpected code $response") diff --git a/samples/guide/src/main/java/okhttp3/recipes/kt/PostStreaming.kt b/samples/guide/src/main/java/okhttp3/recipes/kt/PostStreaming.kt index a0abf3078..017b8a00f 100644 --- a/samples/guide/src/main/java/okhttp3/recipes/kt/PostStreaming.kt +++ b/samples/guide/src/main/java/okhttp3/recipes/kt/PostStreaming.kt @@ -16,6 +16,7 @@ package okhttp3.recipes.kt import java.io.IOException +import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient import okhttp3.Request @@ -46,10 +47,10 @@ class PostStreaming { } } - val request = Request.Builder() - .url("https://api.github.com/markdown/raw") - .post(requestBody) - .build() + val request = Request( + url = "https://api.github.com/markdown/raw".toHttpUrl(), + body = requestBody, + ) client.newCall(request).execute().use { response -> if (!response.isSuccessful) throw IOException("Unexpected code $response") diff --git a/samples/guide/src/main/java/okhttp3/recipes/kt/PostString.kt b/samples/guide/src/main/java/okhttp3/recipes/kt/PostString.kt index ea19558e6..d2a6ac8c8 100644 --- a/samples/guide/src/main/java/okhttp3/recipes/kt/PostString.kt +++ b/samples/guide/src/main/java/okhttp3/recipes/kt/PostString.kt @@ -16,6 +16,7 @@ package okhttp3.recipes.kt import java.io.IOException +import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient import okhttp3.Request @@ -34,10 +35,10 @@ class PostString { | * _1.2_ August 11, 2013 |""".trimMargin() - val request = Request.Builder() - .url("https://api.github.com/markdown/raw") - .post(postBody.toRequestBody(MEDIA_TYPE_MARKDOWN)) - .build() + val request = Request( + url = "https://api.github.com/markdown/raw".toHttpUrl(), + body = postBody.toRequestBody(MEDIA_TYPE_MARKDOWN), + ) client.newCall(request).execute().use { response -> if (!response.isSuccessful) throw IOException("Unexpected code $response")