Skip to content

Instantly share code, notes, and snippets.

@JeppeLeth
Created September 11, 2017 08:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JeppeLeth/f95cc1582bc844f06ad98c37331e20ee to your computer and use it in GitHub Desktop.
Save JeppeLeth/f95cc1582bc844f06ad98c37331e20ee to your computer and use it in GitHub Desktop.
JavaNetCookie - A cookie jar that delegates to a java.net.CookieHandler
/**
* 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;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment