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

okhttp3.JavaNetCookieJar.kt Maven / Gradle / Ivy

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

import java.io.IOException
import java.net.CookieHandler
import java.net.HttpCookie
import java.util.Collections
import okhttp3.internal.cookieToString
import okhttp3.internal.delimiterOffset
import okhttp3.internal.platform.Platform
import okhttp3.internal.platform.Platform.Companion.WARN
import okhttp3.internal.trimSubstring

/** A cookie jar that delegates to a [java.net.CookieHandler]. */
class JavaNetCookieJar(private val cookieHandler: CookieHandler) : CookieJar {

  override fun saveFromResponse(url: HttpUrl, cookies: List) {
    val cookieStrings = mutableListOf()
    for (cookie in cookies) {
      cookieStrings.add(cookieToString(cookie, true))
    }
    val multimap = mapOf("Set-Cookie" to cookieStrings)
    try {
      cookieHandler.put(url.toUri(), multimap)
    } catch (e: IOException) {
      Platform.get().log("Saving cookies failed for " + url.resolve("/...")!!, WARN, e)
    }
  }

  override fun loadForRequest(url: HttpUrl): List {
    val cookieHeaders = try {
      // The RI passes all headers. We don't have 'em, so we don't pass 'em!
      cookieHandler.get(url.toUri(), emptyMap>())
    } catch (e: IOException) {
      Platform.get().log("Loading cookies failed for " + url.resolve("/...")!!, WARN, e)
      return emptyList()
    }

    var cookies: MutableList? = null
    for ((key, value) in cookieHeaders) {
      if (("Cookie".equals(key, ignoreCase = true) || "Cookie2".equals(key, ignoreCase = true)) &&
          value.isNotEmpty()) {
        for (header in value) {
          if (cookies == null) cookies = mutableListOf()
          cookies.addAll(decodeHeaderAsJavaNetCookies(url, header))
        }
      }
    }

    return if (cookies != null) {
      Collections.unmodifiableList(cookies)
    } else {
      emptyList()
    }
  }

  /**
   * Convert a request header to OkHttp's cookies via [HttpCookie]. That extra step handles
   * multiple cookies in a single request header, which [Cookie.parse] doesn't support.
   */
  private fun decodeHeaderAsJavaNetCookies(url: HttpUrl, header: String): List {
    val result = mutableListOf()
    var pos = 0
    val limit = header.length
    var pairEnd: Int
    while (pos < limit) {
      pairEnd = header.delimiterOffset(";,", pos, limit)
      val equalsSign = header.delimiterOffset('=', pos, pairEnd)
      val name = header.trimSubstring(pos, equalsSign)
      if (name.startsWith("$")) {
        pos = pairEnd + 1
        continue
      }

      // We have either name=value or just a name.
      var value = if (equalsSign < pairEnd) {
        header.trimSubstring(equalsSign + 1, pairEnd)
      } else {
        ""
      }

      // If the value is "quoted", drop the quotes.
      if (value.startsWith("\"") && value.endsWith("\"")) {
        value = value.substring(1, value.length - 1)
      }

      result.add(Cookie.Builder()
          .name(name)
          .value(value)
          .domain(url.host)
          .build())
      pos = pairEnd + 1
    }
    return result
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy