1
0
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:
Masaru Nomura
2019-05-23 23:12:19 -04:00
parent 103e95d416
commit 7ad4f970ba
21 changed files with 267 additions and 173 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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