Skip to content

Instantly share code, notes, and snippets.

@JeppeLeth
Created September 11, 2017 08:13
Show Gist options
  • Select an option

  • Save JeppeLeth/f95cc1582bc844f06ad98c37331e20ee to your computer and use it in GitHub Desktop.

Select an option

Save JeppeLeth/f95cc1582bc844f06ad98c37331e20ee to your computer and use it in GitHub Desktop.

Revisions

  1. JeppeLeth created this gist Sep 11, 2017.
    92 changes: 92 additions & 0 deletions JavaNetCookieJar
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,92 @@
    /**
    * A cookie jar that delegates to a {@link java.net.CookieHandler}.
    * Copied from https://github.com/square/okhttp/blob/master/okhttp-urlconnection/src/main/java/okhttp3/JavaNetCookieJar.java
    */
    public class JavaNetCookieJar implements CookieJar {
    private final CookieHandler cookieHandler;

    public JavaNetCookieJar(CookieHandler cookieHandler) {
    this.cookieHandler = cookieHandler;
    }

    @Override
    public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
    if (cookieHandler != null) {
    List<String> cookieStrings = new ArrayList<>();
    for (Cookie cookie : cookies) {
    if (cookie.hostOnly()) {
    cookieStrings.add(cookie.toString());
    } else {
    cookieStrings.add(cookie.toString().replaceAll("(domain=)(\\w+)", "$1.$2"));
    }
    }
    Map<String, List<String>> multimap = Collections.singletonMap("Set-Cookie", cookieStrings);
    try {
    cookieHandler.put(url.uri(), multimap);
    } catch (IOException e) {
    ELog.e("OkHttp Cookie", "Saving cookies failed for " + url.resolve("/..."), e);
    }
    }
    }

    @Override
    public List<Cookie> loadForRequest(HttpUrl url) {
    // The RI passes all headers. We don't have 'em, so we don't pass 'em!
    Map<String, List<String>> headers = Collections.emptyMap();
    Map<String, List<String>> cookieHeaders;
    try {
    cookieHeaders = cookieHandler.get(url.uri(), headers);
    } catch (IOException e) {
    Log.e("OkHttp Cookie", "Loading cookies failed for " + url.resolve("/..."), e);
    return Collections.emptyList();
    }

    List<Cookie> cookies = null;
    for (Map.Entry<String, List<String>> entry : cookieHeaders.entrySet()) {
    String key = entry.getKey();
    if (("Cookie".equalsIgnoreCase(key) || "Cookie2".equalsIgnoreCase(key))
    && !entry.getValue().isEmpty()) {
    for (String header : entry.getValue()) {
    if (cookies == null) cookies = new ArrayList<>();
    cookies.addAll(decodeHeaderAsJavaNetCookies(url, header));
    }
    }
    }

    return cookies != null
    ? Collections.unmodifiableList(cookies)
    : Collections.<Cookie>emptyList();
    }

    /**
    * Convert a request header to OkHttp's cookies via {@link java.net.HttpCookie}. That extra step
    * handles
    * multiple cookies in a single request header, which {@link Cookie#parse} doesn't support.
    */
    private List<Cookie> decodeHeaderAsJavaNetCookies(HttpUrl url, String header) {
    List<Cookie> result = new ArrayList<>();
    for (int pos = 0, limit = header.length(), pairEnd; pos < limit; pos = pairEnd + 1) {
    pairEnd = delimiterOffset(header, pos, limit, ";,");
    int equalsSign = delimiterOffset(header, pos, pairEnd, '=');
    String name = trimSubstring(header, pos, equalsSign);
    if (name.startsWith("$")) continue;

    // We have either name=value or just a name.
    String value = equalsSign < pairEnd
    ? trimSubstring(header, equalsSign + 1, pairEnd)
    : "";

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

    result.add(new Cookie.Builder()
    .name(name)
    .value(value)
    .domain(url.host())
    .build());
    }
    return result;
    }
    }