Browse Source

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
pull/25999/head
Arjen Poutsma 4 years ago
parent
commit
885a5048c1
  1. 32
      spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClientBuilder.java
  2. 32
      spring-webflux/src/test/java/org/springframework/web/reactive/function/client/DefaultWebClientTests.java

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

@ -274,9 +274,13 @@ final class DefaultWebClientBuilder implements WebClient.Builder { @@ -274,9 +274,13 @@ final class DefaultWebClientBuilder implements WebClient.Builder {
.map(filter -> filter.apply(exchange))
.orElse(exchange) : exchange);
HttpHeaders defaultHeaders = copyDefaultHeaders();
MultiValueMap<String, String> defaultCookies = copyDefaultCookies();
return new DefaultWebClient(filteredExchange, initUriBuilderFactory(),
this.defaultHeaders != null ? HttpHeaders.readOnlyHttpHeaders(this.defaultHeaders) : null,
this.defaultCookies != null ? CollectionUtils.unmodifiableMultiValueMap(this.defaultCookies) : null,
defaultHeaders,
defaultCookies,
this.defaultRequest, new DefaultWebClientBuilder(this));
}
@ -313,4 +317,28 @@ final class DefaultWebClientBuilder implements WebClient.Builder { @@ -313,4 +317,28 @@ final class DefaultWebClientBuilder implements WebClient.Builder {
return factory;
}
@Nullable
private HttpHeaders copyDefaultHeaders() {
if (this.defaultHeaders != null) {
HttpHeaders copy = new HttpHeaders();
this.defaultHeaders.forEach((key, values) -> copy.put(key, new ArrayList<>(values)));
return HttpHeaders.readOnlyHttpHeaders(copy);
}
else {
return null;
}
}
@Nullable
private MultiValueMap<String, String> copyDefaultCookies() {
if (this.defaultCookies != null) {
MultiValueMap<String, String> copy = new LinkedMultiValueMap<>(this.defaultCookies.size());
this.defaultCookies.forEach((key, values) -> copy.put(key, new ArrayList<>(values)));
return CollectionUtils.unmodifiableMultiValueMap(copy);
}
else {
return null;
}
}
}

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

@ -142,7 +142,8 @@ public class DefaultWebClientTests { @@ -142,7 +142,8 @@ public class DefaultWebClientTests {
@Test
public void defaultHeaderAndCookie() {
WebClient client = this.builder
.defaultHeader("Accept", "application/json").defaultCookie("id", "123")
.defaultHeader("Accept", "application/json")
.defaultCookie("id", "123")
.build();
client.get().uri("/path")
@ -170,6 +171,35 @@ public class DefaultWebClientTests { @@ -170,6 +171,35 @@ public class DefaultWebClientTests {
assertThat(request.cookies().getFirst("id")).isEqualTo("456");
}
@Test
public void defaultHeaderAndCookieCopies() {
WebClient client1 = this.builder
.defaultHeader("Accept", "application/json")
.defaultCookie("id", "123")
.build();
WebClient client2 = this.builder
.defaultHeader("Accept", "application/xml")
.defaultCookies(cookies -> cookies.set("id", "456"))
.build();
client1.get().uri("/path")
.retrieve().bodyToMono(Void.class).block(Duration.ofSeconds(10));
ClientRequest request = verifyAndGetRequest();
assertThat(request.headers().getFirst("Accept")).isEqualTo("application/json");
assertThat(request.cookies().getFirst("id")).isEqualTo("123");
client2.get().uri("/path")
.retrieve().bodyToMono(Void.class).block(Duration.ofSeconds(10));
request = verifyAndGetRequest();
assertThat(request.headers().getFirst("Accept")).isEqualTo("application/xml");
assertThat(request.cookies().getFirst("id")).isEqualTo("456");
}
@Test
public void defaultRequest() {
ThreadLocal<String> context = new NamedThreadLocal<>("foo");

Loading…
Cancel
Save