All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.okhttp3.internal.-ResponseCommon.kt Maven / Gradle / Ivy

There is a newer version: 5.0.0-alpha.14
Show newest version
/*
 * Copyright (C) 2022 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package okhttp3.internal

import kotlin.jvm.JvmOverloads
import okhttp3.CacheControl
import okhttp3.Headers
import okhttp3.MediaType
import okhttp3.Protocol
import okhttp3.Request
import okhttp3.Response
import okhttp3.ResponseBody
import okhttp3.ResponseBody.Companion.asResponseBody
import okhttp3.internal.http.HTTP_MOVED_PERM
import okhttp3.internal.http.HTTP_MOVED_TEMP
import okhttp3.internal.http.HTTP_MULT_CHOICE
import okhttp3.internal.http.HTTP_PERM_REDIRECT
import okhttp3.internal.http.HTTP_SEE_OTHER
import okhttp3.internal.http.HTTP_TEMP_REDIRECT
import okio.Buffer
import okio.IOException
import okio.Source
import okio.Timeout
import okio.buffer

internal class UnreadableResponseBody(
  private val mediaType: MediaType?,
  private val contentLength: Long,
): ResponseBody(), Source {
  override fun contentType() = mediaType
  override fun contentLength() = contentLength
  override fun source() = buffer()

  override fun read(sink: Buffer, byteCount: Long): Long {
    throw IllegalStateException("""
      |Unreadable ResponseBody! These Response objects have bodies that are stripped:
      | * Response.cacheResponse
      | * Response.networkResponse
      | * Response.priorResponse
      | * EventSourceListener
      | * WebSocketListener
      |(It is safe to call contentType() and contentLength() on these response bodies.)
      """.trimMargin()
    )
  }

  override fun timeout() = Timeout.NONE

  override fun close() {
  }
}

fun Response.stripBody(): Response {
  return newBuilder()
    .body(UnreadableResponseBody(body.contentType(), body.contentLength()))
    .build()
}

val Response.commonIsSuccessful: Boolean
  get() = code in 200..299

fun Response.commonHeaders(name: String): List = headers.values(name)

@JvmOverloads
fun Response.commonHeader(name: String, defaultValue: String?): String? = headers[name] ?: defaultValue

@Throws(IOException::class)
fun Response.commonPeekBody(byteCount: Long): ResponseBody {
  val peeked = body.source().peek()
  val buffer = Buffer()
  peeked.request(byteCount)
  buffer.write(peeked, minOf(byteCount, peeked.buffer.size))
  return buffer.asResponseBody(body.contentType(), buffer.size)
}

fun Response.commonNewBuilder(): Response.Builder = Response.Builder(this)

val Response.commonIsRedirect: Boolean
  get() = when (code) {
    HTTP_PERM_REDIRECT, HTTP_TEMP_REDIRECT, HTTP_MULT_CHOICE, HTTP_MOVED_PERM, HTTP_MOVED_TEMP, HTTP_SEE_OTHER -> true
    else -> false
  }

val Response.commonCacheControl: CacheControl
  get() {
    var result = lazyCacheControl
    if (result == null) {
      result = CacheControl.parse(headers)
      lazyCacheControl = result
    }
    return result
  }

fun Response.commonClose() {
  body.close()
}

fun Response.commonToString(): String =
  "Response{protocol=$protocol, code=$code, message=$message, url=${request.url}}"

fun Response.Builder.commonRequest(request: Request) = apply {
  this.request = request
}

fun Response.Builder.commonProtocol(protocol: Protocol) = apply {
  this.protocol = protocol
}

fun Response.Builder.commonCode(code: Int) = apply {
  this.code = code
}

fun Response.Builder.commonMessage(message: String) = apply {
  this.message = message
}

fun Response.Builder.commonHeader(name: String, value: String) = apply {
  headers[name] = value
}

fun Response.Builder.commonAddHeader(name: String, value: String) = apply {
  headers.add(name, value)
}

fun Response.Builder.commonRemoveHeader(name: String) = apply {
  headers.removeAll(name)
}

fun Response.Builder.commonHeaders(headers: Headers) = apply {
  this.headers = headers.newBuilder()
}

fun Response.Builder.commonTrailers(trailersFn: (() -> Headers)) = apply {
  this.trailersFn = trailersFn
}

fun Response.Builder.commonBody(body: ResponseBody) = apply {
  this.body = body
}

fun Response.Builder.commonNetworkResponse(networkResponse: Response?) = apply {
  checkSupportResponse("networkResponse", networkResponse)
  this.networkResponse = networkResponse
}

fun Response.Builder.commonCacheResponse(cacheResponse: Response?) = apply {
  checkSupportResponse("cacheResponse", cacheResponse)
  this.cacheResponse = cacheResponse
}

private fun checkSupportResponse(name: String, response: Response?) {
  response?.apply {
    require(networkResponse == null) { "$name.networkResponse != null" }
    require(cacheResponse == null) { "$name.cacheResponse != null" }
    require(priorResponse == null) { "$name.priorResponse != null" }
  }
}

fun Response.Builder.commonPriorResponse(priorResponse: Response?) = apply {
  this.priorResponse = priorResponse
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy