Skip to content

Commit 2a5eab4

Browse files
committed
Ignore quality factor when filtering out "*/*"
Prior to this commit, the `RequestedContentTypeResolverBuilder` would create a `RequestedContentTypeResolver` that internally delegates to a list of resolvers. Each resolver would either return the list of requested media types, or a singleton list with the "*/*" media type; in this case this signals that the resolver cannot find a specific media type requested and that we should continue with the next resolver in the list. Media Types returned by resolvers can contain parameters, such as the quality factor. If the HTTP client requests "*/*;q=0.8", the `HeaderContentTypeResolver` will return this as a singleton list. While this has been resolved from the request, such a media type should not be selected over other media types that could be returned by other resolvers. This commit changes the `RequestedContentTypeResolverBuilder` so that it does not select "*/*;q=0.8" as the requested media type, but instead continues delegating to other resolvers in the list. This means we need to remove the quality factor before comparing it to the "*/*" for equality check. Fixes gh-29915
1 parent 1de36ab commit 2a5eab4

File tree

2 files changed

+25
-12
lines changed

2 files changed

+25
-12
lines changed

spring-webflux/src/main/java/org/springframework/web/reactive/accept/RequestedContentTypeResolverBuilder.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public RequestedContentTypeResolver build() {
9393
return exchange -> {
9494
for (RequestedContentTypeResolver resolver : resolvers) {
9595
List<MediaType> mediaTypes = resolver.resolveMediaTypes(exchange);
96-
if (mediaTypes.equals(RequestedContentTypeResolver.MEDIA_TYPE_ALL_LIST)) {
96+
if (isMediaTypeAll(mediaTypes)) {
9797
continue;
9898
}
9999
return mediaTypes;
@@ -102,6 +102,11 @@ public RequestedContentTypeResolver build() {
102102
};
103103
}
104104

105+
private boolean isMediaTypeAll(List<MediaType> mediaTypes) {
106+
return mediaTypes.size() == 1
107+
&& mediaTypes.get(0).removeQualityValue().equals(MediaType.ALL);
108+
}
109+
105110

106111
/**
107112
* Helper to create and configure {@link ParameterContentTypeResolver}.

spring-webflux/src/test/java/org/springframework/web/reactive/accept/RequestedContentTypeResolverBuilderTests.java

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -34,8 +34,7 @@
3434
public class RequestedContentTypeResolverBuilderTests {
3535

3636
@Test
37-
public void defaultSettings() throws Exception {
38-
37+
void defaultSettings() {
3938
RequestedContentTypeResolver resolver = new RequestedContentTypeResolverBuilder().build();
4039
MockServerWebExchange exchange = MockServerWebExchange.from(
4140
MockServerHttpRequest.get("/flower").accept(MediaType.IMAGE_GIF));
@@ -45,8 +44,7 @@ public void defaultSettings() throws Exception {
4544
}
4645

4746
@Test
48-
public void parameterResolver() throws Exception {
49-
47+
void parameterResolver() {
5048
RequestedContentTypeResolverBuilder builder = new RequestedContentTypeResolverBuilder();
5149
builder.parameterResolver().mediaType("json", MediaType.APPLICATION_JSON);
5250
RequestedContentTypeResolver resolver = builder.build();
@@ -58,8 +56,7 @@ public void parameterResolver() throws Exception {
5856
}
5957

6058
@Test
61-
public void parameterResolverWithCustomParamName() throws Exception {
62-
59+
void parameterResolverWithCustomParamName() {
6360
RequestedContentTypeResolverBuilder builder = new RequestedContentTypeResolverBuilder();
6461
builder.parameterResolver().mediaType("json", MediaType.APPLICATION_JSON).parameterName("s");
6562
RequestedContentTypeResolver resolver = builder.build();
@@ -71,8 +68,7 @@ public void parameterResolverWithCustomParamName() throws Exception {
7168
}
7269

7370
@Test // SPR-10513
74-
public void fixedResolver() throws Exception {
75-
71+
void fixedResolver() {
7672
RequestedContentTypeResolverBuilder builder = new RequestedContentTypeResolverBuilder();
7773
builder.fixedResolver(MediaType.APPLICATION_JSON);
7874
RequestedContentTypeResolver resolver = builder.build();
@@ -84,8 +80,7 @@ public void fixedResolver() throws Exception {
8480
}
8581

8682
@Test // SPR-12286
87-
public void resolver() throws Exception {
88-
83+
void resolver() {
8984
RequestedContentTypeResolverBuilder builder = new RequestedContentTypeResolverBuilder();
9085
builder.resolver(new FixedContentTypeResolver(MediaType.APPLICATION_JSON));
9186
RequestedContentTypeResolver resolver = builder.build();
@@ -99,4 +94,17 @@ public void resolver() throws Exception {
9994
assertThat(mediaTypes).isEqualTo(Collections.singletonList(MediaType.APPLICATION_JSON));
10095
}
10196

97+
@Test
98+
void removeQualityFactorForMediaTypeAllChecks() {
99+
RequestedContentTypeResolverBuilder builder = new RequestedContentTypeResolverBuilder();
100+
builder.resolver(new HeaderContentTypeResolver());
101+
builder.resolver(new FixedContentTypeResolver(MediaType.APPLICATION_JSON));
102+
RequestedContentTypeResolver resolver = builder.build();
103+
104+
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/")
105+
.accept(MediaType.valueOf("*/*;q=0.8")));
106+
List<MediaType> mediaTypes = resolver.resolveMediaTypes(exchange);
107+
assertThat(mediaTypes).isEqualTo(Collections.singletonList(MediaType.APPLICATION_JSON));
108+
}
109+
102110
}

0 commit comments

Comments
 (0)