Skip to content

Commit 828cac8

Browse files
author
Steve Riesenberg
committed
Fix case sensitive headers comparison
Closes gh-10557
1 parent aefd2d4 commit 828cac8

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

web/src/main/java/org/springframework/security/web/server/header/StaticServerHttpHeadersWriter.java

+10-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.springframework.security.web.server.header;
1818

1919
import java.util.Arrays;
20-
import java.util.Collections;
2120

2221
import reactor.core.publisher.Mono;
2322

@@ -41,8 +40,16 @@ public StaticServerHttpHeadersWriter(HttpHeaders headersToAdd) {
4140
@Override
4241
public Mono<Void> writeHttpHeaders(ServerWebExchange exchange) {
4342
HttpHeaders headers = exchange.getResponse().getHeaders();
44-
boolean containsOneHeaderToAdd = Collections.disjoint(headers.keySet(), this.headersToAdd.keySet());
45-
if (containsOneHeaderToAdd) {
43+
// Note: We need to ensure that the following algorithm compares headers
44+
// case insensitively, which should be true of headers.containsKey().
45+
boolean containsNoHeadersToAdd = true;
46+
for (String headerName : this.headersToAdd.keySet()) {
47+
if (headers.containsKey(headerName)) {
48+
containsNoHeadersToAdd = false;
49+
break;
50+
}
51+
}
52+
if (containsNoHeadersToAdd) {
4653
this.headersToAdd.forEach(headers::put);
4754
}
4855
return Mono.empty();

web/src/test/java/org/springframework/security/web/server/header/StaticServerHttpHeadersWriterTests.java

+21
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,14 @@
1616

1717
package org.springframework.security.web.server.header;
1818

19+
import java.util.Locale;
20+
1921
import org.junit.Test;
2022

2123
import org.springframework.http.HttpHeaders;
2224
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
2325
import org.springframework.mock.web.server.MockServerWebExchange;
26+
import org.springframework.util.LinkedMultiValueMap;
2427
import org.springframework.web.server.ServerWebExchange;
2528

2629
import static org.assertj.core.api.Assertions.assertThat;
@@ -56,6 +59,24 @@ public void writeHeadersWhenSingleHeaderAndHeaderWrittenThenSuccess() {
5659
.containsOnly(headerValue);
5760
}
5861

62+
// gh-10557
63+
@Test
64+
public void writeHeadersWhenHeaderWrittenWithDifferentCaseThenDoesNotWriteHeaders() {
65+
String headerName = HttpHeaders.CACHE_CONTROL.toLowerCase(Locale.ROOT);
66+
String headerValue = "max-age=120";
67+
this.headers.set(headerName, headerValue);
68+
// Note: This test inverts which collection uses case sensitive headers,
69+
// due to the fact that gh-10557 reports NettyHeadersAdapter as the
70+
// response headers implementation, which is not accessible here.
71+
HttpHeaders caseSensitiveHeaders = new HttpHeaders(new LinkedMultiValueMap<>());
72+
caseSensitiveHeaders.set(HttpHeaders.CACHE_CONTROL, CacheControlServerHttpHeadersWriter.CACHE_CONTRTOL_VALUE);
73+
caseSensitiveHeaders.set(HttpHeaders.PRAGMA, CacheControlServerHttpHeadersWriter.PRAGMA_VALUE);
74+
caseSensitiveHeaders.set(HttpHeaders.EXPIRES, CacheControlServerHttpHeadersWriter.EXPIRES_VALUE);
75+
this.writer = new StaticServerHttpHeadersWriter(caseSensitiveHeaders);
76+
this.writer.writeHttpHeaders(this.exchange);
77+
assertThat(this.headers.get(headerName)).containsOnly(headerValue);
78+
}
79+
5980
@Test
6081
public void writeHeadersWhenMultiHeaderThenWritesAllHeaders() {
6182
this.writer = StaticServerHttpHeadersWriter.builder()

0 commit comments

Comments
 (0)