mirror of
https://github.com/square/okhttp.git
synced 2025-07-31 05:04:26 +03:00
Idiomatic Kotlin for Response.kt
- define `@get:JvmName(...)` for the following vals in constructor instead of passing `builder: Builder`. - `request: Request` - `protocol: Protocol` - `message: String` - `code: Int` - `handshake: Handshake?` - `headers: Headers` - `body: ResponseBody?` - `networkResponse: Response?` - `cacheResponse: Response?` - `priorResponse: Response?` - `sentRequestAtMillis: Long` - `receivedResponseAtMillis: Long` - `exchange: Exchange?` - add `@Deprecated(...)` to the following functions. - `fun request(): Request` - `fun protocol(): Protocol` - `fun message(): String` - `fun code(): Int` - `fun handshake(): Handshake?` - `fun headers(): Headers` - `fun body(): ResponseBody?` - `fun networkResponse(): Response?` - `fun cacheResponse(): Response?` - `fun priorResponse(): Response?` - `fun sentRequestAtMillis(): Long` - `fun receivedResponseAtMillis(): Long` - `fun cacheControl(): CacheControl` - clean up code where `()`(parentheses) is unnecessarily used.
This commit is contained in:
@ -130,7 +130,7 @@ class Main : Runnable {
|
|||||||
val response = client.newCall(request).execute()
|
val response = client.newCall(request).execute()
|
||||||
if (showHeaders) {
|
if (showHeaders) {
|
||||||
println(StatusLine.get(response))
|
println(StatusLine.get(response))
|
||||||
val headers = response.headers()
|
val headers = response.headers
|
||||||
for ((name, value) in headers) {
|
for ((name, value) in headers) {
|
||||||
println("$name: $value")
|
println("$name: $value")
|
||||||
}
|
}
|
||||||
@ -139,13 +139,13 @@ class Main : Runnable {
|
|||||||
|
|
||||||
// Stream the response to the System.out as it is returned from the server.
|
// Stream the response to the System.out as it is returned from the server.
|
||||||
val out = System.out.sink()
|
val out = System.out.sink()
|
||||||
val source = response.body()!!.source()
|
val source = response.body!!.source()
|
||||||
while (!source.exhausted()) {
|
while (!source.exhausted()) {
|
||||||
out.write(source.buffer, source.buffer.size)
|
out.write(source.buffer, source.buffer.size)
|
||||||
out.flush()
|
out.flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
response.body()!!.close()
|
response.body!!.close()
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -202,7 +202,7 @@ class DnsOverHttps internal constructor(builder: Builder) : Dns {
|
|||||||
|
|
||||||
val cacheResponse = client.newCall(cacheRequest).execute()
|
val cacheResponse = client.newCall(cacheRequest).execute()
|
||||||
|
|
||||||
if (cacheResponse.code() != 504) {
|
if (cacheResponse.code != 504) {
|
||||||
return cacheResponse
|
return cacheResponse
|
||||||
}
|
}
|
||||||
} catch (ioe: IOException) {
|
} catch (ioe: IOException) {
|
||||||
@ -216,16 +216,16 @@ class DnsOverHttps internal constructor(builder: Builder) : Dns {
|
|||||||
|
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
private fun readResponse(hostname: String, response: Response): List<InetAddress> {
|
private fun readResponse(hostname: String, response: Response): List<InetAddress> {
|
||||||
if (response.cacheResponse() == null && response.protocol() !== Protocol.HTTP_2) {
|
if (response.cacheResponse == null && response.protocol !== Protocol.HTTP_2) {
|
||||||
Platform.get().log(Platform.WARN, "Incorrect protocol: ${response.protocol()}", null)
|
Platform.get().log(Platform.WARN, "Incorrect protocol: ${response.protocol}", null)
|
||||||
}
|
}
|
||||||
|
|
||||||
response.use {
|
response.use {
|
||||||
if (!response.isSuccessful) {
|
if (!response.isSuccessful) {
|
||||||
throw IOException("response: " + response.code() + " " + response.message())
|
throw IOException("response: " + response.code + " " + response.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
val body = response.body()
|
val body = response.body
|
||||||
|
|
||||||
if (body!!.contentLength() > MAX_RESPONSE_SIZE) {
|
if (body!!.contentLength() > MAX_RESPONSE_SIZE) {
|
||||||
throw IOException(
|
throw IOException(
|
||||||
|
@ -223,21 +223,21 @@ class HttpLoggingInterceptor @JvmOverloads constructor(
|
|||||||
|
|
||||||
val tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs)
|
val tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs)
|
||||||
|
|
||||||
val responseBody = response.body()!!
|
val responseBody = response.body!!
|
||||||
val contentLength = responseBody.contentLength()
|
val contentLength = responseBody.contentLength()
|
||||||
val bodySize = if (contentLength != -1L) "$contentLength-byte" else "unknown-length"
|
val bodySize = if (contentLength != -1L) "$contentLength-byte" else "unknown-length"
|
||||||
logger.log(
|
logger.log(
|
||||||
"<-- ${response.code()}${if (response.message().isEmpty()) "" else ' ' + response.message()} ${response.request().url} (${tookMs}ms${if (!logHeaders) ", $bodySize body" else ""})")
|
"<-- ${response.code}${if (response.message.isEmpty()) "" else ' ' + response.message} ${response.request.url} (${tookMs}ms${if (!logHeaders) ", $bodySize body" else ""})")
|
||||||
|
|
||||||
if (logHeaders) {
|
if (logHeaders) {
|
||||||
val headers = response.headers()
|
val headers = response.headers
|
||||||
for (i in 0 until headers.size) {
|
for (i in 0 until headers.size) {
|
||||||
logHeader(headers, i)
|
logHeader(headers, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!logBody || !response.promisesBody()) {
|
if (!logBody || !response.promisesBody()) {
|
||||||
logger.log("<-- END HTTP")
|
logger.log("<-- END HTTP")
|
||||||
} else if (bodyHasUnknownEncoding(response.headers())) {
|
} else if (bodyHasUnknownEncoding(response.headers)) {
|
||||||
logger.log("<-- END HTTP (encoded body omitted)")
|
logger.log("<-- END HTTP (encoded body omitted)")
|
||||||
} else {
|
} else {
|
||||||
val source = responseBody.source()
|
val source = responseBody.source()
|
||||||
|
@ -53,7 +53,7 @@ class RealEventSource(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val body = response.body()!!
|
val body = response.body!!
|
||||||
|
|
||||||
if (!body.isEventStream()) {
|
if (!body.isEventStream()) {
|
||||||
listener.onFailure(this,
|
listener.onFailure(this,
|
||||||
|
@ -34,7 +34,7 @@ object EventSources {
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun processResponse(response: Response, listener: EventSourceListener) {
|
fun processResponse(response: Response, listener: EventSourceListener) {
|
||||||
val eventSource = RealEventSource(response.request(), listener)
|
val eventSource = RealEventSource(response.request, listener)
|
||||||
eventSource.processResponse(response)
|
eventSource.processResponse(response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,9 @@ class JavaNetAuthenticator : okhttp3.Authenticator {
|
|||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
override fun authenticate(route: Route?, response: Response): Request? {
|
override fun authenticate(route: Route?, response: Response): Request? {
|
||||||
val challenges = response.challenges()
|
val challenges = response.challenges()
|
||||||
val request = response.request()
|
val request = response.request
|
||||||
val url = request.url
|
val url = request.url
|
||||||
val proxyAuthorization = response.code() == 407
|
val proxyAuthorization = response.code == 407
|
||||||
val proxy = route?.proxy ?: Proxy.NO_PROXY
|
val proxy = route?.proxy ?: Proxy.NO_PROXY
|
||||||
|
|
||||||
for (challenge in challenges) {
|
for (challenge in challenges) {
|
||||||
|
@ -174,7 +174,7 @@ class Cache internal constructor(
|
|||||||
|
|
||||||
val response = entry.response(snapshot)
|
val response = entry.response(snapshot)
|
||||||
if (!entry.matches(request, response)) {
|
if (!entry.matches(request, response)) {
|
||||||
response.body()?.closeQuietly()
|
response.body?.closeQuietly()
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,11 +182,11 @@ class Cache internal constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun put(response: Response): CacheRequest? {
|
internal fun put(response: Response): CacheRequest? {
|
||||||
val requestMethod = response.request().method
|
val requestMethod = response.request.method
|
||||||
|
|
||||||
if (HttpMethod.invalidatesCache(response.request().method)) {
|
if (HttpMethod.invalidatesCache(response.request.method)) {
|
||||||
try {
|
try {
|
||||||
remove(response.request())
|
remove(response.request)
|
||||||
} catch (_: IOException) {
|
} catch (_: IOException) {
|
||||||
// The cache cannot be written.
|
// The cache cannot be written.
|
||||||
}
|
}
|
||||||
@ -206,7 +206,7 @@ class Cache internal constructor(
|
|||||||
val entry = Entry(response)
|
val entry = Entry(response)
|
||||||
var editor: DiskLruCache.Editor? = null
|
var editor: DiskLruCache.Editor? = null
|
||||||
try {
|
try {
|
||||||
editor = cache.edit(key(response.request().url)) ?: return null
|
editor = cache.edit(key(response.request.url)) ?: return null
|
||||||
entry.writeTo(editor)
|
entry.writeTo(editor)
|
||||||
return RealCacheRequest(editor)
|
return RealCacheRequest(editor)
|
||||||
} catch (_: IOException) {
|
} catch (_: IOException) {
|
||||||
@ -222,7 +222,7 @@ class Cache internal constructor(
|
|||||||
|
|
||||||
internal fun update(cached: Response, network: Response) {
|
internal fun update(cached: Response, network: Response) {
|
||||||
val entry = Entry(network)
|
val entry = Entry(network)
|
||||||
val snapshot = (cached.body() as CacheResponseBody).snapshot
|
val snapshot = (cached.body as CacheResponseBody).snapshot
|
||||||
var editor: DiskLruCache.Editor? = null
|
var editor: DiskLruCache.Editor? = null
|
||||||
try {
|
try {
|
||||||
editor = snapshot.edit() // Returns null if snapshot is not current.
|
editor = snapshot.edit() // Returns null if snapshot is not current.
|
||||||
@ -537,16 +537,16 @@ class Cache internal constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal constructor(response: Response) {
|
internal constructor(response: Response) {
|
||||||
this.url = response.request().url.toString()
|
this.url = response.request.url.toString()
|
||||||
this.varyHeaders = response.varyHeaders()
|
this.varyHeaders = response.varyHeaders()
|
||||||
this.requestMethod = response.request().method
|
this.requestMethod = response.request.method
|
||||||
this.protocol = response.protocol()
|
this.protocol = response.protocol
|
||||||
this.code = response.code()
|
this.code = response.code
|
||||||
this.message = response.message()
|
this.message = response.message
|
||||||
this.responseHeaders = response.headers()
|
this.responseHeaders = response.headers
|
||||||
this.handshake = response.handshake()
|
this.handshake = response.handshake
|
||||||
this.sentRequestMillis = response.sentRequestAtMillis()
|
this.sentRequestMillis = response.sentRequestAtMillis
|
||||||
this.receivedResponseMillis = response.receivedResponseAtMillis()
|
this.receivedResponseMillis = response.receivedResponseAtMillis
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
@ -724,13 +724,13 @@ class Cache internal constructor(
|
|||||||
cachedRequest: Headers,
|
cachedRequest: Headers,
|
||||||
newRequest: Request
|
newRequest: Request
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return cachedResponse.headers().varyFields().none {
|
return cachedResponse.headers.varyFields().none {
|
||||||
cachedRequest.values(it) != newRequest.headers(it)
|
cachedRequest.values(it) != newRequest.headers(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if a Vary header contains an asterisk. Such responses cannot be cached. */
|
/** Returns true if a Vary header contains an asterisk. Such responses cannot be cached. */
|
||||||
fun Response.hasVaryAll() = "*" in headers().varyFields()
|
fun Response.hasVaryAll() = "*" in headers.varyFields()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the names of the request headers that need to be checked for equality when caching.
|
* Returns the names of the request headers that need to be checked for equality when caching.
|
||||||
@ -759,8 +759,8 @@ class Cache internal constructor(
|
|||||||
fun Response.varyHeaders(): Headers {
|
fun Response.varyHeaders(): Headers {
|
||||||
// Use the request headers sent over the network, since that's what the response varies on.
|
// Use the request headers sent over the network, since that's what the response varies on.
|
||||||
// Otherwise OkHttp-supplied headers like "Accept-Encoding: gzip" may be lost.
|
// Otherwise OkHttp-supplied headers like "Accept-Encoding: gzip" may be lost.
|
||||||
val requestHeaders = networkResponse()!!.request().headers
|
val requestHeaders = networkResponse!!.request.headers
|
||||||
val responseHeaders = headers()
|
val responseHeaders = headers
|
||||||
return varyHeaders(requestHeaders, responseHeaders)
|
return varyHeaders(requestHeaders, responseHeaders)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,25 +37,6 @@ import java.net.HttpURLConnection.HTTP_UNAUTHORIZED
|
|||||||
* [ResponseBody] for an explanation and examples.
|
* [ResponseBody] for an explanation and examples.
|
||||||
*/
|
*/
|
||||||
class Response internal constructor(
|
class Response internal constructor(
|
||||||
internal val request: Request,
|
|
||||||
internal val protocol: Protocol,
|
|
||||||
internal val message: String,
|
|
||||||
builder: Builder
|
|
||||||
) : Closeable {
|
|
||||||
internal val code: Int = builder.code
|
|
||||||
internal val handshake: Handshake? = builder.handshake
|
|
||||||
internal val headers: Headers = builder.headers.build()
|
|
||||||
internal val body: ResponseBody? = builder.body
|
|
||||||
internal val networkResponse: Response? = builder.networkResponse
|
|
||||||
internal val cacheResponse: Response? = builder.cacheResponse
|
|
||||||
internal val priorResponse: Response? = builder.priorResponse
|
|
||||||
internal val sentRequestAtMillis: Long = builder.sentRequestAtMillis
|
|
||||||
internal val receivedResponseAtMillis: Long = builder.receivedResponseAtMillis
|
|
||||||
internal val exchange: Exchange? = builder.exchange
|
|
||||||
|
|
||||||
@Volatile
|
|
||||||
private var cacheControl: CacheControl? = null // Lazily initialized.
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The wire-level request that initiated this HTTP response. This is not necessarily the same
|
* The wire-level request that initiated this HTTP response. This is not necessarily the same
|
||||||
* request issued by the application:
|
* request issued by the application:
|
||||||
@ -65,12 +46,96 @@ class Response internal constructor(
|
|||||||
* * It may be the request generated in response to an HTTP redirect or authentication
|
* * It may be the request generated in response to an HTTP redirect or authentication
|
||||||
* challenge. In this case the request URL may be different than the initial request URL.
|
* challenge. In this case the request URL may be different than the initial request URL.
|
||||||
*/
|
*/
|
||||||
fun request(): Request = request
|
@get:JvmName("request") val request: Request,
|
||||||
|
|
||||||
/** Returns the HTTP protocol, such as [Protocol.HTTP_1_1] or [Protocol.HTTP_1_0]. */
|
/** Returns the HTTP protocol, such as [Protocol.HTTP_1_1] or [Protocol.HTTP_1_0]. */
|
||||||
fun protocol(): Protocol = protocol
|
@get:JvmName("protocol") val protocol: Protocol,
|
||||||
|
|
||||||
|
/** Returns the HTTP status message. */
|
||||||
|
@get:JvmName("message") val message: String,
|
||||||
|
|
||||||
/** Returns the HTTP status code. */
|
/** Returns the HTTP status code. */
|
||||||
|
@get:JvmName("code") val code: Int,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the TLS handshake of the connection that carried this response, or null if the
|
||||||
|
* response was received without TLS.
|
||||||
|
*/
|
||||||
|
@get:JvmName("handshake") val handshake: Handshake?,
|
||||||
|
|
||||||
|
/** Returns the HTTP headers. */
|
||||||
|
@get:JvmName("headers") val headers: Headers,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a non-null value if this response was passed to [Callback.onResponse] or returned
|
||||||
|
* from [Call.execute]. Response bodies must be [closed][ResponseBody] and may
|
||||||
|
* be consumed only once.
|
||||||
|
*
|
||||||
|
* This always returns null on responses returned from [cacheResponse], [networkResponse],
|
||||||
|
* and [priorResponse].
|
||||||
|
*/
|
||||||
|
@get:JvmName("body") val body: ResponseBody?,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the raw response received from the network. Will be null if this response didn't use
|
||||||
|
* the network, such as when the response is fully cached. The body of the returned response
|
||||||
|
* should not be read.
|
||||||
|
*/
|
||||||
|
@get:JvmName("networkResponse") val networkResponse: Response?,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the raw response received from the cache. Will be null if this response didn't use
|
||||||
|
* the cache. For conditional get requests the cache response and network response may both be
|
||||||
|
* non-null. The body of the returned response should not be read.
|
||||||
|
*/
|
||||||
|
@get:JvmName("cacheResponse") val cacheResponse: Response?,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the response for the HTTP redirect or authorization challenge that triggered this
|
||||||
|
* response, or null if this response wasn't triggered by an automatic retry. The body of the
|
||||||
|
* returned response should not be read because it has already been consumed by the redirecting
|
||||||
|
* client.
|
||||||
|
*/
|
||||||
|
@get:JvmName("priorResponse") val priorResponse: Response?,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a [timestamp][System.currentTimeMillis] taken immediately before OkHttp
|
||||||
|
* transmitted the initiating request over the network. If this response is being served from the
|
||||||
|
* cache then this is the timestamp of the original request.
|
||||||
|
*/
|
||||||
|
@get:JvmName("sentRequestAtMillis") val sentRequestAtMillis: Long,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a [timestamp][System.currentTimeMillis] taken immediately after OkHttp
|
||||||
|
* received this response's headers from the network. If this response is being served from the
|
||||||
|
* cache then this is the timestamp of the original response.
|
||||||
|
*/
|
||||||
|
@get:JvmName("receivedResponseAtMillis") val receivedResponseAtMillis: Long,
|
||||||
|
|
||||||
|
@get:JvmName("exchange") val exchange: Exchange?
|
||||||
|
) : Closeable {
|
||||||
|
|
||||||
|
private var lazyCacheControl: CacheControl? = null
|
||||||
|
|
||||||
|
@JvmName("-deprecated_request")
|
||||||
|
@Deprecated(
|
||||||
|
message = "moved to val",
|
||||||
|
replaceWith = ReplaceWith(expression = "request"),
|
||||||
|
level = DeprecationLevel.WARNING)
|
||||||
|
fun request(): Request = request
|
||||||
|
|
||||||
|
@JvmName("-deprecated_protocol")
|
||||||
|
@Deprecated(
|
||||||
|
message = "moved to val",
|
||||||
|
replaceWith = ReplaceWith(expression = "protocol"),
|
||||||
|
level = DeprecationLevel.WARNING)
|
||||||
|
fun protocol(): Protocol = protocol
|
||||||
|
|
||||||
|
@JvmName("-deprecated_code")
|
||||||
|
@Deprecated(
|
||||||
|
message = "moved to val",
|
||||||
|
replaceWith = ReplaceWith(expression = "code"),
|
||||||
|
level = DeprecationLevel.WARNING)
|
||||||
fun code(): Int = code
|
fun code(): Int = code
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,13 +145,18 @@ class Response internal constructor(
|
|||||||
val isSuccessful: Boolean
|
val isSuccessful: Boolean
|
||||||
get() = code in 200..299
|
get() = code in 200..299
|
||||||
|
|
||||||
/** Returns the HTTP status message. */
|
@JvmName("-deprecated_message")
|
||||||
|
@Deprecated(
|
||||||
|
message = "moved to val",
|
||||||
|
replaceWith = ReplaceWith(expression = "message"),
|
||||||
|
level = DeprecationLevel.WARNING)
|
||||||
fun message(): String = message
|
fun message(): String = message
|
||||||
|
|
||||||
/**
|
@JvmName("-deprecated_handshake")
|
||||||
* Returns the TLS handshake of the connection that carried this response, or null if the
|
@Deprecated(
|
||||||
* response was received without TLS.
|
message = "moved to val",
|
||||||
*/
|
replaceWith = ReplaceWith(expression = "handshake"),
|
||||||
|
level = DeprecationLevel.WARNING)
|
||||||
fun handshake(): Handshake? = handshake
|
fun handshake(): Handshake? = handshake
|
||||||
|
|
||||||
fun headers(name: String): List<String> = headers.values(name)
|
fun headers(name: String): List<String> = headers.values(name)
|
||||||
@ -94,6 +164,11 @@ class Response internal constructor(
|
|||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun header(name: String, defaultValue: String? = null): String? = headers[name] ?: defaultValue
|
fun header(name: String, defaultValue: String? = null): String? = headers[name] ?: defaultValue
|
||||||
|
|
||||||
|
@JvmName("-deprecated_headers")
|
||||||
|
@Deprecated(
|
||||||
|
message = "moved to val",
|
||||||
|
replaceWith = ReplaceWith(expression = "headers"),
|
||||||
|
level = DeprecationLevel.WARNING)
|
||||||
fun headers(): Headers = headers
|
fun headers(): Headers = headers
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -123,14 +198,11 @@ class Response internal constructor(
|
|||||||
return ResponseBody.create(body.contentType(), buffer.size, buffer)
|
return ResponseBody.create(body.contentType(), buffer.size, buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@JvmName("-deprecated_body")
|
||||||
* Returns a non-null value if this response was passed to [Callback.onResponse] or returned
|
@Deprecated(
|
||||||
* from [Call.execute]. Response bodies must be [closed][ResponseBody] and may
|
message = "moved to val",
|
||||||
* be consumed only once.
|
replaceWith = ReplaceWith(expression = "body"),
|
||||||
*
|
level = DeprecationLevel.WARNING)
|
||||||
* This always returns null on responses returned from [cacheResponse], [networkResponse],
|
|
||||||
* and [priorResponse].
|
|
||||||
*/
|
|
||||||
fun body(): ResponseBody? = body
|
fun body(): ResponseBody? = body
|
||||||
|
|
||||||
fun newBuilder(): Builder = Builder(this)
|
fun newBuilder(): Builder = Builder(this)
|
||||||
@ -142,26 +214,25 @@ class Response internal constructor(
|
|||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@JvmName("-deprecated_networkResponse")
|
||||||
* Returns the raw response received from the network. Will be null if this response didn't use
|
@Deprecated(
|
||||||
* the network, such as when the response is fully cached. The body of the returned response
|
message = "moved to val",
|
||||||
* should not be read.
|
replaceWith = ReplaceWith(expression = "networkResponse"),
|
||||||
*/
|
level = DeprecationLevel.WARNING)
|
||||||
fun networkResponse(): Response? = networkResponse
|
fun networkResponse(): Response? = networkResponse
|
||||||
|
|
||||||
/**
|
@JvmName("-deprecated_cacheResponse")
|
||||||
* Returns the raw response received from the cache. Will be null if this response didn't use
|
@Deprecated(
|
||||||
* the cache. For conditional get requests the cache response and network response may both be
|
message = "moved to val",
|
||||||
* non-null. The body of the returned response should not be read.
|
replaceWith = ReplaceWith(expression = "cacheResponse"),
|
||||||
*/
|
level = DeprecationLevel.WARNING)
|
||||||
fun cacheResponse(): Response? = cacheResponse
|
fun cacheResponse(): Response? = cacheResponse
|
||||||
|
|
||||||
/**
|
@JvmName("-deprecated_priorResponse")
|
||||||
* Returns the response for the HTTP redirect or authorization challenge that triggered this
|
@Deprecated(
|
||||||
* response, or null if this response wasn't triggered by an automatic retry. The body of the
|
message = "moved to val",
|
||||||
* returned response should not be read because it has already been consumed by the redirecting
|
replaceWith = ReplaceWith(expression = "priorResponse"),
|
||||||
* client.
|
level = DeprecationLevel.WARNING)
|
||||||
*/
|
|
||||||
fun priorResponse(): Response? = priorResponse
|
fun priorResponse(): Response? = priorResponse
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -176,7 +247,7 @@ class Response internal constructor(
|
|||||||
* auth param, this is up to the caller that interprets these challenges.
|
* auth param, this is up to the caller that interprets these challenges.
|
||||||
*/
|
*/
|
||||||
fun challenges(): List<Challenge> {
|
fun challenges(): List<Challenge> {
|
||||||
return headers().parseChallenges(
|
return headers.parseChallenges(
|
||||||
when (code) {
|
when (code) {
|
||||||
HTTP_UNAUTHORIZED -> "WWW-Authenticate"
|
HTTP_UNAUTHORIZED -> "WWW-Authenticate"
|
||||||
HTTP_PROXY_AUTH -> "Proxy-Authenticate"
|
HTTP_PROXY_AUTH -> "Proxy-Authenticate"
|
||||||
@ -189,22 +260,35 @@ class Response internal constructor(
|
|||||||
* Returns the cache control directives for this response. This is never null, even if this
|
* Returns the cache control directives for this response. This is never null, even if this
|
||||||
* response contains no `Cache-Control` header.
|
* response contains no `Cache-Control` header.
|
||||||
*/
|
*/
|
||||||
fun cacheControl(): CacheControl = cacheControl ?: CacheControl.parse(headers).also {
|
@get:JvmName("cacheControl") val cacheControl: CacheControl
|
||||||
cacheControl = it
|
get() {
|
||||||
}
|
var result = lazyCacheControl
|
||||||
|
if (result == null) {
|
||||||
|
result = CacheControl.parse(headers)
|
||||||
|
lazyCacheControl = result
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
@JvmName("-deprecated_cacheControl")
|
||||||
* Returns a [timestamp][System.currentTimeMillis] taken immediately before OkHttp
|
@Deprecated(
|
||||||
* transmitted the initiating request over the network. If this response is being served from the
|
message = "moved to val",
|
||||||
* cache then this is the timestamp of the original request.
|
replaceWith = ReplaceWith(expression = "cacheControl"),
|
||||||
*/
|
level = DeprecationLevel.WARNING)
|
||||||
|
fun cacheControl(): CacheControl = cacheControl
|
||||||
|
|
||||||
|
@JvmName("-deprecated_sentRequestAtMillis")
|
||||||
|
@Deprecated(
|
||||||
|
message = "moved to val",
|
||||||
|
replaceWith = ReplaceWith(expression = "sentRequestAtMillis"),
|
||||||
|
level = DeprecationLevel.WARNING)
|
||||||
fun sentRequestAtMillis(): Long = sentRequestAtMillis
|
fun sentRequestAtMillis(): Long = sentRequestAtMillis
|
||||||
|
|
||||||
/**
|
@JvmName("-deprecated_receivedResponseAtMillis")
|
||||||
* Returns a [timestamp][System.currentTimeMillis] taken immediately after OkHttp
|
@Deprecated(
|
||||||
* received this response's headers from the network. If this response is being served from the
|
message = "moved to val",
|
||||||
* cache then this is the timestamp of the original response.
|
replaceWith = ReplaceWith(expression = "receivedResponseAtMillis"),
|
||||||
*/
|
level = DeprecationLevel.WARNING)
|
||||||
fun receivedResponseAtMillis(): Long = receivedResponseAtMillis
|
fun receivedResponseAtMillis(): Long = receivedResponseAtMillis
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -353,7 +437,17 @@ class Response internal constructor(
|
|||||||
checkNotNull(request) { "request == null" },
|
checkNotNull(request) { "request == null" },
|
||||||
checkNotNull(protocol) { "protocol == null" },
|
checkNotNull(protocol) { "protocol == null" },
|
||||||
checkNotNull(message) { "message == null" },
|
checkNotNull(message) { "message == null" },
|
||||||
this)
|
code,
|
||||||
|
handshake,
|
||||||
|
headers.build(),
|
||||||
|
body,
|
||||||
|
networkResponse,
|
||||||
|
cacheResponse,
|
||||||
|
priorResponse,
|
||||||
|
sentRequestAtMillis,
|
||||||
|
receivedResponseAtMillis,
|
||||||
|
exchange
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ class CacheInterceptor(internal val cache: Cache?) : Interceptor {
|
|||||||
|
|
||||||
if (cacheCandidate != null && cacheResponse == null) {
|
if (cacheCandidate != null && cacheResponse == null) {
|
||||||
// The cache candidate wasn't applicable. Close it.
|
// The cache candidate wasn't applicable. Close it.
|
||||||
cacheCandidate.body()?.closeQuietly()
|
cacheCandidate.body?.closeQuietly()
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're forbidden from using the network and the cache is insufficient, fail.
|
// If we're forbidden from using the network and the cache is insufficient, fail.
|
||||||
@ -83,22 +83,22 @@ class CacheInterceptor(internal val cache: Cache?) : Interceptor {
|
|||||||
} finally {
|
} finally {
|
||||||
// If we're crashing on I/O or otherwise, don't leak the cache body.
|
// If we're crashing on I/O or otherwise, don't leak the cache body.
|
||||||
if (networkResponse == null && cacheCandidate != null) {
|
if (networkResponse == null && cacheCandidate != null) {
|
||||||
cacheCandidate.body()?.closeQuietly()
|
cacheCandidate.body?.closeQuietly()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have a cache response too, then we're doing a conditional get.
|
// If we have a cache response too, then we're doing a conditional get.
|
||||||
if (cacheResponse != null) {
|
if (cacheResponse != null) {
|
||||||
if (networkResponse?.code() == HTTP_NOT_MODIFIED) {
|
if (networkResponse?.code == HTTP_NOT_MODIFIED) {
|
||||||
val response = cacheResponse.newBuilder()
|
val response = cacheResponse.newBuilder()
|
||||||
.headers(combine(cacheResponse.headers(), networkResponse.headers()))
|
.headers(combine(cacheResponse.headers, networkResponse.headers))
|
||||||
.sentRequestAtMillis(networkResponse.sentRequestAtMillis())
|
.sentRequestAtMillis(networkResponse.sentRequestAtMillis)
|
||||||
.receivedResponseAtMillis(networkResponse.receivedResponseAtMillis())
|
.receivedResponseAtMillis(networkResponse.receivedResponseAtMillis)
|
||||||
.cacheResponse(stripBody(cacheResponse))
|
.cacheResponse(stripBody(cacheResponse))
|
||||||
.networkResponse(stripBody(networkResponse))
|
.networkResponse(stripBody(networkResponse))
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
networkResponse.body()!!.close()
|
networkResponse.body!!.close()
|
||||||
|
|
||||||
// Update the cache after combining headers but before stripping the
|
// Update the cache after combining headers but before stripping the
|
||||||
// Content-Encoding header (as performed by initContentStream()).
|
// Content-Encoding header (as performed by initContentStream()).
|
||||||
@ -106,7 +106,7 @@ class CacheInterceptor(internal val cache: Cache?) : Interceptor {
|
|||||||
cache.update(cacheResponse, response)
|
cache.update(cacheResponse, response)
|
||||||
return response
|
return response
|
||||||
} else {
|
} else {
|
||||||
cacheResponse.body()?.closeQuietly()
|
cacheResponse.body?.closeQuietly()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ class CacheInterceptor(internal val cache: Cache?) : Interceptor {
|
|||||||
if (cacheRequest == null) return response
|
if (cacheRequest == null) return response
|
||||||
val cacheBodyUnbuffered = cacheRequest.body()
|
val cacheBodyUnbuffered = cacheRequest.body()
|
||||||
|
|
||||||
val source = response.body()!!.source()
|
val source = response.body!!.source()
|
||||||
val cacheBody = cacheBodyUnbuffered.buffer()
|
val cacheBody = cacheBodyUnbuffered.buffer()
|
||||||
|
|
||||||
val cacheWritingSource = object : Source {
|
val cacheWritingSource = object : Source {
|
||||||
@ -193,7 +193,7 @@ class CacheInterceptor(internal val cache: Cache?) : Interceptor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val contentType = response.header("Content-Type")
|
val contentType = response.header("Content-Type")
|
||||||
val contentLength = response.body()!!.contentLength()
|
val contentLength = response.body!!.contentLength()
|
||||||
return response.newBuilder()
|
return response.newBuilder()
|
||||||
.body(RealResponseBody(contentType, contentLength, cacheWritingSource.buffer()))
|
.body(RealResponseBody(contentType, contentLength, cacheWritingSource.buffer()))
|
||||||
.build()
|
.build()
|
||||||
@ -202,7 +202,7 @@ class CacheInterceptor(internal val cache: Cache?) : Interceptor {
|
|||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private fun stripBody(response: Response?): Response? {
|
private fun stripBody(response: Response?): Response? {
|
||||||
return if (response?.body() != null) {
|
return if (response?.body != null) {
|
||||||
response.newBuilder().body(null).build()
|
response.newBuilder().body(null).build()
|
||||||
} else {
|
} else {
|
||||||
response
|
response
|
||||||
|
@ -91,14 +91,14 @@ class CacheStrategy internal constructor(
|
|||||||
* cached response older than 24 hours, we are required to attach a warning.
|
* cached response older than 24 hours, we are required to attach a warning.
|
||||||
*/
|
*/
|
||||||
private fun isFreshnessLifetimeHeuristic(): Boolean {
|
private fun isFreshnessLifetimeHeuristic(): Boolean {
|
||||||
return cacheResponse!!.cacheControl().maxAgeSeconds == -1 && expires == null
|
return cacheResponse!!.cacheControl.maxAgeSeconds == -1 && expires == null
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (cacheResponse != null) {
|
if (cacheResponse != null) {
|
||||||
this.sentRequestMillis = cacheResponse.sentRequestAtMillis()
|
this.sentRequestMillis = cacheResponse.sentRequestAtMillis
|
||||||
this.receivedResponseMillis = cacheResponse.receivedResponseAtMillis()
|
this.receivedResponseMillis = cacheResponse.receivedResponseAtMillis
|
||||||
val headers = cacheResponse.headers()
|
val headers = cacheResponse.headers
|
||||||
for (i in 0 until headers.size) {
|
for (i in 0 until headers.size) {
|
||||||
val fieldName = headers.name(i)
|
val fieldName = headers.name(i)
|
||||||
val value = headers.value(i)
|
val value = headers.value(i)
|
||||||
@ -145,7 +145,7 @@ class CacheStrategy internal constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Drop the cached response if it's missing a required handshake.
|
// Drop the cached response if it's missing a required handshake.
|
||||||
if (request.isHttps && cacheResponse.handshake() == null) {
|
if (request.isHttps && cacheResponse.handshake == null) {
|
||||||
return CacheStrategy(request, null)
|
return CacheStrategy(request, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +161,7 @@ class CacheStrategy internal constructor(
|
|||||||
return CacheStrategy(request, null)
|
return CacheStrategy(request, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
val responseCaching = cacheResponse.cacheControl()
|
val responseCaching = cacheResponse.cacheControl
|
||||||
|
|
||||||
val ageMillis = cacheResponseAge()
|
val ageMillis = cacheResponseAge()
|
||||||
var freshMillis = computeFreshnessLifetime()
|
var freshMillis = computeFreshnessLifetime()
|
||||||
@ -229,7 +229,7 @@ class CacheStrategy internal constructor(
|
|||||||
* date.
|
* date.
|
||||||
*/
|
*/
|
||||||
private fun computeFreshnessLifetime(): Long {
|
private fun computeFreshnessLifetime(): Long {
|
||||||
val responseCaching = cacheResponse!!.cacheControl()
|
val responseCaching = cacheResponse!!.cacheControl
|
||||||
if (responseCaching.maxAgeSeconds != -1) {
|
if (responseCaching.maxAgeSeconds != -1) {
|
||||||
return SECONDS.toMillis(responseCaching.maxAgeSeconds.toLong())
|
return SECONDS.toMillis(responseCaching.maxAgeSeconds.toLong())
|
||||||
}
|
}
|
||||||
@ -241,7 +241,7 @@ class CacheStrategy internal constructor(
|
|||||||
return if (delta > 0L) delta else 0L
|
return if (delta > 0L) delta else 0L
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastModified != null && cacheResponse.request().url.query == null) {
|
if (lastModified != null && cacheResponse.request.url.query == null) {
|
||||||
// As recommended by the HTTP RFC and implemented in Firefox, the max age of a document
|
// As recommended by the HTTP RFC and implemented in Firefox, the max age of a document
|
||||||
// should be defaulted to 10% of the document's age at the time it was served. Default
|
// should be defaulted to 10% of the document's age at the time it was served. Default
|
||||||
// expiration dates aren't used for URIs containing a query.
|
// expiration dates aren't used for URIs containing a query.
|
||||||
@ -290,7 +290,7 @@ class CacheStrategy internal constructor(
|
|||||||
fun isCacheable(response: Response, request: Request): Boolean {
|
fun isCacheable(response: Response, request: Request): Boolean {
|
||||||
// Always go to network for uncacheable response codes (RFC 7231 section 6.1), This
|
// Always go to network for uncacheable response codes (RFC 7231 section 6.1), This
|
||||||
// implementation doesn't support caching partial content.
|
// implementation doesn't support caching partial content.
|
||||||
when (response.code()) {
|
when (response.code) {
|
||||||
HTTP_OK,
|
HTTP_OK,
|
||||||
HTTP_NOT_AUTHORITATIVE,
|
HTTP_NOT_AUTHORITATIVE,
|
||||||
HTTP_NO_CONTENT,
|
HTTP_NO_CONTENT,
|
||||||
@ -311,9 +311,9 @@ class CacheStrategy internal constructor(
|
|||||||
// http://tools.ietf.org/html/rfc7234#section-3
|
// http://tools.ietf.org/html/rfc7234#section-3
|
||||||
// s-maxage is not checked because OkHttp is a private cache that should ignore s-maxage.
|
// s-maxage is not checked because OkHttp is a private cache that should ignore s-maxage.
|
||||||
if (response.header("Expires") == null &&
|
if (response.header("Expires") == null &&
|
||||||
response.cacheControl().maxAgeSeconds == -1 &&
|
response.cacheControl.maxAgeSeconds == -1 &&
|
||||||
!response.cacheControl().isPublic &&
|
!response.cacheControl.isPublic &&
|
||||||
!response.cacheControl().isPrivate) {
|
!response.cacheControl.isPrivate) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -325,7 +325,7 @@ class CacheStrategy internal constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// A 'no-store' directive on request or response prevents the response from being cached.
|
// A 'no-store' directive on request or response prevents the response from being cached.
|
||||||
return !response.cacheControl().noStore && !request.cacheControl.noStore
|
return !response.cacheControl.noStore && !request.cacheControl.noStore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -423,7 +423,7 @@ class RealConnection(
|
|||||||
.build()
|
.build()
|
||||||
tunnelCodec.skipConnectBody(response)
|
tunnelCodec.skipConnectBody(response)
|
||||||
|
|
||||||
when (response.code()) {
|
when (response.code) {
|
||||||
HTTP_OK -> {
|
HTTP_OK -> {
|
||||||
// Assume the server won't send a TLS ServerHello until we send a TLS ClientHello. If
|
// Assume the server won't send a TLS ServerHello until we send a TLS ClientHello. If
|
||||||
// that happens, then we will have buffered bytes that are needed by the SSLSocket!
|
// that happens, then we will have buffered bytes that are needed by the SSLSocket!
|
||||||
@ -444,7 +444,7 @@ class RealConnection(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> throw IOException("Unexpected response code for CONNECT: ${response.code()}")
|
else -> throw IOException("Unexpected response code for CONNECT: ${response.code}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ class BridgeInterceptor(private val cookieJar: CookieJar) : Interceptor {
|
|||||||
|
|
||||||
val networkResponse = chain.proceed(requestBuilder.build())
|
val networkResponse = chain.proceed(requestBuilder.build())
|
||||||
|
|
||||||
cookieJar.receiveHeaders(userRequest.url, networkResponse.headers())
|
cookieJar.receiveHeaders(userRequest.url, networkResponse.headers)
|
||||||
|
|
||||||
val responseBuilder = networkResponse.newBuilder()
|
val responseBuilder = networkResponse.newBuilder()
|
||||||
.request(userRequest)
|
.request(userRequest)
|
||||||
@ -91,10 +91,10 @@ class BridgeInterceptor(private val cookieJar: CookieJar) : Interceptor {
|
|||||||
if (transparentGzip &&
|
if (transparentGzip &&
|
||||||
"gzip".equals(networkResponse.header("Content-Encoding"), ignoreCase = true) &&
|
"gzip".equals(networkResponse.header("Content-Encoding"), ignoreCase = true) &&
|
||||||
networkResponse.promisesBody()) {
|
networkResponse.promisesBody()) {
|
||||||
val responseBody = networkResponse.body()
|
val responseBody = networkResponse.body
|
||||||
if (responseBody != null) {
|
if (responseBody != null) {
|
||||||
val gzipSource = GzipSource(responseBody.source())
|
val gzipSource = GzipSource(responseBody.source())
|
||||||
val strippedHeaders = networkResponse.headers().newBuilder()
|
val strippedHeaders = networkResponse.headers.newBuilder()
|
||||||
.removeAll("Content-Encoding")
|
.removeAll("Content-Encoding")
|
||||||
.removeAll("Content-Length")
|
.removeAll("Content-Length")
|
||||||
.build()
|
.build()
|
||||||
|
@ -87,7 +87,7 @@ class CallServerInterceptor(private val forWebSocket: Boolean) : Interceptor {
|
|||||||
.sentRequestAtMillis(sentRequestMillis)
|
.sentRequestAtMillis(sentRequestMillis)
|
||||||
.receivedResponseAtMillis(System.currentTimeMillis())
|
.receivedResponseAtMillis(System.currentTimeMillis())
|
||||||
.build()
|
.build()
|
||||||
var code = response.code()
|
var code = response.code
|
||||||
if (code == 100) {
|
if (code == 100) {
|
||||||
// server sent a 100-continue even though we did not request one.
|
// server sent a 100-continue even though we did not request one.
|
||||||
// try again to read the actual response
|
// try again to read the actual response
|
||||||
@ -97,7 +97,7 @@ class CallServerInterceptor(private val forWebSocket: Boolean) : Interceptor {
|
|||||||
.sentRequestAtMillis(sentRequestMillis)
|
.sentRequestAtMillis(sentRequestMillis)
|
||||||
.receivedResponseAtMillis(System.currentTimeMillis())
|
.receivedResponseAtMillis(System.currentTimeMillis())
|
||||||
.build()
|
.build()
|
||||||
code = response.code()
|
code = response.code
|
||||||
}
|
}
|
||||||
|
|
||||||
exchange.responseHeadersEnd(response)
|
exchange.responseHeadersEnd(response)
|
||||||
@ -112,13 +112,13 @@ class CallServerInterceptor(private val forWebSocket: Boolean) : Interceptor {
|
|||||||
.body(exchange.openResponseBody(response))
|
.body(exchange.openResponseBody(response))
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
if ("close".equals(response.request().header("Connection"), ignoreCase = true) ||
|
if ("close".equals(response.request.header("Connection"), ignoreCase = true) ||
|
||||||
"close".equals(response.header("Connection"), ignoreCase = true)) {
|
"close".equals(response.header("Connection"), ignoreCase = true)) {
|
||||||
exchange.noNewExchangesOnConnection()
|
exchange.noNewExchangesOnConnection()
|
||||||
}
|
}
|
||||||
if ((code == 204 || code == 205) && response.body()?.contentLength() ?: -1L > 0L) {
|
if ((code == 204 || code == 205) && response.body?.contentLength() ?: -1L > 0L) {
|
||||||
throw ProtocolException(
|
throw ProtocolException(
|
||||||
"HTTP $code had non-zero Content-Length: ${response.body()?.contentLength()}")
|
"HTTP $code had non-zero Content-Length: ${response.body?.contentLength()}")
|
||||||
}
|
}
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
@ -212,11 +212,11 @@ fun CookieJar.receiveHeaders(url: HttpUrl, headers: Headers) {
|
|||||||
*/
|
*/
|
||||||
fun Response.promisesBody(): Boolean {
|
fun Response.promisesBody(): Boolean {
|
||||||
// HEAD requests never yield a body regardless of the response headers.
|
// HEAD requests never yield a body regardless of the response headers.
|
||||||
if (request().method == "HEAD") {
|
if (request.method == "HEAD") {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
val responseCode = code()
|
val responseCode = code
|
||||||
if ((responseCode < HTTP_CONTINUE || responseCode >= 200) &&
|
if ((responseCode < HTTP_CONTINUE || responseCode >= 200) &&
|
||||||
responseCode != HTTP_NO_CONTENT &&
|
responseCode != HTTP_NO_CONTENT &&
|
||||||
responseCode != HTTP_NOT_MODIFIED) {
|
responseCode != HTTP_NOT_MODIFIED) {
|
||||||
|
@ -117,7 +117,7 @@ class RealInterceptorChain(
|
|||||||
"network interceptor $interceptor must call proceed() exactly once"
|
"network interceptor $interceptor must call proceed() exactly once"
|
||||||
}
|
}
|
||||||
|
|
||||||
check(response.body() != null) { "interceptor $interceptor returned a response with no body" }
|
check(response.body != null) { "interceptor $interceptor returned a response with no body" }
|
||||||
|
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ class RetryAndFollowUpInterceptor(private val client: OkHttpClient) : Intercepto
|
|||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
response.body()?.closeQuietly()
|
response.body?.closeQuietly()
|
||||||
if (transmitter.hasExchange()) {
|
if (transmitter.hasExchange()) {
|
||||||
exchange?.detachWithViolence()
|
exchange?.detachWithViolence()
|
||||||
}
|
}
|
||||||
@ -198,9 +198,9 @@ class RetryAndFollowUpInterceptor(private val client: OkHttpClient) : Intercepto
|
|||||||
*/
|
*/
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
private fun followUpRequest(userResponse: Response, route: Route?): Request? {
|
private fun followUpRequest(userResponse: Response, route: Route?): Request? {
|
||||||
val responseCode = userResponse.code()
|
val responseCode = userResponse.code
|
||||||
|
|
||||||
val method = userResponse.request().method
|
val method = userResponse.request.method
|
||||||
when (responseCode) {
|
when (responseCode) {
|
||||||
HTTP_PROXY_AUTH -> {
|
HTTP_PROXY_AUTH -> {
|
||||||
val selectedProxy = route!!.proxy
|
val selectedProxy = route!!.proxy
|
||||||
@ -234,12 +234,12 @@ class RetryAndFollowUpInterceptor(private val client: OkHttpClient) : Intercepto
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
val requestBody = userResponse.request().body
|
val requestBody = userResponse.request.body
|
||||||
if (requestBody != null && requestBody.isOneShot()) {
|
if (requestBody != null && requestBody.isOneShot()) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
val priorResponse = userResponse.priorResponse()
|
val priorResponse = userResponse.priorResponse
|
||||||
if (priorResponse != null && priorResponse.code() == HTTP_CLIENT_TIMEOUT) {
|
if (priorResponse != null && priorResponse.code == HTTP_CLIENT_TIMEOUT) {
|
||||||
// We attempted to retry and got another timeout. Give up.
|
// We attempted to retry and got another timeout. Give up.
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -248,19 +248,19 @@ class RetryAndFollowUpInterceptor(private val client: OkHttpClient) : Intercepto
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return userResponse.request()
|
return userResponse.request
|
||||||
}
|
}
|
||||||
|
|
||||||
HTTP_UNAVAILABLE -> {
|
HTTP_UNAVAILABLE -> {
|
||||||
val priorResponse = userResponse.priorResponse()
|
val priorResponse = userResponse.priorResponse
|
||||||
if (priorResponse != null && priorResponse.code() == HTTP_UNAVAILABLE) {
|
if (priorResponse != null && priorResponse.code == HTTP_UNAVAILABLE) {
|
||||||
// We attempted to retry and got another timeout. Give up.
|
// We attempted to retry and got another timeout. Give up.
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retryAfter(userResponse, Integer.MAX_VALUE) == 0) {
|
if (retryAfter(userResponse, Integer.MAX_VALUE) == 0) {
|
||||||
// specifically received an instruction to retry without delay
|
// specifically received an instruction to retry without delay
|
||||||
return userResponse.request()
|
return userResponse.request
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
@ -275,20 +275,20 @@ class RetryAndFollowUpInterceptor(private val client: OkHttpClient) : Intercepto
|
|||||||
|
|
||||||
val location = userResponse.header("Location") ?: return null
|
val location = userResponse.header("Location") ?: return null
|
||||||
// Don't follow redirects to unsupported protocols.
|
// Don't follow redirects to unsupported protocols.
|
||||||
val url = userResponse.request().url.resolve(location) ?: return null
|
val url = userResponse.request.url.resolve(location) ?: return null
|
||||||
|
|
||||||
// If configured, don't follow redirects between SSL and non-SSL.
|
// If configured, don't follow redirects between SSL and non-SSL.
|
||||||
val sameScheme = url.scheme == userResponse.request().url.scheme
|
val sameScheme = url.scheme == userResponse.request.url.scheme
|
||||||
if (!sameScheme && !client.followSslRedirects()) return null
|
if (!sameScheme && !client.followSslRedirects()) return null
|
||||||
|
|
||||||
// Most redirects don't include a request body.
|
// Most redirects don't include a request body.
|
||||||
val requestBuilder = userResponse.request().newBuilder()
|
val requestBuilder = userResponse.request.newBuilder()
|
||||||
if (HttpMethod.permitsRequestBody(method)) {
|
if (HttpMethod.permitsRequestBody(method)) {
|
||||||
val maintainBody = HttpMethod.redirectsWithBody(method)
|
val maintainBody = HttpMethod.redirectsWithBody(method)
|
||||||
if (HttpMethod.redirectsToGet(method)) {
|
if (HttpMethod.redirectsToGet(method)) {
|
||||||
requestBuilder.method("GET", null)
|
requestBuilder.method("GET", null)
|
||||||
} else {
|
} else {
|
||||||
val requestBody = if (maintainBody) userResponse.request().body else null
|
val requestBody = if (maintainBody) userResponse.request.body else null
|
||||||
requestBuilder.method(method, requestBody)
|
requestBuilder.method(method, requestBody)
|
||||||
}
|
}
|
||||||
if (!maintainBody) {
|
if (!maintainBody) {
|
||||||
@ -301,7 +301,7 @@ class RetryAndFollowUpInterceptor(private val client: OkHttpClient) : Intercepto
|
|||||||
// When redirecting across hosts, drop all authentication headers. This
|
// When redirecting across hosts, drop all authentication headers. This
|
||||||
// is potentially annoying to the application layer since they have no
|
// is potentially annoying to the application layer since they have no
|
||||||
// way to retain them.
|
// way to retain them.
|
||||||
if (!userResponse.request().url.canReuseConnectionFor(url)) {
|
if (!userResponse.request.url.canReuseConnectionFor(url)) {
|
||||||
requestBuilder.removeHeader("Authorization")
|
requestBuilder.removeHeader("Authorization")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ class StatusLine(
|
|||||||
const val HTTP_CONTINUE = 100
|
const val HTTP_CONTINUE = 100
|
||||||
|
|
||||||
fun get(response: Response): StatusLine {
|
fun get(response: Response): StatusLine {
|
||||||
return StatusLine(response.protocol(), response.code(), response.message())
|
return StatusLine(response.protocol, response.code, response.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
|
@ -133,7 +133,7 @@ class Http1ExchangeCodec(
|
|||||||
override fun openResponseBodySource(response: Response): Source {
|
override fun openResponseBodySource(response: Response): Source {
|
||||||
return when {
|
return when {
|
||||||
!response.promisesBody() -> newFixedLengthSource(0)
|
!response.promisesBody() -> newFixedLengthSource(0)
|
||||||
response.isChunked() -> newChunkedSource(response.request().url)
|
response.isChunked() -> newChunkedSource(response.request.url)
|
||||||
else -> {
|
else -> {
|
||||||
val contentLength = response.headersContentLength()
|
val contentLength = response.headersContentLength()
|
||||||
if (contentLength != -1L) {
|
if (contentLength != -1L) {
|
||||||
|
@ -192,9 +192,9 @@ class RealWebSocket(
|
|||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
internal fun checkUpgradeSuccess(response: Response, exchange: Exchange?) {
|
internal fun checkUpgradeSuccess(response: Response, exchange: Exchange?) {
|
||||||
if (response.code() != 101) {
|
if (response.code != 101) {
|
||||||
throw ProtocolException(
|
throw ProtocolException(
|
||||||
"Expected HTTP 101 response but was '${response.code()} ${response.message()}'")
|
"Expected HTTP 101 response but was '${response.code} ${response.message}'")
|
||||||
}
|
}
|
||||||
|
|
||||||
val headerConnection = response.header("Connection")
|
val headerConnection = response.header("Connection")
|
||||||
|
@ -64,8 +64,8 @@ class ConscryptTest {
|
|||||||
|
|
||||||
val response = client.newCall(request).execute()
|
val response = client.newCall(request).execute()
|
||||||
|
|
||||||
assertThat(response.protocol()).isEqualTo(Protocol.HTTP_2)
|
assertThat(response.protocol).isEqualTo(Protocol.HTTP_2)
|
||||||
assertThat(response.handshake()!!.tlsVersion).isEqualTo(TlsVersion.TLS_1_3)
|
assertThat(response.handshake!!.tlsVersion).isEqualTo(TlsVersion.TLS_1_3)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -76,8 +76,8 @@ class ConscryptTest {
|
|||||||
|
|
||||||
val response = client.newCall(request).execute()
|
val response = client.newCall(request).execute()
|
||||||
|
|
||||||
assertThat(response.protocol()).isEqualTo(Protocol.HTTP_2)
|
assertThat(response.protocol).isEqualTo(Protocol.HTTP_2)
|
||||||
if (response.handshake()!!.tlsVersion != TlsVersion.TLS_1_3) {
|
if (response.handshake!!.tlsVersion != TlsVersion.TLS_1_3) {
|
||||||
System.err.println("Flaky TLSv1.3 with google")
|
System.err.println("Flaky TLSv1.3 with google")
|
||||||
// assertThat(response.handshake()!!.tlsVersion).isEqualTo(TlsVersion.TLS_1_3)
|
// assertThat(response.handshake()!!.tlsVersion).isEqualTo(TlsVersion.TLS_1_3)
|
||||||
}
|
}
|
||||||
|
@ -1041,27 +1041,27 @@ class KotlinSourceCompatibilityTest {
|
|||||||
@Test @Ignore
|
@Test @Ignore
|
||||||
fun response() {
|
fun response() {
|
||||||
val response: Response = Response.Builder().build()
|
val response: Response = Response.Builder().build()
|
||||||
val request: Request = response.request()
|
val request: Request = response.request
|
||||||
val protocol: Protocol = response.protocol()
|
val protocol: Protocol = response.protocol
|
||||||
val code: Int = response.code()
|
val code: Int = response.code
|
||||||
val successful: Boolean = response.isSuccessful
|
val successful: Boolean = response.isSuccessful
|
||||||
val message: String = response.message()
|
val message: String = response.message
|
||||||
val handshake: Handshake? = response.handshake()
|
val handshake: Handshake? = response.handshake
|
||||||
val headersForName: List<String> = response.headers("")
|
val headersForName: List<String> = response.headers("")
|
||||||
val header: String? = response.header("")
|
val header: String? = response.header("")
|
||||||
val headers: Headers = response.headers()
|
val headers: Headers = response.headers
|
||||||
val trailers: Headers = response.trailers()
|
val trailers: Headers = response.trailers()
|
||||||
val peekBody: ResponseBody = response.peekBody(0L)
|
val peekBody: ResponseBody = response.peekBody(0L)
|
||||||
val body: ResponseBody? = response.body()
|
val body: ResponseBody? = response.body
|
||||||
val builder: Response.Builder = response.newBuilder()
|
val builder: Response.Builder = response.newBuilder()
|
||||||
val redirect: Boolean = response.isRedirect
|
val redirect: Boolean = response.isRedirect
|
||||||
val networkResponse: Response? = response.networkResponse()
|
val networkResponse: Response? = response.networkResponse
|
||||||
val cacheResponse: Response? = response.cacheResponse()
|
val cacheResponse: Response? = response.cacheResponse
|
||||||
val priorResponse: Response? = response.priorResponse()
|
val priorResponse: Response? = response.priorResponse
|
||||||
val challenges: List<Challenge> = response.challenges()
|
val challenges: List<Challenge> = response.challenges()
|
||||||
val cacheControl: CacheControl = response.cacheControl()
|
val cacheControl: CacheControl = response.cacheControl
|
||||||
val sentRequestAtMillis: Long = response.sentRequestAtMillis()
|
val sentRequestAtMillis: Long = response.sentRequestAtMillis
|
||||||
val receivedResponseAtMillis: Long = response.receivedResponseAtMillis()
|
val receivedResponseAtMillis: Long = response.receivedResponseAtMillis
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test @Ignore
|
@Test @Ignore
|
||||||
|
Reference in New Issue
Block a user