From a06bbccf9ecccd41f1099e0462005478cc84974b Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Fri, 25 Oct 2024 10:22:12 +0200 Subject: [PATCH] HttpHeaders.writeableHttpHeaders should unwrap many times Prior to this commit, the `HttpHeaders.writeableHttpHeaders` would only consider headers read-only instances that were wrapped once by `HttpHeaders.readOnlyHttpHeaders`. This does not work when other `HttpHeaders` wrappers are involved in the chain. This commit ensures that `writeableHttpHeaders` unwraps all headers instances down to the actual multivalue map and create a new headers instance out of it. Fixes gh-33789 --- .../main/java/org/springframework/http/HttpHeaders.java | 5 ++++- .../java/org/springframework/http/HttpHeadersTests.java | 8 ++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java index 5e742ee9f994..0c7e1d426077 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java +++ b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java @@ -1872,7 +1872,10 @@ public static HttpHeaders writableHttpHeaders(HttpHeaders headers) { if (headers == EMPTY) { return new HttpHeaders(); } - return (headers instanceof ReadOnlyHttpHeaders ? new HttpHeaders(headers.headers) : headers); + while (headers.headers instanceof HttpHeaders wrapped) { + headers = wrapped; + } + return new HttpHeaders(headers.headers); } /** diff --git a/spring-web/src/test/java/org/springframework/http/HttpHeadersTests.java b/spring-web/src/test/java/org/springframework/http/HttpHeadersTests.java index 80d62a344acd..5725b0b4324c 100644 --- a/spring-web/src/test/java/org/springframework/http/HttpHeadersTests.java +++ b/spring-web/src/test/java/org/springframework/http/HttpHeadersTests.java @@ -57,6 +57,14 @@ class HttpHeadersTests { private final HttpHeaders headers = new HttpHeaders(); + @Test + void writableHttpHeadersUnwrapsMultiple() { + HttpHeaders originalExchangeHeaders = HttpHeaders.readOnlyHttpHeaders(new HttpHeaders()); + HttpHeaders firewallHeaders = new HttpHeaders(originalExchangeHeaders); + HttpHeaders writeable = HttpHeaders.writableHttpHeaders(firewallHeaders); + writeable.setContentType(MediaType.APPLICATION_JSON); + } + @Test void getOrEmpty() { String key = "FOO";