Refine compareTo for param and header conditions
Issue: SPR-16674
This commit is contained in:
parent
c238fb441b
commit
1aadf2c3a6
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -122,19 +122,27 @@ public final class HeadersRequestCondition extends AbstractRequestCondition<Head
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns:
|
||||
* <ul>
|
||||
* <li>0 if the two conditions have the same number of header expressions
|
||||
* <li>Less than 0 if "this" instance has more header expressions
|
||||
* <li>Greater than 0 if the "other" instance has more header expressions
|
||||
* </ul>
|
||||
* Compare to another condition based on header expressions. A condition
|
||||
* is considered to be a more specific match, if it has:
|
||||
* <ol>
|
||||
* <li>A greater number of expressions.
|
||||
* <li>A greater number of non-negated expressions with a concrete value.
|
||||
* </ol>
|
||||
* <p>It is assumed that both instances have been obtained via
|
||||
* {@link #getMatchingCondition(ServerWebExchange)} and each instance
|
||||
* contains the matching header expression only or is otherwise empty.
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(HeadersRequestCondition other, ServerWebExchange exchange) {
|
||||
return other.expressions.size() - this.expressions.size();
|
||||
int result = other.expressions.size() - this.expressions.size();
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
return (int) (getValueMatchCount(other.expressions) - getValueMatchCount(this.expressions));
|
||||
}
|
||||
|
||||
private long getValueMatchCount(Set<HeaderExpression> expressions) {
|
||||
return expressions.stream().filter(e -> e.getValue() != null && !e.isNegated()).count();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -104,19 +104,27 @@ public final class ParamsRequestCondition extends AbstractRequestCondition<Param
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns:
|
||||
* <ul>
|
||||
* <li>0 if the two conditions have the same number of parameter expressions
|
||||
* <li>Less than 0 if "this" instance has more parameter expressions
|
||||
* <li>Greater than 0 if the "other" instance has more parameter expressions
|
||||
* </ul>
|
||||
* Compare to another condition based on parameter expressions. A condition
|
||||
* is considered to be a more specific match, if it has:
|
||||
* <ol>
|
||||
* <li>A greater number of expressions.
|
||||
* <li>A greater number of non-negated expressions with a concrete value.
|
||||
* </ol>
|
||||
* <p>It is assumed that both instances have been obtained via
|
||||
* {@link #getMatchingCondition(ServerWebExchange)} and each instance
|
||||
* contains the matching parameter expressions only or is otherwise empty.
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(ParamsRequestCondition other, ServerWebExchange exchange) {
|
||||
return (other.expressions.size() - this.expressions.size());
|
||||
int result = other.expressions.size() - this.expressions.size();
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
return (int) (getValueMatchCount(other.expressions) - getValueMatchCount(this.expressions));
|
||||
}
|
||||
|
||||
private long getValueMatchCount(Set<ParamExpression> expressions) {
|
||||
return expressions.stream().filter(e -> e.getValue() != null && !e.isNegated()).count();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -20,14 +20,11 @@ import java.util.Collection;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
|
||||
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.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.mock.http.server.reactive.test.MockServerHttpRequest.*;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link HeadersRequestCondition}.
|
||||
|
@ -46,75 +43,75 @@ public class HeadersRequestConditionTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void headerPresent() throws Exception {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("Accept", ""));
|
||||
public void headerPresent() {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("Accept", ""));
|
||||
HeadersRequestCondition condition = new HeadersRequestCondition("accept");
|
||||
|
||||
assertNotNull(condition.getMatchingCondition(exchange));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerPresentNoMatch() throws Exception {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("bar", ""));
|
||||
public void headerPresentNoMatch() {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("bar", ""));
|
||||
HeadersRequestCondition condition = new HeadersRequestCondition("foo");
|
||||
|
||||
assertNull(condition.getMatchingCondition(exchange));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerNotPresent() throws Exception {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/"));
|
||||
public void headerNotPresent() {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(get("/"));
|
||||
HeadersRequestCondition condition = new HeadersRequestCondition("!accept");
|
||||
|
||||
assertNotNull(condition.getMatchingCondition(exchange));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerValueMatch() throws Exception {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("foo", "bar"));
|
||||
public void headerValueMatch() {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("foo", "bar"));
|
||||
HeadersRequestCondition condition = new HeadersRequestCondition("foo=bar");
|
||||
|
||||
assertNotNull(condition.getMatchingCondition(exchange));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerValueNoMatch() throws Exception {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("foo", "bazz"));
|
||||
public void headerValueNoMatch() {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("foo", "bazz"));
|
||||
HeadersRequestCondition condition = new HeadersRequestCondition("foo=bar");
|
||||
|
||||
assertNull(condition.getMatchingCondition(exchange));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerCaseSensitiveValueMatch() throws Exception {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("foo", "bar"));
|
||||
public void headerCaseSensitiveValueMatch() {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("foo", "bar"));
|
||||
HeadersRequestCondition condition = new HeadersRequestCondition("foo=Bar");
|
||||
|
||||
assertNull(condition.getMatchingCondition(exchange));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerValueMatchNegated() throws Exception {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("foo", "baz"));
|
||||
public void headerValueMatchNegated() {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("foo", "baz"));
|
||||
HeadersRequestCondition condition = new HeadersRequestCondition("foo!=bar");
|
||||
|
||||
assertNotNull(condition.getMatchingCondition(exchange));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerValueNoMatchNegated() throws Exception {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("foo", "bar"));
|
||||
public void headerValueNoMatchNegated() {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("foo", "bar"));
|
||||
HeadersRequestCondition condition = new HeadersRequestCondition("foo!=bar");
|
||||
|
||||
assertNull(condition.getMatchingCondition(exchange));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compareTo() throws Exception {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/"));
|
||||
public void compareTo() {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(get("/"));
|
||||
|
||||
HeadersRequestCondition condition1 = new HeadersRequestCondition("foo", "bar", "baz");
|
||||
HeadersRequestCondition condition2 = new HeadersRequestCondition("foo", "bar");
|
||||
HeadersRequestCondition condition2 = new HeadersRequestCondition("foo=a", "bar");
|
||||
|
||||
int result = condition1.compareTo(condition2, exchange);
|
||||
assertTrue("Invalid comparison result: " + result, result < 0);
|
||||
|
@ -123,6 +120,27 @@ public class HeadersRequestConditionTests {
|
|||
assertTrue("Invalid comparison result: " + result, result > 0);
|
||||
}
|
||||
|
||||
@Test // SPR-16674
|
||||
public void compareToWithMoreSpecificMatchByValue() {
|
||||
ServerWebExchange exchange = MockServerWebExchange.from(get("/"));
|
||||
|
||||
HeadersRequestCondition condition1 = new HeadersRequestCondition("foo=a");
|
||||
HeadersRequestCondition condition2 = new HeadersRequestCondition("foo");
|
||||
|
||||
int result = condition1.compareTo(condition2, exchange);
|
||||
assertTrue("Invalid comparison result: " + result, result < 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compareToWithNegatedMatch() {
|
||||
ServerWebExchange exchange = MockServerWebExchange.from(get("/"));
|
||||
|
||||
HeadersRequestCondition condition1 = new HeadersRequestCondition("foo!=a");
|
||||
HeadersRequestCondition condition2 = new HeadersRequestCondition("foo");
|
||||
|
||||
assertEquals("Negated match should not count as more specific",
|
||||
0, condition1.compareTo(condition2, exchange));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void combine() {
|
||||
|
@ -135,8 +153,8 @@ public class HeadersRequestConditionTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void getMatchingCondition() throws Exception {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("foo", "bar"));
|
||||
public void getMatchingCondition() {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("foo", "bar"));
|
||||
HeadersRequestCondition condition = new HeadersRequestCondition("foo");
|
||||
|
||||
HeadersRequestCondition result = condition.getMatchingCondition(exchange);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -23,12 +23,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.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
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 ParamsRequestCondition}.
|
||||
|
@ -95,6 +91,28 @@ public class ParamsRequestConditionTests {
|
|||
assertTrue("Invalid comparison result: " + result, result > 0);
|
||||
}
|
||||
|
||||
@Test // SPR-16674
|
||||
public void compareToWithMoreSpecificMatchByValue() {
|
||||
ServerWebExchange exchange = MockServerWebExchange.from(get("/"));
|
||||
|
||||
ParamsRequestCondition condition1 = new ParamsRequestCondition("response_type=code");
|
||||
ParamsRequestCondition condition2 = new ParamsRequestCondition("response_type");
|
||||
|
||||
int result = condition1.compareTo(condition2, exchange);
|
||||
assertTrue("Invalid comparison result: " + result, result < 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compareToWithNegatedMatch() {
|
||||
ServerWebExchange exchange = MockServerWebExchange.from(get("/"));
|
||||
|
||||
ParamsRequestCondition condition1 = new ParamsRequestCondition("response_type!=code");
|
||||
ParamsRequestCondition condition2 = new ParamsRequestCondition("response_type");
|
||||
|
||||
assertEquals("Negated match should not count as more specific",
|
||||
0, condition1.compareTo(condition2, exchange));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void combine() {
|
||||
ParamsRequestCondition condition1 = new ParamsRequestCondition("foo=bar");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -122,19 +122,27 @@ public final class HeadersRequestCondition extends AbstractRequestCondition<Head
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns:
|
||||
* <ul>
|
||||
* <li>0 if the two conditions have the same number of header expressions
|
||||
* <li>Less than 0 if "this" instance has more header expressions
|
||||
* <li>Greater than 0 if the "other" instance has more header expressions
|
||||
* </ul>
|
||||
* Compare to another condition based on header expressions. A condition
|
||||
* is considered to be a more specific match, if it has:
|
||||
* <ol>
|
||||
* <li>A greater number of expressions.
|
||||
* <li>A greater number of non-negated expressions with a concrete value.
|
||||
* </ol>
|
||||
* <p>It is assumed that both instances have been obtained via
|
||||
* {@link #getMatchingCondition(HttpServletRequest)} and each instance
|
||||
* contains the matching header expression only or is otherwise empty.
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(HeadersRequestCondition other, HttpServletRequest request) {
|
||||
return other.expressions.size() - this.expressions.size();
|
||||
int result = other.expressions.size() - this.expressions.size();
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
return (int) (getValueMatchCount(other.expressions) - getValueMatchCount(this.expressions));
|
||||
}
|
||||
|
||||
private long getValueMatchCount(Set<HeaderExpression> expressions) {
|
||||
return expressions.stream().filter(e -> e.getValue() != null && !e.isNegated()).count();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -107,19 +107,27 @@ public final class ParamsRequestCondition extends AbstractRequestCondition<Param
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns:
|
||||
* <ul>
|
||||
* <li>0 if the two conditions have the same number of parameter expressions
|
||||
* <li>Less than 0 if "this" instance has more parameter expressions
|
||||
* <li>Greater than 0 if the "other" instance has more parameter expressions
|
||||
* </ul>
|
||||
* Compare to another condition based on parameter expressions. A condition
|
||||
* is considered to be a more specific match, if it has:
|
||||
* <ol>
|
||||
* <li>A greater number of expressions.
|
||||
* <li>A greater number of non-negated expressions with a concrete value.
|
||||
* </ol>
|
||||
* <p>It is assumed that both instances have been obtained via
|
||||
* {@link #getMatchingCondition(HttpServletRequest)} and each instance
|
||||
* contains the matching parameter expressions only or is otherwise empty.
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(ParamsRequestCondition other, HttpServletRequest request) {
|
||||
return (other.expressions.size() - this.expressions.size());
|
||||
int result = other.expressions.size() - this.expressions.size();
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
return (int) (getValueMatchCount(other.expressions) - getValueMatchCount(this.expressions));
|
||||
}
|
||||
|
||||
private long getValueMatchCount(Set<ParamExpression> expressions) {
|
||||
return expressions.stream().filter(e -> e.getValue() != null && !e.isNegated()).count();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -121,7 +121,7 @@ public class HeadersRequestConditionTests {
|
|||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
|
||||
HeadersRequestCondition condition1 = new HeadersRequestCondition("foo", "bar", "baz");
|
||||
HeadersRequestCondition condition2 = new HeadersRequestCondition("foo", "bar");
|
||||
HeadersRequestCondition condition2 = new HeadersRequestCondition("foo=a", "bar");
|
||||
|
||||
int result = condition1.compareTo(condition2, request);
|
||||
assertTrue("Invalid comparison result: " + result, result < 0);
|
||||
|
@ -130,6 +130,30 @@ public class HeadersRequestConditionTests {
|
|||
assertTrue("Invalid comparison result: " + result, result > 0);
|
||||
}
|
||||
|
||||
@Test // SPR-16674
|
||||
public void compareToWithMoreSpecificMatchByValue() {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
|
||||
HeadersRequestCondition condition1 = new HeadersRequestCondition("foo=a");
|
||||
HeadersRequestCondition condition2 = new HeadersRequestCondition("foo");
|
||||
|
||||
int result = condition1.compareTo(condition2, request);
|
||||
assertTrue("Invalid comparison result: " + result, result < 0);
|
||||
|
||||
result = condition2.compareTo(condition1, request);
|
||||
assertTrue("Invalid comparison result: " + result, result > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compareToWithNegatedMatch() {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
|
||||
HeadersRequestCondition condition1 = new HeadersRequestCondition("foo!=a");
|
||||
HeadersRequestCondition condition2 = new HeadersRequestCondition("foo");
|
||||
|
||||
assertEquals("Negated match should not count as more specific",
|
||||
0, condition1.compareTo(condition2, request));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void combine() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -97,7 +97,7 @@ public class ParamsRequestConditionTests {
|
|||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
|
||||
ParamsRequestCondition condition1 = new ParamsRequestCondition("foo", "bar", "baz");
|
||||
ParamsRequestCondition condition2 = new ParamsRequestCondition("foo", "bar");
|
||||
ParamsRequestCondition condition2 = new ParamsRequestCondition("foo=a", "bar");
|
||||
|
||||
int result = condition1.compareTo(condition2, request);
|
||||
assertTrue("Invalid comparison result: " + result, result < 0);
|
||||
|
@ -106,6 +106,28 @@ public class ParamsRequestConditionTests {
|
|||
assertTrue("Invalid comparison result: " + result, result > 0);
|
||||
}
|
||||
|
||||
@Test // SPR-16674
|
||||
public void compareToWithMoreSpecificMatchByValue() {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
|
||||
ParamsRequestCondition condition1 = new ParamsRequestCondition("response_type=code");
|
||||
ParamsRequestCondition condition2 = new ParamsRequestCondition("response_type");
|
||||
|
||||
int result = condition1.compareTo(condition2, request);
|
||||
assertTrue("Invalid comparison result: " + result, result < 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compareToWithNegatedMatch() {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
|
||||
ParamsRequestCondition condition1 = new ParamsRequestCondition("response_type!=code");
|
||||
ParamsRequestCondition condition2 = new ParamsRequestCondition("response_type");
|
||||
|
||||
assertEquals("Negated match should not count as more specific",
|
||||
0, condition1.compareTo(condition2, request));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void combine() {
|
||||
ParamsRequestCondition condition1 = new ParamsRequestCondition("foo=bar");
|
||||
|
|
Loading…
Reference in New Issue