Skip to content

Commit 58b17bf

Browse files
committed
Remove framgent in ResourceUrlEncodingFilter
Closes gh-22552
1 parent 86bf699 commit 58b17bf

File tree

2 files changed

+73
-74
lines changed

2 files changed

+73
-74
lines changed

spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 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.
@@ -111,7 +111,7 @@ public String resolveUrlPath(String url) {
111111
return null;
112112
}
113113
if (this.indexLookupPath != null && url.startsWith(this.prefixLookupPath)) {
114-
int suffixIndex = getQueryParamsIndex(url);
114+
int suffixIndex = getEndPathIndex(url);
115115
String suffix = url.substring(suffixIndex);
116116
String lookupPath = url.substring(this.indexLookupPath, suffixIndex);
117117
lookupPath = this.resourceUrlProvider.getForLookupPath(lookupPath);
@@ -122,9 +122,16 @@ public String resolveUrlPath(String url) {
122122
return null;
123123
}
124124

125-
private int getQueryParamsIndex(String url) {
126-
int index = url.indexOf('?');
127-
return (index > 0 ? index : url.length());
125+
private int getEndPathIndex(String path) {
126+
int end = path.indexOf('?');
127+
int fragmentIndex = path.indexOf('#');
128+
if (fragmentIndex != -1 && (end == -1 || fragmentIndex < end)) {
129+
end = fragmentIndex;
130+
}
131+
if (end == -1) {
132+
end = path.length();
133+
}
134+
return end;
128135
}
129136
}
130137

Lines changed: 61 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 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.
@@ -15,9 +15,11 @@
1515
*/
1616
package org.springframework.web.servlet.resource;
1717

18-
import java.util.Arrays;
18+
import java.io.IOException;
19+
import java.util.ArrayList;
1920
import java.util.Collections;
2021
import java.util.List;
22+
import javax.servlet.ServletException;
2123
import javax.servlet.http.HttpServletResponse;
2224

2325
import org.junit.Before;
@@ -27,7 +29,7 @@
2729
import org.springframework.mock.web.test.MockHttpServletRequest;
2830
import org.springframework.mock.web.test.MockHttpServletResponse;
2931

30-
import static org.junit.Assert.assertEquals;
32+
import static org.junit.Assert.*;
3133

3234
/**
3335
* Unit tests for {@code ResourceUrlEncodingFilter}.
@@ -40,51 +42,54 @@ public class ResourceUrlEncodingFilterTests {
4042

4143
private ResourceUrlProvider urlProvider;
4244

45+
4346
@Before
44-
public void createFilter() throws Exception {
47+
public void createFilter() {
4548
VersionResourceResolver versionResolver = new VersionResourceResolver();
4649
versionResolver.setStrategyMap(Collections.singletonMap("/**", new ContentVersionStrategy()));
4750
PathResourceResolver pathResolver = new PathResourceResolver();
4851
pathResolver.setAllowedLocations(new ClassPathResource("test/", getClass()));
49-
List<ResourceResolver> resolvers = Arrays.asList(versionResolver, pathResolver);
52+
List<ResourceResolver> resolvers = new ArrayList<>();
53+
resolvers.add(versionResolver);
54+
resolvers.add(pathResolver);
5055

5156
this.filter = new ResourceUrlEncodingFilter();
5257
this.urlProvider = createResourceUrlProvider(resolvers);
5358
}
5459

60+
private ResourceUrlProvider createResourceUrlProvider(List<ResourceResolver> resolvers) {
61+
ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler();
62+
handler.setLocations(Collections.singletonList(new ClassPathResource("test/", getClass())));
63+
handler.setResourceResolvers(resolvers);
64+
65+
ResourceUrlProvider urlProvider = new ResourceUrlProvider();
66+
urlProvider.setHandlerMap(Collections.singletonMap("/resources/**", handler));
67+
return urlProvider;
68+
}
69+
70+
5571
@Test
5672
public void encodeURL() throws Exception {
57-
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/");
58-
MockHttpServletResponse response = new MockHttpServletResponse();
59-
60-
this.filter.doFilter(request, response, (req, res) -> {
61-
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
62-
String result = ((HttpServletResponse) res).encodeURL("/resources/bar.css");
63-
assertEquals("/resources/bar-11e16cf79faee7ac698c805cf28248d2.css", result);
64-
});
73+
testEncodeUrl(new MockHttpServletRequest("GET", "/"),
74+
"/resources/bar.css", "/resources/bar-11e16cf79faee7ac698c805cf28248d2.css");
6575
}
6676

6777
@Test
68-
public void encodeURLWithContext() throws Exception {
78+
public void encodeUrlWithContext() throws Exception {
6979
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/context/foo");
7080
request.setContextPath("/context");
71-
MockHttpServletResponse response = new MockHttpServletResponse();
7281

73-
this.filter.doFilter(request, response, (req, res) -> {
74-
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
75-
String result = ((HttpServletResponse) res).encodeURL("/context/resources/bar.css");
76-
assertEquals("/context/resources/bar-11e16cf79faee7ac698c805cf28248d2.css", result);
77-
});
82+
testEncodeUrl(request, "/context/resources/bar.css",
83+
"/context/resources/bar-11e16cf79faee7ac698c805cf28248d2.css");
7884
}
7985

8086

8187
@Test
8288
public void encodeUrlWithContextAndForwardedRequest() throws Exception {
8389
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/context/foo");
8490
request.setContextPath("/context");
85-
MockHttpServletResponse response = new MockHttpServletResponse();
8691

87-
this.filter.doFilter(request, response, (req, res) -> {
92+
this.filter.doFilter(request, new MockHttpServletResponse(), (req, res) -> {
8893
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
8994
request.setRequestURI("/forwarded");
9095
request.setContextPath("/");
@@ -93,84 +98,71 @@ public void encodeUrlWithContextAndForwardedRequest() throws Exception {
9398
});
9499
}
95100

96-
// SPR-13757
97-
@Test
101+
@Test // SPR-13757
98102
public void encodeContextPathUrlWithoutSuffix() throws Exception {
99103
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/context");
100104
request.setContextPath("/context");
101-
MockHttpServletResponse response = new MockHttpServletResponse();
102105

103-
this.filter.doFilter(request, response, (req, res) -> {
104-
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
105-
String result = ((HttpServletResponse) res).encodeURL("/context/resources/bar.css");
106-
assertEquals("/context/resources/bar-11e16cf79faee7ac698c805cf28248d2.css", result);
107-
});
106+
testEncodeUrl(request, "/context/resources/bar.css",
107+
"/context/resources/bar-11e16cf79faee7ac698c805cf28248d2.css");
108108
}
109109

110110
@Test
111111
public void encodeContextPathUrlWithSuffix() throws Exception {
112112
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/context/");
113113
request.setContextPath("/context");
114-
MockHttpServletResponse response = new MockHttpServletResponse();
115114

116-
this.filter.doFilter(request, response, (req, res) -> {
117-
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
118-
String result = ((HttpServletResponse) res).encodeURL("/context/resources/bar.css");
119-
assertEquals("/context/resources/bar-11e16cf79faee7ac698c805cf28248d2.css", result);
120-
});
115+
testEncodeUrl(request, "/context/resources/bar.css",
116+
"/context/resources/bar-11e16cf79faee7ac698c805cf28248d2.css");
121117
}
122118

123-
// SPR-13018
124-
@Test
125-
public void encodeEmptyURLWithContext() throws Exception {
119+
@Test // SPR-13018
120+
public void encodeEmptyUrlWithContext() throws Exception {
126121
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/context/foo");
127122
request.setContextPath("/context");
128-
MockHttpServletResponse response = new MockHttpServletResponse();
129123

130-
this.filter.doFilter(request, response, (req, res) -> {
131-
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
132-
String result = ((HttpServletResponse) res).encodeURL("?foo=1");
133-
assertEquals("?foo=1", result);
134-
});
124+
testEncodeUrl(request, "?foo=1", "?foo=1");
135125
}
136126

137-
// SPR-13374
138-
@Test
139-
public void encodeURLWithRequestParams() throws Exception {
127+
@Test // SPR-13374
128+
public void encodeUrlWithRequestParams() throws Exception {
140129
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
141130
request.setContextPath("/");
142-
MockHttpServletResponse response = new MockHttpServletResponse();
143131

144-
this.filter.doFilter(request, response, (req, res) -> {
145-
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
146-
String result = ((HttpServletResponse) res).encodeURL("/resources/bar.css?foo=bar&url=http://example.org");
147-
assertEquals("/resources/bar-11e16cf79faee7ac698c805cf28248d2.css?foo=bar&url=http://example.org", result);
148-
});
132+
testEncodeUrl(request, "/resources/bar.css?foo=bar&url=http://example.org",
133+
"/resources/bar-11e16cf79faee7ac698c805cf28248d2.css?foo=bar&url=http://example.org");
149134
}
150135

151-
// SPR-13847
152-
@Test
136+
@Test // SPR-13847
153137
public void encodeUrlPreventStringOutOfBounds() throws Exception {
154138
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/context-path/index");
155139
request.setContextPath("/context-path");
156140
request.setServletPath("");
157-
MockHttpServletResponse response = new MockHttpServletResponse();
158141

159-
this.filter.doFilter(request, response, (req, res) -> {
160-
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
161-
String result = ((HttpServletResponse) res).encodeURL("index?key=value");
162-
assertEquals("index?key=value", result);
163-
});
142+
testEncodeUrl(request, "index?key=value", "index?key=value");
143+
}
144+
145+
@Test // gh-22552
146+
public void encodeUrlWithFragment() throws Exception {
147+
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
148+
request.setContextPath("/");
149+
150+
testEncodeUrl(request, "/resources/bar.css#something",
151+
"/resources/bar-11e16cf79faee7ac698c805cf28248d2.css#something");
152+
153+
testEncodeUrl(request,
154+
"/resources/bar.css?foo=bar&url=http://example.org#something",
155+
"/resources/bar-11e16cf79faee7ac698c805cf28248d2.css?foo=bar&url=http://example.org#something");
164156
}
165157

158+
private void testEncodeUrl(MockHttpServletRequest request, String url, String expected)
159+
throws ServletException, IOException {
166160

167-
protected ResourceUrlProvider createResourceUrlProvider(List<ResourceResolver> resolvers) {
168-
ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler();
169-
handler.setLocations(Arrays.asList(new ClassPathResource("test/", getClass())));
170-
handler.setResourceResolvers(resolvers);
171-
ResourceUrlProvider urlProvider = new ResourceUrlProvider();
172-
urlProvider.setHandlerMap(Collections.singletonMap("/resources/**", handler));
173-
return urlProvider;
161+
this.filter.doFilter(request, new MockHttpServletResponse(), (req, res) -> {
162+
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
163+
String result = ((HttpServletResponse) res).encodeURL(url);
164+
assertEquals(expected, result);
165+
});
174166
}
175167

176168
}

0 commit comments

Comments
 (0)