Skip to content

Commit dd93a7f

Browse files
committed
Simplify MediaTypeRequestMatcher construction
1 parent 8dd2864 commit dd93a7f

File tree

2 files changed

+189
-8
lines changed

2 files changed

+189
-8
lines changed

web/src/main/java/org/springframework/security/web/util/matcher/MediaTypeRequestMatcher.java

+21-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2019 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.
@@ -30,6 +30,7 @@
3030
import org.springframework.util.Assert;
3131
import org.springframework.web.HttpMediaTypeNotAcceptableException;
3232
import org.springframework.web.accept.ContentNegotiationStrategy;
33+
import org.springframework.web.accept.HeaderContentNegotiationStrategy;
3334
import org.springframework.web.context.request.ServletWebRequest;
3435

3536
/**
@@ -135,6 +136,7 @@
135136
* </pre>
136137
*
137138
* @author Rob Winch
139+
* @author Dan Zheng
138140
* @since 3.2
139141
*/
140142

@@ -145,6 +147,23 @@ public final class MediaTypeRequestMatcher implements RequestMatcher {
145147
private boolean useEquals;
146148
private Set<MediaType> ignoredMediaTypes = Collections.emptySet();
147149

150+
/**
151+
* Creates an instance
152+
* @param matchingMediaTypes the {@link MediaType} that will make the http request.
153+
* @since 5.2
154+
*/
155+
public MediaTypeRequestMatcher(MediaType... matchingMediaTypes) {
156+
this(new HeaderContentNegotiationStrategy(), Arrays.asList(matchingMediaTypes));
157+
}
158+
159+
/**
160+
* Creates an instance
161+
* @param matchingMediaTypes the {@link MediaType} that will make the http request.
162+
* @since 5.2
163+
*/
164+
public MediaTypeRequestMatcher(Collection<MediaType> matchingMediaTypes) {
165+
this(new HeaderContentNegotiationStrategy(), matchingMediaTypes);
166+
}
148167
/**
149168
* Creates an instance
150169
* @param contentNegotiationStrategy the {@link ContentNegotiationStrategy} to use
@@ -164,8 +183,7 @@ public MediaTypeRequestMatcher(ContentNegotiationStrategy contentNegotiationStra
164183
*/
165184
public MediaTypeRequestMatcher(ContentNegotiationStrategy contentNegotiationStrategy,
166185
Collection<MediaType> matchingMediaTypes) {
167-
Assert.notNull(contentNegotiationStrategy,
168-
"ContentNegotiationStrategy cannot be null");
186+
Assert.notNull(contentNegotiationStrategy, "ContentNegotiationStrategy cannot be null");
169187
Assert.notEmpty(matchingMediaTypes, "matchingMediaTypes cannot be null or empty");
170188
this.contentNegotiationStrategy = contentNegotiationStrategy;
171189
this.matchingMediaTypes = matchingMediaTypes;

web/src/test/java/org/springframework/security/web/util/matcher/MediaTypeRequestMatcherTests.java

+168-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2019 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.
@@ -28,16 +28,16 @@
2828
import org.junit.runner.RunWith;
2929
import org.mockito.Mock;
3030
import org.mockito.junit.MockitoJUnitRunner;
31+
3132
import org.springframework.http.MediaType;
3233
import org.springframework.mock.web.MockHttpServletRequest;
33-
import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
3434
import org.springframework.web.HttpMediaTypeNotAcceptableException;
3535
import org.springframework.web.accept.ContentNegotiationStrategy;
3636
import org.springframework.web.context.request.NativeWebRequest;
3737

3838
/**
3939
* @author Rob Winch
40-
*
40+
* @author Dan Zheng
4141
*/
4242
@RunWith(MockitoJUnitRunner.class)
4343
public class MediaTypeRequestMatcherTests {
@@ -53,8 +53,9 @@ public void setup() {
5353
}
5454

5555
@Test(expected = IllegalArgumentException.class)
56-
public void constructorNullCNSVarargs() {
57-
new MediaTypeRequestMatcher(null, MediaType.ALL);
56+
public void constructorWhenNullCNSThenIAE() {
57+
ContentNegotiationStrategy c = null;
58+
new MediaTypeRequestMatcher(c, MediaType.ALL);
5859
}
5960

6061
@Test(expected = IllegalArgumentException.class)
@@ -79,6 +80,16 @@ public void constructorEmtpyMediaTypes() {
7980
Collections.<MediaType> emptyList());
8081
}
8182

83+
@Test(expected = IllegalArgumentException.class)
84+
public void constructorWhenEmptyMediaTypeThenIAE() {
85+
new MediaTypeRequestMatcher();
86+
}
87+
88+
@Test(expected = IllegalArgumentException.class)
89+
public void constructorWhenEmptyMediaTypeCollectionThenIAE() {
90+
new MediaTypeRequestMatcher(Collections.<MediaType> emptyList());
91+
}
92+
8293
@Test
8394
public void negotiationStrategyThrowsHMTNAE()
8495
throws HttpMediaTypeNotAcceptableException {
@@ -91,6 +102,7 @@ public void negotiationStrategyThrowsHMTNAE()
91102

92103
@Test
93104
public void mediaAllMatches() throws Exception {
105+
94106
when(negotiationStrategy.resolveMediaTypes(any(NativeWebRequest.class)))
95107
.thenReturn(Arrays.asList(MediaType.ALL));
96108

@@ -102,6 +114,77 @@ public void mediaAllMatches() throws Exception {
102114
assertThat(matcher.matches(request)).isTrue();
103115
}
104116

117+
@Test
118+
public void matchWhenAcceptHeaderAsteriskThenAll() throws Exception {
119+
request.addHeader("Accept", "*/*");
120+
matcher = new MediaTypeRequestMatcher(MediaType.ALL);
121+
assertThat(matcher.matches(request)).isTrue();
122+
}
123+
124+
@Test
125+
public void matchWhenAcceptHeaderAsteriskThenAnyone() throws Exception {
126+
request.addHeader("Accept", "*/*");
127+
matcher = new MediaTypeRequestMatcher(MediaType.TEXT_HTML);
128+
assertThat(matcher.matches(request)).isTrue();
129+
}
130+
131+
@Test
132+
public void matchWhenAcceptHeaderAsteriskThenAllInCollection() throws Exception {
133+
request.addHeader("Accept", "*/*");
134+
matcher = new MediaTypeRequestMatcher(Collections.singleton(MediaType.ALL));
135+
assertThat(matcher.matches(request)).isTrue();
136+
}
137+
138+
@Test
139+
public void matchWhenAcceptHeaderAsteriskThenAnyoneInCollection() throws Exception {
140+
request.addHeader("Accept", "*/*");
141+
matcher = new MediaTypeRequestMatcher(Collections.singleton(MediaType.TEXT_HTML));
142+
assertThat(matcher.matches(request)).isTrue();
143+
}
144+
145+
@Test
146+
public void matchWhenNoAcceptHeaderThenAll() throws Exception {
147+
request.removeHeader("Accept");
148+
// if not set Accept, it is match all
149+
matcher = new MediaTypeRequestMatcher(MediaType.ALL);
150+
assertThat(matcher.matches(request)).isTrue();
151+
}
152+
153+
@Test
154+
public void matchWhenNoAcceptHeaderThenAnyone() throws Exception {
155+
request.removeHeader("Accept");
156+
matcher = new MediaTypeRequestMatcher(MediaType.TEXT_HTML);
157+
assertThat(matcher.matches(request)).isTrue();
158+
}
159+
160+
@Test
161+
public void matchWhenSingleAcceptHeaderThenOne() throws Exception {
162+
request.addHeader("Accept", "text/html");
163+
matcher = new MediaTypeRequestMatcher(MediaType.TEXT_HTML);
164+
assertThat(matcher.matches(request)).isTrue();
165+
}
166+
167+
@Test
168+
public void matchWhenSingleAcceptHeaderThenOneWithCollection() throws Exception {
169+
request.addHeader("Accept", "text/html");
170+
matcher = new MediaTypeRequestMatcher(Collections.singleton(MediaType.TEXT_HTML));
171+
assertThat(matcher.matches(request)).isTrue();
172+
}
173+
174+
@Test
175+
public void matchWhenMultipleAcceptHeaderThenMatchMultiple() throws Exception {
176+
request.addHeader("Accept", "text/html, application/xhtml+xml, application/xml;q=0.9");
177+
matcher = new MediaTypeRequestMatcher(MediaType.TEXT_HTML, MediaType.APPLICATION_XHTML_XML, MediaType.APPLICATION_XML);
178+
assertThat(matcher.matches(request)).isTrue();
179+
}
180+
181+
@Test
182+
public void matchWhenMultipleAcceptHeaderThenAnyoneInCollection() throws Exception {
183+
request.addHeader("Accept", "text/html, application/xhtml+xml, application/xml;q=0.9");
184+
matcher = new MediaTypeRequestMatcher(Arrays.asList(MediaType.APPLICATION_XHTML_XML));
185+
assertThat(matcher.matches(request)).isTrue();
186+
}
187+
105188
@Test
106189
public void multipleMediaType() throws HttpMediaTypeNotAcceptableException {
107190
when(negotiationStrategy.resolveMediaTypes(any(NativeWebRequest.class)))
@@ -133,6 +216,14 @@ public void resolveTextPlainMatchesTextAll()
133216
assertThat(matcher.matches(request)).isTrue();
134217
}
135218

219+
@Test
220+
public void matchWhenAcceptHeaderIsTextThenMediaTypeAllIsMatched() {
221+
request.addHeader("Accept", MediaType.TEXT_PLAIN_VALUE);
222+
223+
matcher = new MediaTypeRequestMatcher(new MediaType("text", "*"));
224+
assertThat(matcher.matches(request)).isTrue();
225+
}
226+
136227
@Test
137228
public void resolveTextAllMatchesTextPlain()
138229
throws HttpMediaTypeNotAcceptableException {
@@ -143,6 +234,15 @@ public void resolveTextAllMatchesTextPlain()
143234
assertThat(matcher.matches(request)).isTrue();
144235
}
145236

237+
@Test
238+
public void matchWhenAcceptHeaderIsTextWildcardThenMediaTypeTextIsMatched() {
239+
request.addHeader("Accept", "text/*");
240+
241+
matcher = new MediaTypeRequestMatcher(MediaType.TEXT_PLAIN);
242+
assertThat(matcher.matches(request)).isTrue();
243+
}
244+
245+
146246
// useEquals
147247

148248
@Test
@@ -156,6 +256,15 @@ public void useEqualsResolveTextAllMatchesTextPlain()
156256
assertThat(matcher.matches(request)).isFalse();
157257
}
158258

259+
@Test
260+
public void useEqualsWhenTrueThenMediaTypeTextIsNotMatched() {
261+
request.addHeader("Accept", "text/*");
262+
263+
matcher = new MediaTypeRequestMatcher(MediaType.TEXT_PLAIN);
264+
matcher.setUseEquals(true);
265+
assertThat(matcher.matches(request)).isFalse();
266+
}
267+
159268
@Test
160269
public void useEqualsResolveTextPlainMatchesTextAll()
161270
throws HttpMediaTypeNotAcceptableException {
@@ -168,6 +277,15 @@ public void useEqualsResolveTextPlainMatchesTextAll()
168277
assertThat(matcher.matches(request)).isFalse();
169278
}
170279

280+
@Test
281+
public void useEqualsWhenTrueThenMediaTypeTextAllIsNotMatched() {
282+
request.addHeader("Accept", MediaType.TEXT_PLAIN_VALUE);
283+
284+
matcher = new MediaTypeRequestMatcher(new MediaType("text", "*"));
285+
matcher.setUseEquals(true);
286+
assertThat(matcher.matches(request)).isFalse();
287+
}
288+
171289
@Test
172290
public void useEqualsSame() throws HttpMediaTypeNotAcceptableException {
173291
when(negotiationStrategy.resolveMediaTypes(any(NativeWebRequest.class)))
@@ -178,6 +296,15 @@ public void useEqualsSame() throws HttpMediaTypeNotAcceptableException {
178296
assertThat(matcher.matches(request)).isTrue();
179297
}
180298

299+
@Test
300+
public void useEqualsWhenTrueThenMediaTypeIsMatchedWithEqualString() {
301+
request.addHeader("Accept", MediaType.TEXT_PLAIN_VALUE);
302+
303+
matcher = new MediaTypeRequestMatcher(MediaType.TEXT_PLAIN);
304+
matcher.setUseEquals(true);
305+
assertThat(matcher.matches(request)).isTrue();
306+
}
307+
181308
@Test
182309
public void useEqualsWithCustomMediaType() throws HttpMediaTypeNotAcceptableException {
183310
when(negotiationStrategy.resolveMediaTypes(any(NativeWebRequest.class)))
@@ -189,6 +316,15 @@ public void useEqualsWithCustomMediaType() throws HttpMediaTypeNotAcceptableExce
189316
assertThat(matcher.matches(request)).isTrue();
190317
}
191318

319+
@Test
320+
public void useEqualsWhenTrueThenCustomMediaTypeIsMatched() {
321+
request.addHeader("Accept", "text/unique");
322+
323+
matcher = new MediaTypeRequestMatcher(new MediaType("text", "unique"));
324+
matcher.setUseEquals(true);
325+
assertThat(matcher.matches(request)).isTrue();
326+
}
327+
192328
// ignoreMediaTypeAll
193329

194330
@Test
@@ -201,6 +337,15 @@ public void mediaAllIgnoreMediaTypeAll() throws HttpMediaTypeNotAcceptableExcept
201337
assertThat(matcher.matches(request)).isFalse();
202338
}
203339

340+
@Test
341+
public void ignoredMediaTypesWhenAllThenAnyoneIsNotMatched() {
342+
request.addHeader("Accept", MediaType.ALL_VALUE);
343+
matcher = new MediaTypeRequestMatcher(MediaType.TEXT_HTML);
344+
matcher.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL));
345+
346+
assertThat(matcher.matches(request)).isFalse();
347+
}
348+
204349
@Test
205350
public void mediaAllAndTextHtmlIgnoreMediaTypeAll()
206351
throws HttpMediaTypeNotAcceptableException {
@@ -212,6 +357,15 @@ public void mediaAllAndTextHtmlIgnoreMediaTypeAll()
212357
assertThat(matcher.matches(request)).isTrue();
213358
}
214359

360+
@Test
361+
public void ignoredMediaTypesWhenAllAndTextThenTextCanBeMatched() {
362+
request.addHeader("Accept", MediaType.ALL_VALUE + ", " + MediaType.TEXT_HTML_VALUE);
363+
matcher = new MediaTypeRequestMatcher(MediaType.TEXT_HTML);
364+
matcher.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL));
365+
366+
assertThat(matcher.matches(request)).isTrue();
367+
}
368+
215369
@Test
216370
public void mediaAllQ08AndTextPlainIgnoreMediaTypeAll()
217371
throws HttpMediaTypeNotAcceptableException {
@@ -224,4 +378,13 @@ public void mediaAllQ08AndTextPlainIgnoreMediaTypeAll()
224378

225379
assertThat(matcher.matches(request)).isFalse();
226380
}
381+
382+
@Test
383+
public void ignoredMediaTypesWhenAllThenQ08WithTextIsNotMatched() {
384+
request.addHeader("Accept", MediaType.TEXT_PLAIN + ", */*;q=0.8");
385+
matcher = new MediaTypeRequestMatcher(MediaType.TEXT_HTML);
386+
matcher.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL));
387+
388+
assertThat(matcher.matches(request)).isFalse();
389+
}
227390
}

0 commit comments

Comments
 (0)