Skip to content

Commit b453840

Browse files
committed
HttpHeaders no longer a MultiValueMap
Closes gh-17060
1 parent e5e962e commit b453840

23 files changed

+81
-87
lines changed

config/src/test/java/org/springframework/security/config/web/server/CorsSpecTests.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818

1919
import java.util.Arrays;
2020
import java.util.HashSet;
21-
import java.util.List;
22-
import java.util.Map;
2321
import java.util.Set;
2422

2523
import org.junit.jupiter.api.BeforeEach;
@@ -114,12 +112,13 @@ private void assertHeaders() {
114112
.exchange()
115113
.returnResult(String.class);
116114
// @formatter:on
117-
Map<String, List<String>> responseHeaders = response.getResponseHeaders();
115+
HttpHeaders responseHeaders = response.getResponseHeaders();
118116
if (!this.expectedHeaders.isEmpty()) {
119-
assertThat(responseHeaders).describedAs(response.toString()).containsAllEntriesOf(this.expectedHeaders);
117+
this.expectedHeaders.forEach(
118+
(headerName, headerValues) -> assertThat(responseHeaders.get(headerName)).isEqualTo(headerValues));
120119
}
121120
if (!this.headerNamesNotPresent.isEmpty()) {
122-
assertThat(responseHeaders.keySet()).doesNotContainAnyElementsOf(this.headerNamesNotPresent);
121+
assertThat(responseHeaders.headerNames()).doesNotContainAnyElementsOf(this.headerNamesNotPresent);
123122
}
124123
}
125124

config/src/test/java/org/springframework/security/config/web/server/HeaderSpecTests.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818

1919
import java.time.Duration;
2020
import java.util.HashSet;
21-
import java.util.List;
22-
import java.util.Map;
2321
import java.util.Set;
2422

2523
import org.junit.jupiter.api.BeforeEach;
@@ -80,14 +78,14 @@ public void setup() {
8078

8179
@Test
8280
public void headersWhenDisableThenNoSecurityHeaders() {
83-
new HashSet<>(this.expectedHeaders.keySet()).forEach(this::expectHeaderNamesNotPresent);
81+
new HashSet<>(this.expectedHeaders.headerNames()).forEach(this::expectHeaderNamesNotPresent);
8482
this.http.headers().disable();
8583
assertHeaders();
8684
}
8785

8886
@Test
8987
public void headersWhenDisableInLambdaThenNoSecurityHeaders() {
90-
new HashSet<>(this.expectedHeaders.keySet()).forEach(this::expectHeaderNamesNotPresent);
88+
new HashSet<>(this.expectedHeaders.headerNames()).forEach(this::expectHeaderNamesNotPresent);
9189
this.http.headers((headers) -> headers.disable());
9290
assertHeaders();
9391
}
@@ -515,12 +513,13 @@ private void assertHeaders() {
515513
.uri("https://example.com/")
516514
.exchange()
517515
.returnResult(String.class);
518-
Map<String, List<String>> responseHeaders = response.getResponseHeaders();
516+
HttpHeaders responseHeaders = response.getResponseHeaders();
519517
if (!this.expectedHeaders.isEmpty()) {
520-
assertThat(responseHeaders).describedAs(response.toString()).containsAllEntriesOf(this.expectedHeaders);
518+
this.expectedHeaders.forEach(
519+
(headerName, headerValues) -> assertThat(responseHeaders.get(headerName)).isEqualTo(headerValues));
521520
}
522521
if (!this.headerNamesNotPresent.isEmpty()) {
523-
assertThat(responseHeaders.keySet()).doesNotContainAnyElementsOf(this.headerNamesNotPresent);
522+
assertThat(responseHeaders.headerNames()).doesNotContainAnyElementsOf(this.headerNamesNotPresent);
524523
}
525524
}
526525

config/src/test/java/org/springframework/security/config/web/server/OidcLogoutSpecTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,7 @@ private String session(RecordedRequest request) {
945945
private MockResponse toMockResponse(FluxExchangeResult<String> result) {
946946
MockResponse response = new MockResponse();
947947
response.setResponseCode(result.getStatus().value());
948-
for (String name : result.getResponseHeaders().keySet()) {
948+
for (String name : result.getResponseHeaders().headerNames()) {
949949
response.addHeader(name, result.getResponseHeaders().getFirst(name));
950950
}
951951
String body = result.getResponseBody().blockFirst();

config/src/test/kotlin/org/springframework/security/config/web/server/ServerHttpsRedirectDslTests.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ class ServerHttpsRedirectDslTests {
127127
return http {
128128
redirectToHttps {
129129
httpsRedirectWhen {
130-
it.request.headers.containsKey("X-Requires-Https")
130+
it.request.headers.headerNames().contains("X-Requires-Https")
131131
}
132132
}
133133
}
@@ -165,7 +165,7 @@ class ServerHttpsRedirectDslTests {
165165
redirectToHttps {
166166
httpsRedirectWhen(PathPatternParserServerWebExchangeMatcher("/secure"))
167167
httpsRedirectWhen {
168-
it.request.headers.containsKey("X-Requires-Https")
168+
it.request.headers.headerNames().contains("X-Requires-Https")
169169
}
170170
}
171171
}

oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/server/BearerTokenServerAuthenticationEntryPointTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public void commenceWhenBearerTokenThenErrorInformation() {
9191
@Test
9292
public void commenceWhenNoSubscriberThenNothingHappens() {
9393
this.entryPoint.commence(this.exchange, new BadCredentialsException(""));
94-
assertThat(getResponse().getHeaders()).isEmpty();
94+
assertThat(getResponse().getHeaders().headerNames()).isEmpty();
9595
assertThat(getResponse().getStatusCode()).isNull();
9696
}
9797

web/src/main/java/org/springframework/security/web/FilterInvocation.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ public Enumeration<String> getHeaders(String name) {
267267

268268
@Override
269269
public Enumeration<String> getHeaderNames() {
270-
return Collections.enumeration(this.headers.keySet());
270+
return Collections.enumeration(this.headers.headerNames());
271271
}
272272

273273
@Override

web/src/main/java/org/springframework/security/web/server/firewall/StrictServerWebExchangeFirewall.java

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ public class StrictServerWebExchangeFirewall implements ServerWebExchangeFirewal
135135
private static final Pattern ASSIGNED_AND_NOT_ISO_CONTROL_PATTERN = Pattern
136136
.compile("[\\p{IsAssigned}&&[^\\p{IsControl}]]*");
137137

138-
private static final Predicate<String> ASSIGNED_AND_NOT_ISO_CONTROL_PREDICATE = (
139-
s) -> ASSIGNED_AND_NOT_ISO_CONTROL_PATTERN.matcher(s).matches();
138+
private static final Predicate<String> ASSIGNED_AND_NOT_ISO_CONTROL_PREDICATE = (s) -> s == null
139+
|| ASSIGNED_AND_NOT_ISO_CONTROL_PATTERN.matcher(s).matches();
140140

141141
private static final Pattern HEADER_VALUE_PATTERN = Pattern.compile("[\\p{IsAssigned}&&[[^\\p{IsControl}]||\\t]]*");
142142

@@ -198,13 +198,11 @@ public Mono<ServerWebExchange> getFirewalledExchange(ServerWebExchange exchange)
198198
exchange.getResponse().beforeCommit(() -> Mono.fromRunnable(() -> {
199199
ServerHttpResponse response = exchange.getResponse();
200200
HttpHeaders headers = response.getHeaders();
201-
for (Map.Entry<String, List<String>> header : headers.entrySet()) {
202-
String headerName = header.getKey();
203-
List<String> headerValues = header.getValue();
201+
headers.forEach((headerName, headerValues) -> {
204202
for (String headerValue : headerValues) {
205203
validateCrlf(headerName, headerValue);
206204
}
207-
}
205+
});
208206
}));
209207
return new StrictFirewallServerWebExchange(exchange);
210208
});
@@ -767,23 +765,21 @@ public String getFirst(String headerName) {
767765
}
768766

769767
@Override
770-
public List<String> get(Object key) {
771-
if (key instanceof String headerName) {
772-
validateAllowedHeaderName(headerName);
773-
}
774-
List<String> headerValues = super.get(key);
768+
public List<String> get(String headerName) {
769+
validateAllowedHeaderName(headerName);
770+
List<String> headerValues = super.get(headerName);
775771
if (headerValues == null) {
776772
return headerValues;
777773
}
778774
for (String headerValue : headerValues) {
779-
validateAllowedHeaderValue(key, headerValue);
775+
validateAllowedHeaderValue(headerName, headerValue);
780776
}
781777
return headerValues;
782778
}
783779

784780
@Override
785-
public Set<String> keySet() {
786-
Set<String> headerNames = super.keySet();
781+
public Set<String> headerNames() {
782+
Set<String> headerNames = super.headerNames();
787783
for (String headerName : headerNames) {
788784
validateAllowedHeaderName(headerName);
789785
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ public Mono<Void> writeHttpHeaders(ServerWebExchange exchange) {
4343
// Note: We need to ensure that the following algorithm compares headers
4444
// case insensitively, which should be true of headers.containsKey().
4545
boolean containsNoHeadersToAdd = true;
46-
for (String headerName : this.headersToAdd.keySet()) {
47-
if (headers.containsKey(headerName)) {
46+
for (String headerName : this.headersToAdd.headerNames()) {
47+
if (headers.containsHeader(headerName)) {
4848
containsNoHeadersToAdd = false;
4949
break;
5050
}

web/src/test/java/org/springframework/security/web/server/firewall/StrictServerWebExchangeFirewallTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ void getFirewalledExchangeGetHeaderNamesWhenControlCharacterInHeaderNameThenExce
444444
ServerWebExchange exchange = getFirewalledExchange();
445445
HttpHeaders headers = exchange.getRequest().getHeaders();
446446
assertThatExceptionOfType(ServerExchangeRejectedException.class)
447-
.isThrownBy(() -> headers.keySet().iterator().next());
447+
.isThrownBy(() -> headers.headerNames().iterator().next());
448448
}
449449

450450
@Test

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public class CacheControlServerHttpHeadersWriterTests {
4242
@Test
4343
public void writeHeadersWhenCacheHeadersThenWritesAllCacheControl() {
4444
this.writer.writeHttpHeaders(this.exchange);
45-
assertThat(this.headers).hasSize(3);
45+
assertThat(this.headers.headerNames()).hasSize(3);
4646
assertThat(this.headers.get(HttpHeaders.CACHE_CONTROL))
4747
.containsOnly(CacheControlServerHttpHeadersWriter.CACHE_CONTRTOL_VALUE);
4848
assertThat(this.headers.get(HttpHeaders.EXPIRES))
@@ -63,7 +63,7 @@ public void writeHeadersWhenPragmaThenNoCacheControlHeaders() {
6363
String pragma = "1";
6464
this.headers.set(HttpHeaders.PRAGMA, pragma);
6565
this.writer.writeHttpHeaders(this.exchange);
66-
assertThat(this.headers).hasSize(1);
66+
assertThat(this.headers.headerNames()).hasSize(1);
6767
assertThat(this.headers.get(HttpHeaders.PRAGMA)).containsOnly(pragma);
6868
}
6969

@@ -72,7 +72,7 @@ public void writeHeadersWhenExpiresThenNoCacheControlHeaders() {
7272
String expires = "1";
7373
this.headers.set(HttpHeaders.EXPIRES, expires);
7474
this.writer.writeHttpHeaders(this.exchange);
75-
assertThat(this.headers).hasSize(1);
75+
assertThat(this.headers.headerNames()).hasSize(1);
7676
assertThat(this.headers.get(HttpHeaders.EXPIRES)).containsOnly(expires);
7777
}
7878

@@ -81,7 +81,7 @@ public void writeHeadersWhenExpiresThenNoCacheControlHeaders() {
8181
public void writeHeadersWhenNotModifiedThenNoCacheControlHeaders() {
8282
this.exchange.getResponse().setStatusCode(HttpStatus.NOT_MODIFIED);
8383
this.writer.writeHttpHeaders(this.exchange);
84-
assertThat(this.headers).isEmpty();
84+
assertThat(this.headers.headerNames()).isEmpty();
8585
}
8686

8787
}

0 commit comments

Comments
 (0)