Skip to content

Commit 1fd6ded

Browse files
committed
Polishing
Closes gh-34081
1 parent 667004e commit 1fd6ded

File tree

6 files changed

+79
-66
lines changed

6 files changed

+79
-66
lines changed

spring-web/src/main/java/org/springframework/http/client/reactive/JdkClientHttpConnector.java

+14-11
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.springframework.http.HttpMethod;
3838
import org.springframework.http.ResponseCookie;
3939
import org.springframework.util.Assert;
40+
import org.springframework.util.MultiValueMap;
4041

4142
/**
4243
* {@link ClientHttpConnector} for the Java {@link HttpClient}.
@@ -99,7 +100,7 @@ public void setBufferFactory(DataBufferFactory bufferFactory) {
99100
}
100101

101102
/**
102-
* Set the underlying {@code HttpClient}'s read timeout as a {@code Duration}.
103+
* Set the underlying {@code HttpClient} read timeout as a {@code Duration}.
103104
* <p>Default is the system's default timeout.
104105
* @since 6.2
105106
* @see java.net.http.HttpRequest.Builder#timeout
@@ -126,21 +127,23 @@ public void setCookieParser(ResponseCookie.Parser parser) {
126127
public Mono<ClientHttpResponse> connect(
127128
HttpMethod method, URI uri, Function<? super ClientHttpRequest, Mono<Void>> requestCallback) {
128129

129-
JdkClientHttpRequest jdkClientHttpRequest = new JdkClientHttpRequest(method, uri, this.bufferFactory,
130-
this.readTimeout);
130+
JdkClientHttpRequest request =
131+
new JdkClientHttpRequest(method, uri, this.bufferFactory, this.readTimeout);
131132

132-
return requestCallback.apply(jdkClientHttpRequest).then(Mono.defer(() -> {
133-
HttpRequest httpRequest = jdkClientHttpRequest.getNativeRequest();
133+
return requestCallback.apply(request).then(Mono.defer(() -> {
134+
HttpRequest nativeRequest = request.getNativeRequest();
134135

135136
CompletableFuture<HttpResponse<Flow.Publisher<List<ByteBuffer>>>> future =
136-
this.httpClient.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofPublisher());
137+
this.httpClient.sendAsync(nativeRequest, HttpResponse.BodyHandlers.ofPublisher());
137138

138-
return Mono.fromCompletionStage(future)
139-
.map(response -> {
140-
List<String> headers = response.headers().allValues(HttpHeaders.SET_COOKIE);
141-
return new JdkClientHttpResponse(response, this.bufferFactory, this.cookieParser.parse(headers));
142-
});
139+
return Mono.fromCompletionStage(future).map(response ->
140+
new JdkClientHttpResponse(response, this.bufferFactory, parseCookies(response)));
143141
}));
144142
}
145143

144+
private MultiValueMap<String, ResponseCookie> parseCookies(HttpResponse<?> response) {
145+
List<String> headers = response.headers().allValues(HttpHeaders.SET_COOKIE);
146+
return this.cookieParser.parse(headers);
147+
}
148+
146149
}

spring-web/src/main/java/org/springframework/http/client/reactive/JdkClientHttpRequest.java

+30-29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -59,8 +59,9 @@ class JdkClientHttpRequest extends AbstractClientHttpRequest {
5959
private final HttpRequest.Builder builder;
6060

6161

62-
public JdkClientHttpRequest(HttpMethod httpMethod, URI uri, DataBufferFactory bufferFactory,
63-
@Nullable Duration readTimeout) {
62+
public JdkClientHttpRequest(
63+
HttpMethod httpMethod, URI uri, DataBufferFactory bufferFactory, @Nullable Duration readTimeout) {
64+
6465
Assert.notNull(httpMethod, "HttpMethod is required");
6566
Assert.notNull(uri, "URI is required");
6667
Assert.notNull(bufferFactory, "DataBufferFactory is required");
@@ -97,32 +98,6 @@ public <T> T getNativeRequest() {
9798
}
9899

99100

100-
@Override
101-
protected void applyHeaders() {
102-
for (Map.Entry<String, List<String>> entry : getHeaders().headerSet()) {
103-
if (entry.getKey().equalsIgnoreCase(HttpHeaders.CONTENT_LENGTH)) {
104-
// content-length is specified when writing
105-
continue;
106-
}
107-
for (String value : entry.getValue()) {
108-
this.builder.header(entry.getKey(), value);
109-
}
110-
}
111-
if (!getHeaders().containsHeader(HttpHeaders.ACCEPT)) {
112-
this.builder.header(HttpHeaders.ACCEPT, "*/*");
113-
}
114-
}
115-
116-
@Override
117-
protected void applyCookies() {
118-
MultiValueMap<String, HttpCookie> cookies = getCookies();
119-
if (cookies.isEmpty()) {
120-
return;
121-
}
122-
this.builder.header(HttpHeaders.COOKIE, cookies.values().stream()
123-
.flatMap(List::stream).map(HttpCookie::toString).collect(Collectors.joining(";")));
124-
}
125-
126101
@Override
127102
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
128103
return doCommit(() -> {
@@ -162,4 +137,30 @@ public Mono<Void> setComplete() {
162137
});
163138
}
164139

140+
@Override
141+
protected void applyHeaders() {
142+
for (Map.Entry<String, List<String>> entry : getHeaders().headerSet()) {
143+
if (entry.getKey().equalsIgnoreCase(HttpHeaders.CONTENT_LENGTH)) {
144+
// content-length is specified when writing
145+
continue;
146+
}
147+
for (String value : entry.getValue()) {
148+
this.builder.header(entry.getKey(), value);
149+
}
150+
}
151+
if (!getHeaders().containsHeader(HttpHeaders.ACCEPT)) {
152+
this.builder.header(HttpHeaders.ACCEPT, "*/*");
153+
}
154+
}
155+
156+
@Override
157+
protected void applyCookies() {
158+
MultiValueMap<String, HttpCookie> cookies = getCookies();
159+
if (cookies.isEmpty()) {
160+
return;
161+
}
162+
this.builder.header(HttpHeaders.COOKIE, cookies.values().stream()
163+
.flatMap(List::stream).map(HttpCookie::toString).collect(Collectors.joining(";")));
164+
}
165+
165166
}

spring-web/src/main/java/org/springframework/http/client/reactive/JdkClientHttpResponse.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@
4747
*/
4848
class JdkClientHttpResponse extends AbstractClientHttpResponse {
4949

50-
public JdkClientHttpResponse(HttpResponse<Flow.Publisher<List<ByteBuffer>>> response,
50+
public JdkClientHttpResponse(
51+
HttpResponse<Flow.Publisher<List<ByteBuffer>>> response,
5152
DataBufferFactory bufferFactory, MultiValueMap<String, ResponseCookie> cookies) {
5253

5354
super(HttpStatusCode.valueOf(response.statusCode()),
@@ -63,7 +64,9 @@ private static HttpHeaders adaptHeaders(HttpResponse<Flow.Publisher<List<ByteBuf
6364
return HttpHeaders.readOnlyHttpHeaders(multiValueMap);
6465
}
6566

66-
private static Flux<DataBuffer> adaptBody(HttpResponse<Flow.Publisher<List<ByteBuffer>>> response, DataBufferFactory bufferFactory) {
67+
private static Flux<DataBuffer> adaptBody(
68+
HttpResponse<Flow.Publisher<List<ByteBuffer>>> response, DataBufferFactory bufferFactory) {
69+
6770
return JdkFlowAdapter.flowPublisherToFlux(response.body())
6871
.flatMapIterable(Function.identity())
6972
.map(bufferFactory::wrap)

spring-web/src/main/java/org/springframework/http/client/reactive/JettyClientHttpConnector.java

+9-3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import org.eclipse.jetty.client.HttpClient;
2424
import org.eclipse.jetty.client.Request;
25+
import org.eclipse.jetty.reactive.client.ReactiveResponse;
2526
import org.jspecify.annotations.Nullable;
2627
import reactor.core.publisher.Flux;
2728
import reactor.core.publisher.Mono;
@@ -32,6 +33,7 @@
3233
import org.springframework.http.HttpMethod;
3334
import org.springframework.http.ResponseCookie;
3435
import org.springframework.util.Assert;
36+
import org.springframework.util.MultiValueMap;
3537

3638
/**
3739
* {@link ClientHttpConnector} for the Jetty Reactive Streams HttpClient.
@@ -126,11 +128,15 @@ public Mono<ClientHttpResponse> connect(HttpMethod method, URI uri,
126128

127129
private Mono<ClientHttpResponse> execute(JettyClientHttpRequest request) {
128130
return Mono.fromDirect(request.toReactiveRequest()
129-
.response((reactiveResponse, chunkPublisher) -> {
131+
.response((response, chunkPublisher) -> {
130132
Flux<DataBuffer> content = Flux.from(chunkPublisher).map(this.bufferFactory::wrap);
131-
List<String> headers = reactiveResponse.getHeaders().getValuesList(HttpHeaders.SET_COOKIE);
132-
return Mono.just(new JettyClientHttpResponse(reactiveResponse, content, this.cookieParser.parse(headers)));
133+
return Mono.just(new JettyClientHttpResponse(response, content, parseCookies(response)));
133134
}));
134135
}
135136

137+
private MultiValueMap<String, ResponseCookie> parseCookies(ReactiveResponse response) {
138+
List<String> headers = response.getHeaders().getValuesList(HttpHeaders.SET_COOKIE);
139+
return this.cookieParser.parse(headers);
140+
}
141+
136142
}

spring-web/src/main/java/org/springframework/http/client/reactive/JettyClientHttpRequest.java

+18-18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -72,11 +72,6 @@ public URI getURI() {
7272
return this.jettyRequest.getURI();
7373
}
7474

75-
@Override
76-
public Mono<Void> setComplete() {
77-
return doCommit();
78-
}
79-
8075
@Override
8176
public DataBufferFactory bufferFactory() {
8277
return this.bufferFactory;
@@ -88,6 +83,12 @@ public <T> T getNativeRequest() {
8883
return (T) this.jettyRequest;
8984
}
9085

86+
@Override
87+
protected HttpHeaders initReadOnlyHeaders() {
88+
return HttpHeaders.readOnlyHttpHeaders(new JettyHeadersAdapter(this.jettyRequest.getHeaders()));
89+
}
90+
91+
9192
@Override
9293
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
9394
return Mono.<Void>create(sink -> {
@@ -108,13 +109,7 @@ public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends Data
108109
.doOnDiscard(DataBuffer.class, DataBufferUtils::release));
109110
}
110111

111-
private String getContentType() {
112-
MediaType contentType = getHeaders().getContentType();
113-
return contentType != null ? contentType.toString() : MediaType.APPLICATION_OCTET_STREAM_VALUE;
114-
}
115-
116112
private List<Content.Chunk> toContentChunks(DataBuffer dataBuffer) {
117-
118113
List<Content.Chunk> result = new ArrayList<>(1);
119114
DataBuffer.ByteBufferIterator iterator = dataBuffer.readableByteBuffers();
120115
while (iterator.hasNext()) {
@@ -131,11 +126,14 @@ private List<Content.Chunk> toContentChunks(DataBuffer dataBuffer) {
131126
return result;
132127
}
133128

129+
private String getContentType() {
130+
MediaType contentType = getHeaders().getContentType();
131+
return (contentType != null ? contentType.toString() : MediaType.APPLICATION_OCTET_STREAM_VALUE);
132+
}
133+
134134
@Override
135-
protected void applyCookies() {
136-
getCookies().values().stream().flatMap(Collection::stream)
137-
.map(cookie -> HttpCookie.build(cookie.getName(), cookie.getValue()).build())
138-
.forEach(this.jettyRequest::cookie);
135+
public Mono<Void> setComplete() {
136+
return doCommit();
139137
}
140138

141139
@Override
@@ -150,8 +148,10 @@ protected void applyHeaders() {
150148
}
151149

152150
@Override
153-
protected HttpHeaders initReadOnlyHeaders() {
154-
return HttpHeaders.readOnlyHttpHeaders(new JettyHeadersAdapter(this.jettyRequest.getHeaders()));
151+
protected void applyCookies() {
152+
getCookies().values().stream().flatMap(Collection::stream)
153+
.map(cookie -> HttpCookie.build(cookie.getName(), cookie.getValue()).build())
154+
.forEach(this.jettyRequest::cookie);
155155
}
156156

157157
@Override

spring-web/src/main/java/org/springframework/http/client/reactive/JettyClientHttpResponse.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -37,10 +37,10 @@
3737
class JettyClientHttpResponse extends AbstractClientHttpResponse {
3838

3939
public JettyClientHttpResponse(
40-
ReactiveResponse reactiveResponse, Flux<DataBuffer> content,
40+
ReactiveResponse response, Flux<DataBuffer> content,
4141
MultiValueMap<String, ResponseCookie> cookies) {
4242

43-
super(HttpStatusCode.valueOf(reactiveResponse.getStatus()), adaptHeaders(reactiveResponse), cookies, content);
43+
super(HttpStatusCode.valueOf(response.getStatus()), adaptHeaders(response), cookies, content);
4444
}
4545

4646
private static HttpHeaders adaptHeaders(ReactiveResponse response) {

0 commit comments

Comments
 (0)