1
0
mirror of https://github.com/square/okhttp.git synced 2025-08-01 16:06:56 +03:00

Add a proper Kotlin constructor for Request (#7208)

* Add a proper Kotlin constructor for Request

This turns out to be very useful throughout our test suite.

* Dump updated API

* Fix multipleTags Kotlin conversion
This commit is contained in:
Jesse Wilson
2022-04-04 09:44:43 -04:00
committed by GitHub
parent 95c6ad9663
commit 79f50e1911
33 changed files with 1404 additions and 1531 deletions

View File

@ -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)

View File

@ -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() {

View File

@ -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))
}

View File

@ -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 <init> (Lokhttp3/HttpUrl;Lokhttp3/Headers;Ljava/lang/String;Lokhttp3/RequestBody;)V
public synthetic fun <init> (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;

View File

@ -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

View File

@ -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)

View File

@ -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<Class<*>, 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<Class<*>, 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<String> = 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)
}
}

View File

@ -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.

View File

@ -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")

View File

@ -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!! }
}
}

View File

@ -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()

View File

@ -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<Unit>()
@ -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<Unit>()
@ -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<Unit>()
@ -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<Response?> { 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<String?>()
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<Unit>()
@ -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<Unit>()
@ -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<Unit>()
@ -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()

View File

@ -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(

View File

@ -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<IOException> {
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)

View File

@ -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("")

View File

@ -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()

View File

@ -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)

View File

@ -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")
}

View File

@ -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()

View File

@ -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();
}
}

View File

@ -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()
}
}

View File

@ -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<IOException>("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")
}

View File

@ -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)

File diff suppressed because it is too large Load Diff

View File

@ -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) }
}

View File

@ -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())
}

View File

@ -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<Any?>("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<Any?>()
@ -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<Any?>()
@ -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<Any?>()
@ -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<Any?>()
@ -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<Any?>()
@ -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<Any?>()
@ -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<Call?>()
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 {

View File

@ -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<String> = 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)
}
}

View File

@ -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")

View File

@ -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")

View File

@ -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")

View File

@ -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")

View File

@ -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")