mirror of
https://github.com/square/okhttp.git
synced 2026-01-17 08:42:25 +03:00
Merge pull request #2235 from square/jwilson_0113_cookies_
Parse the CookieHandler request cookies in JavaNetCookieJar.
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package okhttp3.internal.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.CookieHandler;
|
||||
import java.net.CookieManager;
|
||||
import java.net.HttpCookie;
|
||||
import java.net.HttpURLConnection;
|
||||
@@ -28,9 +29,9 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.JavaNetCookieJar;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.OkUrlFactory;
|
||||
import okhttp3.JavaNetCookieJar;
|
||||
import okhttp3.mockwebserver.MockResponse;
|
||||
import okhttp3.mockwebserver.MockWebServer;
|
||||
import okhttp3.mockwebserver.RecordedRequest;
|
||||
@@ -143,21 +144,50 @@ public class CookiesTest {
|
||||
MockWebServer server = new MockWebServer();
|
||||
server.enqueue(new MockResponse());
|
||||
server.start();
|
||||
HttpUrl serverUrl = urlWithIpAddress(server, "/");
|
||||
|
||||
CookieManager cookieManager = new CookieManager(null, ACCEPT_ORIGINAL_SERVER);
|
||||
HttpCookie cookieA = new HttpCookie("a", "android");
|
||||
cookieA.setDomain(server.getHostName());
|
||||
cookieA.setDomain(serverUrl.host());
|
||||
cookieA.setPath("/");
|
||||
cookieManager.getCookieStore().add(server.url("/").uri(), cookieA);
|
||||
cookieManager.getCookieStore().add(serverUrl.uri(), cookieA);
|
||||
HttpCookie cookieB = new HttpCookie("b", "banana");
|
||||
cookieB.setDomain(server.getHostName());
|
||||
cookieB.setDomain(serverUrl.host());
|
||||
cookieB.setPath("/");
|
||||
cookieManager.getCookieStore().add(server.url("/").uri(), cookieB);
|
||||
cookieManager.getCookieStore().add(serverUrl.uri(), cookieB);
|
||||
client = client.newBuilder()
|
||||
.cookieJar(new JavaNetCookieJar(cookieManager))
|
||||
.build();
|
||||
|
||||
get(server.url("/"));
|
||||
get(serverUrl);
|
||||
RecordedRequest request = server.takeRequest();
|
||||
|
||||
assertEquals("a=android; b=banana", request.getHeader("Cookie"));
|
||||
}
|
||||
|
||||
@Test public void cookieHandlerLikeAndroid() throws Exception {
|
||||
final MockWebServer server = new MockWebServer();
|
||||
server.enqueue(new MockResponse());
|
||||
server.start();
|
||||
final HttpUrl serverUrl = urlWithIpAddress(server, "/");
|
||||
|
||||
CookieHandler androidCookieHandler = new CookieHandler() {
|
||||
@Override public Map<String, List<String>> get(URI uri, Map<String, List<String>> map)
|
||||
throws IOException {
|
||||
return Collections.singletonMap("Cookie", Collections.singletonList("$Version=\"1\"; "
|
||||
+ "a=\"android\";$Path=\"/\";$Domain=\"" + serverUrl.host() + "\"; "
|
||||
+ "b=\"banana\";$Path=\"/\";$Domain=\"" + serverUrl.host() + "\""));
|
||||
}
|
||||
|
||||
@Override public void put(URI uri, Map<String, List<String>> map) throws IOException {
|
||||
}
|
||||
};
|
||||
|
||||
client = client.newBuilder()
|
||||
.cookieJar(new JavaNetCookieJar(androidCookieHandler))
|
||||
.build();
|
||||
|
||||
get(serverUrl);
|
||||
RecordedRequest request = server.takeRequest();
|
||||
|
||||
assertEquals("a=android; b=banana", request.getHeader("Cookie"));
|
||||
@@ -167,25 +197,27 @@ public class CookiesTest {
|
||||
MockWebServer redirectTarget = new MockWebServer();
|
||||
redirectTarget.enqueue(new MockResponse().setBody("A"));
|
||||
redirectTarget.start();
|
||||
HttpUrl redirectTargetUrl = urlWithIpAddress(redirectTarget, "/");
|
||||
|
||||
MockWebServer redirectSource = new MockWebServer();
|
||||
redirectSource.enqueue(new MockResponse()
|
||||
.setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP)
|
||||
.addHeader("Location: " + redirectTarget.url("/")));
|
||||
.addHeader("Location: " + redirectTargetUrl));
|
||||
redirectSource.start();
|
||||
HttpUrl redirectSourceUrl = urlWithIpAddress(redirectSource, "/");
|
||||
|
||||
CookieManager cookieManager = new CookieManager(null, ACCEPT_ORIGINAL_SERVER);
|
||||
HttpCookie cookie = new HttpCookie("c", "cookie");
|
||||
cookie.setDomain(redirectSource.getHostName());
|
||||
cookie.setDomain(redirectSourceUrl.host());
|
||||
cookie.setPath("/");
|
||||
String portList = Integer.toString(redirectSource.getPort());
|
||||
cookie.setPortlist(portList);
|
||||
cookieManager.getCookieStore().add(redirectSource.url("/").uri(), cookie);
|
||||
cookieManager.getCookieStore().add(redirectSourceUrl.uri(), cookie);
|
||||
client = client.newBuilder()
|
||||
.cookieJar(new JavaNetCookieJar(cookieManager))
|
||||
.build();
|
||||
|
||||
get(redirectSource.url("/"));
|
||||
get(redirectSourceUrl);
|
||||
RecordedRequest request = redirectSource.takeRequest();
|
||||
|
||||
assertEquals("c=cookie", request.getHeader("Cookie"));
|
||||
|
||||
@@ -25,6 +25,8 @@ import java.util.Map;
|
||||
import okhttp3.internal.Internal;
|
||||
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static okhttp3.internal.Util.delimiterOffset;
|
||||
import static okhttp3.internal.Util.trimSubstring;
|
||||
|
||||
/** A cookie jar that delegates to a {@link java.net.CookieHandler}. */
|
||||
public final class JavaNetCookieJar implements CookieJar {
|
||||
@@ -82,19 +84,26 @@ public final class JavaNetCookieJar implements CookieJar {
|
||||
* multiple cookies in a single request header, which {@link Cookie#parse} doesn't support.
|
||||
*/
|
||||
private List<Cookie> decodeHeaderAsJavaNetCookies(HttpUrl url, String header) {
|
||||
List<HttpCookie> javaNetCookies;
|
||||
try {
|
||||
javaNetCookies = HttpCookie.parse(header);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Unfortunately sometimes java.net gives a Cookie like "$Version=1" which it can't parse!
|
||||
Internal.logger.log(WARNING, "Parsing request cookie failed for " + url.resolve("/..."), e);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<Cookie> result = new ArrayList<>();
|
||||
for (HttpCookie javaNetCookie : javaNetCookies) {
|
||||
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(javaNetCookie.getName())
|
||||
.value(javaNetCookie.getValue())
|
||||
.name(name)
|
||||
.value(value)
|
||||
.domain(url.host())
|
||||
.build());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user