Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -108,23 +108,20 @@ public void process(final HttpRequest request, final EntityDetails entity, final
Args.notNull(request, "HTTP request");
Args.notNull(context, "HTTP context");

final HttpClientContext clientContext = HttpClientContext.cast(context);
final String exchangeId = clientContext.getExchangeId();

// Discard the CookieSpec and CookieOrigin of a previous exchange executed with
// this context so the response interceptor never processes Set-Cookie headers
// against the origin of another request
clientContext.setCookieSpec(null);
clientContext.setCookieOrigin(null);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Hsnmohd Very good catch.

However, I would rather keep the cookie spec and cookie origin null in case the Cookie header has manually added and not generated by RequestAddCookies, and let ResponseProcessCookies take no action. Would you agree to that?

final String method = request.getMethod();
if (Method.CONNECT.isSame(method) || Method.TRACE.isSame(method)) {
return;
}

// Check if a Cookie header is already present
if (request.containsHeader(HttpHeaders.COOKIE)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Skipping cookie addition, Cookie header already present in the request");
}
// Skip adding cookies if the Cookie header is already present
return;
}

final HttpClientContext clientContext = HttpClientContext.cast(context);
final String exchangeId = clientContext.getExchangeId();

// Obtain cookie store
final CookieStore cookieStore = clientContext.getCookieStore();
if (cookieStore == null) {
Expand Down Expand Up @@ -184,6 +181,21 @@ public void process(final HttpRequest request, final EntityDetails entity, final
return;
}
final CookieSpec cookieSpec = factory.create(clientContext);

// Stick the CookieSpec and CookieOrigin instances to the HTTP context
// so they could be obtained by the response interceptor
clientContext.setCookieSpec(cookieSpec);
clientContext.setCookieOrigin(cookieOrigin);

// Check if a Cookie header is already present
if (request.containsHeader(HttpHeaders.COOKIE)) {
if (LOG.isDebugEnabled()) {
LOG.debug("{} Skipping cookie addition, Cookie header already present in the request", exchangeId);
}
// Skip adding cookies if the Cookie header is already present
return;
}

// Get all cookies available in the HTTP state
final List<Cookie> cookies = cookieStore.getCookies();
// Find cookies matching the given origin
Expand Down Expand Up @@ -218,11 +230,6 @@ public void process(final HttpRequest request, final EntityDetails entity, final
request.addHeader(header);
}
}

// Stick the CookieSpec and CookieOrigin instances to the HTTP context
// so they could be obtained by the response interceptor
clientContext.setCookieSpec(cookieSpec);
clientContext.setCookieOrigin(cookieOrigin);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,62 @@ void testSkipAddingCookiesWhenCookieHeaderPresent() throws Exception {
Assertions.assertEquals(1, headers.length);
Assertions.assertEquals("existingCookie=existingValue", headers[0].getValue());
}

@Test
void testCookieOriginUpdatedWhenCookieHeaderPresent() throws Exception {
final HttpClientContext context = HttpClientContext.create();
context.setCookieStore(this.cookieStore);
context.setCookieSpecRegistry(this.cookieSpecRegistry);

final HttpRequestInterceptor interceptor = RequestAddCookies.INSTANCE;

// First exchange on this context: cookies are matched for localhost.local
final HttpRequest request1 = new BasicHttpRequest("GET", this.target, "/");
context.setRoute(new HttpRoute(this.target, null, false));
interceptor.process(request1, null, context);
Assertions.assertEquals("localhost.local", context.getCookieOrigin().getHost());

// Second exchange on the same context to a different host with an explicit Cookie header
final HttpHost otherHost = new HttpHost("other.local", 80);
final HttpRequest request2 = new BasicHttpRequest("GET", otherHost, "/stuff/");
request2.addHeader("Cookie", "existingCookie=existingValue");
context.setRoute(new HttpRoute(otherHost, null, false));
interceptor.process(request2, null, context);

final Header[] headers = request2.getHeaders("Cookie");
Assertions.assertEquals(1, headers.length);
Assertions.assertEquals("existingCookie=existingValue", headers[0].getValue());

// The cookie origin must describe the request being executed, not the previous one
final CookieOrigin cookieOrigin = context.getCookieOrigin();
Assertions.assertNotNull(cookieOrigin);
Assertions.assertEquals("other.local", cookieOrigin.getHost());
Assertions.assertEquals(80, cookieOrigin.getPort());
Assertions.assertEquals("/stuff/", cookieOrigin.getPath());
Assertions.assertNotNull(context.getCookieSpec());
}

@Test
void testCookieOriginResetForTraceRequest() throws Exception {
final HttpClientContext context = HttpClientContext.create();
context.setCookieStore(this.cookieStore);
context.setCookieSpecRegistry(this.cookieSpecRegistry);

final HttpRequestInterceptor interceptor = RequestAddCookies.INSTANCE;

final HttpRequest request1 = new BasicHttpRequest("GET", this.target, "/");
context.setRoute(new HttpRoute(this.target, null, false));
interceptor.process(request1, null, context);
Assertions.assertNotNull(context.getCookieOrigin());

final HttpHost otherHost = new HttpHost("other.local", 80);
final HttpRequest request2 = new BasicHttpRequest("TRACE", otherHost, "/");
context.setRoute(new HttpRoute(otherHost, null, false));
interceptor.process(request2, null, context);

Assertions.assertNull(context.getCookieOrigin());
Assertions.assertNull(context.getCookieSpec());
}
@Test
void testAddCookiesWithRequestPathContainingQuery() throws Exception {
final HttpRequest request = new BasicHttpRequest("GET", "/stuff?foo=bar");
Expand Down
Loading