mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-22 05:49:04 +00:00
Consistent adaptation of HTTP headers on Servlet responses
Includes use of Servlet 6.1 setCharacterEncoding(Charset) Closes gh-36343
This commit is contained in:
+2
-2
@@ -174,10 +174,10 @@ public class ServletServerHttpRequest implements ServerHttpRequest {
|
||||
if (contentType != null && contentType.getCharset() == null) {
|
||||
String requestEncoding = this.servletRequest.getCharacterEncoding();
|
||||
if (StringUtils.hasLength(requestEncoding)) {
|
||||
Charset charSet = Charset.forName(requestEncoding);
|
||||
Charset charset = Charset.forName(requestEncoding);
|
||||
Map<String, String> params = new LinkedCaseInsensitiveMap<>();
|
||||
params.putAll(contentType.getParameters());
|
||||
params.put("charset", charSet.toString());
|
||||
params.put("charset", charset.toString());
|
||||
MediaType mediaType = new MediaType(contentType.getType(), contentType.getSubtype(), params);
|
||||
this.headers.setContentType(mediaType);
|
||||
}
|
||||
|
||||
+25
-2
@@ -24,6 +24,7 @@ import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatusCode;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -87,13 +88,13 @@ public class ServletServerHttpResponse implements ServerHttpResponse {
|
||||
@Override
|
||||
public OutputStream getBody() throws IOException {
|
||||
this.bodyUsed = true;
|
||||
this.headersWritten = true;
|
||||
writeHeaders();
|
||||
return this.servletResponse.getOutputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
this.headersWritten = true;
|
||||
writeHeaders();
|
||||
if (this.bodyUsed) {
|
||||
this.servletResponse.flushBuffer();
|
||||
}
|
||||
@@ -101,6 +102,28 @@ public class ServletServerHttpResponse implements ServerHttpResponse {
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
writeHeaders();
|
||||
}
|
||||
|
||||
private void writeHeaders() {
|
||||
if (!this.headersWritten) {
|
||||
// HttpServletResponse exposes some headers as properties: we should include those if not already present
|
||||
if (this.servletResponse.getContentType() == null && this.headers.containsHeader(HttpHeaders.CONTENT_TYPE)) {
|
||||
this.servletResponse.setContentType(this.headers.getFirst(HttpHeaders.CONTENT_TYPE));
|
||||
}
|
||||
if (this.servletResponse.getCharacterEncoding() == null && this.headers.containsHeader(HttpHeaders.CONTENT_TYPE)) {
|
||||
try {
|
||||
// Lazy parsing into MediaType
|
||||
MediaType contentType = this.headers.getContentType();
|
||||
if (contentType != null) {
|
||||
this.servletResponse.setCharacterEncoding(contentType.getCharset());
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Leave character encoding unspecified
|
||||
}
|
||||
}
|
||||
}
|
||||
this.headersWritten = true;
|
||||
}
|
||||
|
||||
|
||||
+19
-18
@@ -18,7 +18,6 @@ package org.springframework.http.server.reactive;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import jakarta.servlet.AsyncContext;
|
||||
import jakarta.servlet.AsyncEvent;
|
||||
@@ -122,31 +121,34 @@ class ServletServerHttpResponse extends AbstractListenerServerHttpResponse {
|
||||
}
|
||||
|
||||
protected void adaptHeaders(boolean removeAdaptedHeaders) {
|
||||
MediaType contentType = null;
|
||||
try {
|
||||
contentType = getHeaders().getContentType();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
String rawContentType = getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
|
||||
this.response.setContentType(rawContentType);
|
||||
}
|
||||
if (this.response.getContentType() == null && contentType != null) {
|
||||
this.response.setContentType(contentType.toString());
|
||||
HttpHeaders headers = getHeaders();
|
||||
// HttpServletResponse exposes some headers as properties: we should include those if not already present
|
||||
|
||||
if (this.response.getContentType() == null && headers.containsHeader(HttpHeaders.CONTENT_TYPE)) {
|
||||
this.response.setContentType(headers.getFirst(HttpHeaders.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
Charset charset = (contentType != null ? contentType.getCharset() : null);
|
||||
if (this.response.getCharacterEncoding() == null && charset != null) {
|
||||
this.response.setCharacterEncoding(charset.name());
|
||||
if (this.response.getCharacterEncoding() == null && headers.containsHeader(HttpHeaders.CONTENT_TYPE)) {
|
||||
try {
|
||||
// Lazy parsing into MediaType
|
||||
MediaType contentType = headers.getContentType();
|
||||
if (contentType != null) {
|
||||
this.response.setCharacterEncoding(contentType.getCharset());
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Leave character encoding unspecified
|
||||
}
|
||||
}
|
||||
|
||||
long contentLength = getHeaders().getContentLength();
|
||||
long contentLength = headers.getContentLength();
|
||||
if (contentLength != -1) {
|
||||
this.response.setContentLengthLong(contentLength);
|
||||
}
|
||||
|
||||
if (removeAdaptedHeaders) {
|
||||
getHeaders().remove(HttpHeaders.CONTENT_TYPE);
|
||||
getHeaders().remove(HttpHeaders.CONTENT_LENGTH);
|
||||
headers.remove(HttpHeaders.CONTENT_TYPE);
|
||||
headers.remove(HttpHeaders.CONTENT_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,7 +354,6 @@ class ServletServerHttpResponse extends AbstractListenerServerHttpResponse {
|
||||
|
||||
private class ResponseBodyProcessor extends AbstractListenerWriteProcessor<DataBuffer> {
|
||||
|
||||
|
||||
public ResponseBodyProcessor() {
|
||||
super(request.getLogPrefix());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user