Skip to content

WebClient sends Cookie header when no cookies defined when using JdkClientHttpRequest #33086

Closed as not planned
@jomarl

Description

@jomarl

WebClient using built in JdkClientHttpConnector sends a empty Cookie header even if there are no cookies added to the request.

The empty Cookie header seems to create trouble with some infrastructure components like LoadBalancers and Firewalls, e.g. the request can end up being rejected.

Example request that is generated.

GET https://some-api.host.tld
Accept: application/json
Content-Length: 0
Host: some-api.host.tld
User-Agent: Java-http-client/17.0.7
Cookie:

The issue (Cookie header) is not present when using the Netty or Jetty reactive client implementations.

The header seems to be applied in JdkClientHttpRequest#applyCookies() method, and by the implementation it looks like it ends up adding the Cookie header even if there are no cookies. There is no way to override or remove this header when setting up a request using the WebClient, as it's added after all interception points that client code can use to remove it.

JdkClientHttpRequest:

	@Override
	protected void applyCookies() {
		this.builder.header(HttpHeaders.COOKIE, getCookies().values().stream()
				.flatMap(List::stream).map(HttpCookie::toString).collect(Collectors.joining(";")));
	}

This ends up calling the builder with a empty string as value if there are no cookies, which passes the header validation and we end up "automagically" getting a unwanted Cookie header on all our requests. As mentioned some Loadbalancers, Firewalls, API Gateways etc. do not allow this type of header (not sure what the RFC says), and the only workaround using the JDK client seems to be to set some dummy cookie so that the header is set to something like Cookie: dummy=dummy; Getting rid of the header do not seem possible from client code.

ReactorClientHttpRequest (Netty):

	@Override
	protected void applyCookies() {
		getCookies().values().forEach(values -> values.forEach(value -> {
			DefaultCookie cookie = new DefaultCookie(value.getName(), value.getValue());
			this.request.addCookie(cookie);
		}));
	}

In this implementation a Cookie header is only added if there are any cookies to add.

Spring Boot 3.2, Spring Framework version 6.1.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    in: webIssues in web modules (web, webmvc, webflux, websocket)status: duplicateA duplicate of another issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions