提交 1aadf2c3 编写于 作者: R Rossen Stoyanchev

Refine compareTo for param and header conditions

Issue: SPR-16674
上级 c238fb44
/*
* 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();
}
......
/*
* 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();
}
......
/*
* 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);
......
/*
* 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");
......
/*
* 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();
}
......
/*
* 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();
}
......
/*
* 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() {
......
/*
* 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");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册