Skip to content

Commit b707d75

Browse files
bclozellxbzmy
authored andcommitted
Allow ServerHttpRequest content-type mutation
Prior to this commit, `ServerHttpRequest.mutate()` would not reflect changes made on the "Accept" and "Content-Type" HTTP headers. This was due to the fact that the instantiation of a new request based on the mutated values would not use the writable HTTP headers used during the mutation, but rather a read-only view of the headers backed by `ReadOnlyHttpHeaders`. `ReadOnlyHttpHeaders` caches those values for performance reasons, so getting those from the new request would not reflect the changes made during the mutation phase. This commit ensures that the new request uses the mutated headers. Fixes spring-projectsgh-26615
1 parent 57a68ad commit b707d75

File tree

2 files changed

+18
-3
lines changed

2 files changed

+18
-3
lines changed

spring-web/src/main/java/org/springframework/http/server/reactive/DefaultServerHttpRequestBuilder.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
*
3939
* @author Rossen Stoyanchev
4040
* @author Sebastien Deleuze
41+
* @author Brian Clozel
4142
* @since 5.0
4243
*/
4344
class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder {
@@ -131,7 +132,7 @@ public ServerHttpRequest.Builder remoteAddress(InetSocketAddress remoteAddress)
131132
@Override
132133
public ServerHttpRequest build() {
133134
return new MutatedServerHttpRequest(getUriToUse(), this.contextPath,
134-
this.httpMethodValue, this.sslInfo, this.remoteAddress, this.body, this.originalRequest);
135+
this.httpMethodValue, this.sslInfo, this.remoteAddress, this.headers, this.body, this.originalRequest);
135136
}
136137

137138
private URI getUriToUse() {
@@ -190,9 +191,9 @@ private static class MutatedServerHttpRequest extends AbstractServerHttpRequest
190191

191192
public MutatedServerHttpRequest(URI uri, @Nullable String contextPath,
192193
String methodValue, @Nullable SslInfo sslInfo, @Nullable InetSocketAddress remoteAddress,
193-
Flux<DataBuffer> body, ServerHttpRequest originalRequest) {
194+
HttpHeaders headers, Flux<DataBuffer> body, ServerHttpRequest originalRequest) {
194195

195-
super(uri, contextPath, originalRequest.getHeaders());
196+
super(uri, contextPath, headers);
196197
this.methodValue = methodValue;
197198
this.remoteAddress = (remoteAddress != null ? remoteAddress : originalRequest.getRemoteAddress());
198199
this.sslInfo = (sslInfo != null ? sslInfo : originalRequest.getSslInfo());

spring-web/src/test/java/org/springframework/http/server/reactive/ServerHttpRequestTests.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
3232
import org.springframework.http.HttpMethod;
33+
import org.springframework.http.MediaType;
3334
import org.springframework.util.MultiValueMap;
3435
import org.springframework.web.testfixture.servlet.DelegatingServletInputStream;
3536
import org.springframework.web.testfixture.servlet.MockAsyncContext;
@@ -46,6 +47,7 @@
4647
*
4748
* @author Rossen Stoyanchev
4849
* @author Sam Brannen
50+
* @author Brian Clozel
4951
*/
5052
public class ServerHttpRequestTests {
5153

@@ -166,6 +168,18 @@ public void mutateHeaderBySettingHeaderValues() throws Exception {
166168
assertThat(request.getHeaders().get(headerName)).containsExactly(headerValue3);
167169
}
168170

171+
@Test // gh-26615
172+
void mutateContentTypeHeaderValue() throws Exception {
173+
ServerHttpRequest request = createRequest("/path").mutate()
174+
.headers(headers -> headers.setContentType(MediaType.APPLICATION_JSON)).build();
175+
176+
assertThat(request.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_JSON);
177+
178+
ServerHttpRequest mutated = request.mutate()
179+
.headers(headers -> headers.setContentType(MediaType.APPLICATION_CBOR)).build();
180+
assertThat(mutated.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_CBOR);
181+
}
182+
169183
@Test
170184
void mutateWithExistingContextPath() throws Exception {
171185
ServerHttpRequest request = createRequest("/context/path", "/context");

0 commit comments

Comments
 (0)