Skip to content

Commit 0acb1e5

Browse files
committed
Copy default headers, cookies in WebClient builder
This commit makes copies of the default headers and cookies when a WebClient is built, so that subsequent changes to these do not affect previously built clients. Closes: gh-25992
1 parent a9dec6a commit 0acb1e5

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClientBuilder.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,14 @@ public WebClient build() {
263263
.reduce(ExchangeFilterFunction::andThen)
264264
.map(filter -> filter.apply(exchange))
265265
.orElse(exchange) : exchange);
266+
267+
HttpHeaders defaultHeaders = copyDefaultHeaders();
268+
269+
MultiValueMap<String, String> defaultCookies = copyDefaultCookies();
270+
266271
return new DefaultWebClient(filteredExchange, initUriBuilderFactory(),
267-
this.defaultHeaders != null ? HttpHeaders.readOnlyHttpHeaders(this.defaultHeaders) : null,
268-
this.defaultCookies != null ? CollectionUtils.unmodifiableMultiValueMap(this.defaultCookies) : null,
272+
defaultHeaders,
273+
defaultCookies,
269274
this.defaultRequest, new DefaultWebClientBuilder(this));
270275
}
271276

@@ -302,4 +307,28 @@ private UriBuilderFactory initUriBuilderFactory() {
302307
return factory;
303308
}
304309

310+
@Nullable
311+
private HttpHeaders copyDefaultHeaders() {
312+
if (this.defaultHeaders != null) {
313+
HttpHeaders copy = new HttpHeaders();
314+
this.defaultHeaders.forEach((key, values) -> copy.put(key, new ArrayList<>(values)));
315+
return HttpHeaders.readOnlyHttpHeaders(copy);
316+
}
317+
else {
318+
return null;
319+
}
320+
}
321+
322+
@Nullable
323+
private MultiValueMap<String, String> copyDefaultCookies() {
324+
if (this.defaultCookies != null) {
325+
MultiValueMap<String, String> copy = new LinkedMultiValueMap<>(this.defaultCookies.size());
326+
this.defaultCookies.forEach((key, values) -> copy.put(key, new ArrayList<>(values)));
327+
return CollectionUtils.unmodifiableMultiValueMap(copy);
328+
}
329+
else {
330+
return null;
331+
}
332+
}
333+
305334
}

spring-webflux/src/test/java/org/springframework/web/reactive/function/client/DefaultWebClientTests.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ public void requestHeaderAndCookie() {
130130
@Test
131131
public void defaultHeaderAndCookie() {
132132
WebClient client = this.builder
133-
.defaultHeader("Accept", "application/json").defaultCookie("id", "123")
133+
.defaultHeader("Accept", "application/json")
134+
.defaultCookie("id", "123")
134135
.build();
135136

136137
client.get().uri("/path").exchange().block(Duration.ofSeconds(10));
@@ -157,6 +158,35 @@ public void defaultHeaderAndCookieOverrides() {
157158
assertThat(request.cookies().getFirst("id")).isEqualTo("456");
158159
}
159160

161+
@Test
162+
public void defaultHeaderAndCookieCopies() {
163+
WebClient client1 = this.builder
164+
.defaultHeader("Accept", "application/json")
165+
.defaultCookie("id", "123")
166+
.build();
167+
WebClient client2 = this.builder
168+
.defaultHeader("Accept", "application/xml")
169+
.defaultCookies(cookies -> cookies.set("id", "456"))
170+
.build();
171+
172+
client1.get().uri("/path")
173+
.exchange().block(Duration.ofSeconds(10));
174+
175+
ClientRequest request = verifyAndGetRequest();
176+
assertThat(request.headers().getFirst("Accept")).isEqualTo("application/json");
177+
assertThat(request.cookies().getFirst("id")).isEqualTo("123");
178+
179+
180+
client2.get().uri("/path")
181+
.exchange().block(Duration.ofSeconds(10));
182+
183+
request = verifyAndGetRequest();
184+
assertThat(request.headers().getFirst("Accept")).isEqualTo("application/xml");
185+
assertThat(request.cookies().getFirst("id")).isEqualTo("456");
186+
187+
188+
}
189+
160190
@Test
161191
public void defaultRequest() {
162192
ThreadLocal<String> context = new NamedThreadLocal<>("foo");

0 commit comments

Comments
 (0)