Repository: square/okhttp
File: okhttp-zstd/src/main/kotlin/okhttp3/zstd/ZstdInterceptor.kt (Kotlin)

Code before:
import okhttp3.internal.http.promisesBody
import okio.buffer
import okio.gzip

/**
 * Transparent ZStandard response support.
 *
 * This must be installed as an application interceptor.
 *
 * Adds `Accept-Encoding: zstd,gzip` to request and checks (and strips) for `Content-Encoding: zstd`
 * in responses.
 *
 * This replaces the transparent gzip compression in OkHttp.
 */
object ZstdInterceptor : Interceptor {
  override fun intercept(chain: Interceptor.Chain): Response {
    val originalRequest = chain.request()

    if (originalRequest.header("Accept-Encoding") != null) {
      return chain.proceed(originalRequest)
    }

    val request =
      originalRequest
        .newBuilder()
        .header("Accept-Encoding", "zstd,gzip")
        .build()

    return decompress(chain.proceed(request))
  }

  internal fun decompress(response: Response): Response {
    if (!response.promisesBody()) {
      return response
    }

    val body = response.body
    val encoding = response.header("Content-Encoding") ?: return response

    val decompressedSource =
      when {
        encoding.equals("zstd", ignoreCase = true) -> body.source().zstdDecompress()
        encoding.equals("gzip", ignoreCase = true) -> body.source().gzip()
        else -> return response
      }

    return response
      .newBuilder()
      .removeHeader("Content-Encoding")
      .removeHeader("Content-Length")
      .body(decompressedSource.buffer().asResponseBody(body.contentType(), -1L))

Review comment (suggestion):
Choosing between zstd or brotli, makes me wonder whether we should support a configurable (default to gzip only) DecompressionInterceptor

Code after:
import okhttp3.internal.http.promisesBody
import okio.buffer
import okio.gzip

/**
 * Transparent Zstandard response support.
 *
 * This must be installed as an application interceptor.
 *
 * Adds `Accept-Encoding: zstd,gzip` to request and checks (and strips) for `Content-Encoding: zstd`
 * in responses.
 *
 * This replaces the transparent gzip compression in OkHttp.
 */
object ZstdInterceptor : Interceptor {
  override fun intercept(chain: Interceptor.Chain): Response {
    val originalRequest = chain.request()

    if (originalRequest.header("Accept-Encoding") != null) {
      return chain.proceed(originalRequest)
    }

    val request =
      originalRequest
        .newBuilder()
        .header("Accept-Encoding", "zstd,gzip")
        .build()

    return decompress(chain.proceed(request))
  }

  internal fun decompress(response: Response): Response {
    if (!response.promisesBody()) {
      return response
    }

    val body = response.body
    val encoding = response.header("Content-Encoding") ?: return response

    val decompressedSource =
      when {
        encoding.equals("zstd", ignoreCase = true) -> body.source().zstdDecompress()
        encoding.equals("gzip", ignoreCase = true) -> body.source().gzip()
        else -> return response
      }

    return response
      .newBuilder()
      .removeHeader("Content-Encoding")
      .removeHeader("Content-Length")
      .body(decompressedSource.buffer().asResponseBody(body.contentType(), -1L))