Match declared parameters on produces condition

Closes gh-21670
This commit is contained in:
Rossen Stoyanchev
2019-03-29 17:03:25 -04:00
parent c0be1c5100
commit 8dc535c15c
5 changed files with 102 additions and 28 deletions

View File

@@ -25,6 +25,7 @@ import java.util.Set;
import org.springframework.http.MediaType;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.cors.reactive.CorsUtils;
@@ -315,12 +316,23 @@ public final class ProducesRequestCondition extends AbstractRequestCondition<Pro
protected boolean matchMediaType(ServerWebExchange exchange) throws NotAcceptableStatusException {
List<MediaType> acceptedMediaTypes = getAcceptedMediaTypes(exchange);
for (MediaType acceptedMediaType : acceptedMediaTypes) {
if (getMediaType().isCompatibleWith(acceptedMediaType)) {
if (getMediaType().isCompatibleWith(acceptedMediaType) && matchParameters(acceptedMediaType)) {
return true;
}
}
return false;
}
private boolean matchParameters(MediaType acceptedMediaType) {
for (String name : getMediaType().getParameters().keySet()) {
String s1 = getMediaType().getParameter(name);
String s2 = acceptedMediaType.getParameter(name);
if (StringUtils.hasText(s1) && StringUtils.hasText(s2) && !s1.equalsIgnoreCase(s2)) {
return false;
}
}
return true;
}
}
}

View File

@@ -24,12 +24,8 @@ import org.junit.Test;
import org.springframework.mock.web.test.server.MockServerWebExchange;
import org.springframework.web.server.ServerWebExchange;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.springframework.mock.http.server.reactive.test.MockServerHttpRequest.get;
import static org.junit.Assert.*;
import static org.springframework.mock.http.server.reactive.test.MockServerHttpRequest.*;
/**
* Unit tests for {@link ProducesRequestCondition}.
@@ -84,6 +80,29 @@ public class ProducesRequestConditionTests {
assertNull(condition.getMatchingCondition(exchange));
}
@Test // gh-21670
public void matchWithParameters() {
String base = "application/atom+xml";
ProducesRequestCondition condition = new ProducesRequestCondition(base + ";type=feed");
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("Accept", base + ";type=feed"));
assertNotNull("Declared parameter value must match if present in request",
condition.getMatchingCondition(exchange));
condition = new ProducesRequestCondition(base + ";type=feed");
exchange = MockServerWebExchange.from(get("/").header("Accept", base + ";type=entry"));
assertNull("Declared parameter value must match if present in request",
condition.getMatchingCondition(exchange));
condition = new ProducesRequestCondition(base + ";type=feed");
exchange = MockServerWebExchange.from(get("/").header("Accept", base));
assertNotNull("Declared parameter has no impact if not present in request",
condition.getMatchingCondition(exchange));
condition = new ProducesRequestCondition(base);
exchange = MockServerWebExchange.from(get("/").header("Accept", base + ";type=feed"));
assertNotNull("No impact from other parameters in request", condition.getMatchingCondition(exchange));
}
@Test
public void matchParseError() {
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("Accept", "bogus"));