Skip to content

Commit adc595b

Browse files
committed
Avoid dependency on WebUtils for extracting file extension
Issue: SPR-14479
1 parent 86c659f commit adc595b

File tree

7 files changed

+53
-119
lines changed

7 files changed

+53
-119
lines changed

spring-web-reactive/src/main/java/org/springframework/web/reactive/accept/PathExtensionContentTypeResolver.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import org.springframework.util.StringUtils;
2727
import org.springframework.web.server.NotAcceptableStatusException;
2828
import org.springframework.web.server.ServerWebExchange;
29-
import org.springframework.web.util.WebUtils;
29+
import org.springframework.web.util.UriUtils;
3030

3131
/**
3232
* A {@link RequestedContentTypeResolver} that extracts the file extension from
@@ -84,8 +84,7 @@ public void setIgnoreUnknownExtensions(boolean ignoreUnknownExtensions) {
8484
@Override
8585
protected String extractKey(ServerWebExchange exchange) {
8686
String path = exchange.getRequest().getURI().getRawPath();
87-
String filename = WebUtils.extractFullFilenameFromUrlPath(path);
88-
String extension = StringUtils.getFilenameExtension(filename);
87+
String extension = UriUtils.extractFileExtension(path);
8988
return (StringUtils.hasText(extension)) ? extension.toLowerCase(Locale.ENGLISH) : null;
9089
}
9190

spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
import org.springframework.util.StringUtils;
3232
import org.springframework.web.HttpMediaTypeNotAcceptableException;
3333
import org.springframework.web.context.request.NativeWebRequest;
34+
import org.springframework.web.util.UriUtils;
3435
import org.springframework.web.util.UrlPathHelper;
35-
import org.springframework.web.util.WebUtils;
3636

3737
/**
3838
* A {@code ContentNegotiationStrategy} that resolves the file extension in the
@@ -114,9 +114,8 @@ protected String getMediaTypeKey(NativeWebRequest webRequest) {
114114
return null;
115115
}
116116
String path = this.urlPathHelper.getLookupPathForRequest(request);
117-
String filename = WebUtils.extractFullFilenameFromUrlPath(path);
118-
String extension = StringUtils.getFilenameExtension(filename);
119-
return (StringUtils.hasText(extension)) ? extension.toLowerCase(Locale.ENGLISH) : null;
117+
String extension = UriUtils.extractFileExtension(path);
118+
return (StringUtils.hasText(extension) ? extension.toLowerCase(Locale.ENGLISH) : null);
120119
}
121120

122121
@Override

spring-web/src/main/java/org/springframework/web/util/UriUtils.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2016 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.
@@ -34,6 +34,7 @@
3434
* </ul>
3535
*
3636
* @author Arjen Poutsma
37+
* @author Juergen Hoeller
3738
* @since 3.0
3839
* @see <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>
3940
*/
@@ -213,4 +214,28 @@ public static String decode(String source, String encoding) throws UnsupportedEn
213214
return (changed ? new String(bos.toByteArray(), encoding) : source);
214215
}
215216

217+
/**
218+
* Extract the file extension from the given URI path.
219+
* @param path the URI path (e.g. "/products/index.html")
220+
* @return the extracted file extension (e.g. "html")
221+
* @since 4.3.2
222+
*/
223+
public static String extractFileExtension(String path) {
224+
int end = path.indexOf('?');
225+
if (end == -1) {
226+
end = path.indexOf('#');
227+
if (end == -1) {
228+
end = path.length();
229+
}
230+
}
231+
int begin = path.lastIndexOf('/', end) + 1;
232+
int paramIndex = path.indexOf(';', begin);
233+
end = (paramIndex != -1 && paramIndex < end ? paramIndex : end);
234+
int extIndex = path.lastIndexOf('.', end);
235+
if (extIndex != -1 && extIndex > begin) {
236+
return path.substring(extIndex + 1, end);
237+
}
238+
return null;
239+
}
240+
216241
}

spring-web/src/main/java/org/springframework/web/util/WebUtils.java

Lines changed: 0 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,6 @@ public static String getRealPath(ServletContext servletContext, String path) thr
260260
return realPath;
261261
}
262262

263-
264263
/**
265264
* Determine the session id of the given request, if any.
266265
* @param request current HTTP request
@@ -470,20 +469,6 @@ public static void clearErrorRequestAttributes(HttpServletRequest request) {
470469
request.removeAttribute(ERROR_SERVLET_NAME_ATTRIBUTE);
471470
}
472471

473-
/**
474-
* Expose the given Map as request attributes, using the keys as attribute names
475-
* and the values as corresponding attribute values. Keys need to be Strings.
476-
* @param request current HTTP request
477-
* @param attributes the attributes Map
478-
*/
479-
public static void exposeRequestAttributes(ServletRequest request, Map<String, ?> attributes) {
480-
Assert.notNull(request, "Request must not be null");
481-
Assert.notNull(attributes, "Attributes Map must not be null");
482-
for (Map.Entry<String, ?> entry : attributes.entrySet()) {
483-
request.setAttribute(entry.getKey(), entry.getValue());
484-
}
485-
}
486-
487472
/**
488473
* Retrieve the first cookie with the given name. Note that multiple
489474
* cookies can have the same name but different paths or domains.
@@ -629,69 +614,6 @@ else if (values.length > 1) {
629614
return params;
630615
}
631616

632-
/**
633-
* Return the target page specified in the request.
634-
* @param request current servlet request
635-
* @param paramPrefix the parameter prefix to check for
636-
* (e.g. "_target" for parameters like "_target1" or "_target2")
637-
* @param currentPage the current page, to be returned as fallback
638-
* if no target page specified
639-
* @return the page specified in the request, or current page if not found
640-
*/
641-
public static int getTargetPage(ServletRequest request, String paramPrefix, int currentPage) {
642-
Enumeration<String> paramNames = request.getParameterNames();
643-
while (paramNames.hasMoreElements()) {
644-
String paramName = paramNames.nextElement();
645-
if (paramName.startsWith(paramPrefix)) {
646-
for (int i = 0; i < WebUtils.SUBMIT_IMAGE_SUFFIXES.length; i++) {
647-
String suffix = WebUtils.SUBMIT_IMAGE_SUFFIXES[i];
648-
if (paramName.endsWith(suffix)) {
649-
paramName = paramName.substring(0, paramName.length() - suffix.length());
650-
}
651-
}
652-
return Integer.parseInt(paramName.substring(paramPrefix.length()));
653-
}
654-
}
655-
return currentPage;
656-
}
657-
658-
659-
/**
660-
* Extract the URL filename from the given request URL path.
661-
* Correctly resolves nested paths such as "/products/view.html" as well.
662-
* @param urlPath the request URL path (e.g. "/index.html")
663-
* @return the extracted URI filename (e.g. "index")
664-
*/
665-
public static String extractFilenameFromUrlPath(String urlPath) {
666-
String filename = extractFullFilenameFromUrlPath(urlPath);
667-
int dotIndex = filename.lastIndexOf('.');
668-
if (dotIndex != -1) {
669-
filename = filename.substring(0, dotIndex);
670-
}
671-
return filename;
672-
}
673-
674-
/**
675-
* Extract the full URL filename (including file extension) from the given
676-
* request URL path. Correctly resolve nested paths such as
677-
* "/products/view.html" and remove any path and or query parameters.
678-
* @param urlPath the request URL path (e.g. "/products/index.html")
679-
* @return the extracted URI filename (e.g. "index.html")
680-
*/
681-
public static String extractFullFilenameFromUrlPath(String urlPath) {
682-
int end = urlPath.indexOf('?');
683-
if (end == -1) {
684-
end = urlPath.indexOf('#');
685-
if (end == -1) {
686-
end = urlPath.length();
687-
}
688-
}
689-
int begin = urlPath.lastIndexOf('/', end) + 1;
690-
int paramIndex = urlPath.indexOf(';', begin);
691-
end = (paramIndex != -1 && paramIndex < end ? paramIndex : end);
692-
return urlPath.substring(begin, end);
693-
}
694-
695617
/**
696618
* Parse the given string with matrix variables. An example string would look
697619
* like this {@code "q1=a;q1=b;q2=a,b,c"}. The resulting map would contain

spring-web/src/test/java/org/springframework/web/util/UriUtilsTests.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2016 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.
@@ -24,6 +24,7 @@
2424

2525
/**
2626
* @author Arjen Poutsma
27+
* @author Juergen Hoeller
2728
*/
2829
public class UriUtilsTests {
2930

@@ -104,4 +105,22 @@ public void decodeInvalidSequence() throws UnsupportedEncodingException {
104105
UriUtils.decode("foo%2", ENC);
105106
}
106107

108+
@Test
109+
public void extractFileExtension() {
110+
assertEquals("html", UriUtils.extractFileExtension("index.html"));
111+
assertEquals("html", UriUtils.extractFileExtension("/index.html"));
112+
assertEquals("html", UriUtils.extractFileExtension("/products/view.html"));
113+
assertEquals("html", UriUtils.extractFileExtension("/products/view.html#/a"));
114+
assertEquals("html", UriUtils.extractFileExtension("/products/view.html#/path/a"));
115+
assertEquals("html", UriUtils.extractFileExtension("/products/view.html#/path/a.do"));
116+
assertEquals("html", UriUtils.extractFileExtension("/products/view.html?param=a"));
117+
assertEquals("html", UriUtils.extractFileExtension("/products/view.html?param=/path/a"));
118+
assertEquals("html", UriUtils.extractFileExtension("/products/view.html?param=/path/a.do"));
119+
assertEquals("html", UriUtils.extractFileExtension("/products/view.html?param=/path/a#/path/a"));
120+
assertEquals("html", UriUtils.extractFileExtension("/products/view.html?param=/path/a.do#/path/a.do"));
121+
assertEquals("html", UriUtils.extractFileExtension("/products;q=11/view.html?param=/path/a.do"));
122+
assertEquals("html", UriUtils.extractFileExtension("/products;q=11/view.html;r=22?param=/path/a.do"));
123+
assertEquals("html", UriUtils.extractFileExtension("/products;q=11/view.html;r=22;s=33?param=/path/a.do"));
124+
}
125+
107126
}

spring-web/src/test/java/org/springframework/web/util/WebUtilsTests.java

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -55,34 +55,6 @@ public void findParameterValue() {
5555
assertEquals("myValue4", WebUtils.findParameterValue(params, "myKey4"));
5656
}
5757

58-
@Test
59-
public void extractFilenameFromUrlPath() {
60-
assertEquals("index", WebUtils.extractFilenameFromUrlPath("index.html"));
61-
assertEquals("index", WebUtils.extractFilenameFromUrlPath("/index.html"));
62-
assertEquals("view", WebUtils.extractFilenameFromUrlPath("/products/view.html"));
63-
assertEquals("view", WebUtils.extractFilenameFromUrlPath("/products/view.html?param=a"));
64-
assertEquals("view", WebUtils.extractFilenameFromUrlPath("/products/view.html?param=/path/a"));
65-
assertEquals("view", WebUtils.extractFilenameFromUrlPath("/products/view.html?param=/path/a.do"));
66-
}
67-
68-
@Test
69-
public void extractFullFilenameFromUrlPath() {
70-
assertEquals("index.html", WebUtils.extractFullFilenameFromUrlPath("index.html"));
71-
assertEquals("index.html", WebUtils.extractFullFilenameFromUrlPath("/index.html"));
72-
assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products/view.html"));
73-
assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products/view.html#/a"));
74-
assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products/view.html#/path/a"));
75-
assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products/view.html#/path/a.do"));
76-
assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products/view.html?param=a"));
77-
assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products/view.html?param=/path/a"));
78-
assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products/view.html?param=/path/a.do"));
79-
assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products/view.html?param=/path/a#/path/a"));
80-
assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products/view.html?param=/path/a.do#/path/a.do"));
81-
assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products;q=11/view.html?param=/path/a.do"));
82-
assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products;q=11/view.html;r=22?param=/path/a.do"));
83-
assertEquals("view.html", WebUtils.extractFullFilenameFromUrlPath("/products;q=11/view.html;r=22;s=33?param=/path/a.do"));
84-
}
85-
8658
@Test
8759
public void parseMatrixVariablesString() {
8860
MultiValueMap<String, String> variables;

spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
import org.springframework.web.context.request.ServletRequestAttributes;
2929
import org.springframework.web.util.UriComponents;
3030
import org.springframework.web.util.UriComponentsBuilder;
31+
import org.springframework.web.util.UriUtils;
3132
import org.springframework.web.util.UrlPathHelper;
32-
import org.springframework.web.util.WebUtils;
3333

3434
/**
3535
* A UriComponentsBuilder that extracts information from the HttpServletRequest.
@@ -44,7 +44,6 @@ public class ServletUriComponentsBuilder extends UriComponentsBuilder {
4444

4545
/**
4646
* Default constructor. Protected to prevent direct instantiation.
47-
*
4847
* @see #fromContextPath(HttpServletRequest)
4948
* @see #fromServletMapping(HttpServletRequest)
5049
* @see #fromRequest(HttpServletRequest)
@@ -219,8 +218,7 @@ private void initPath(String path) {
219218
public String removePathExtension() {
220219
String extension = null;
221220
if (this.originalPath != null) {
222-
String filename = WebUtils.extractFullFilenameFromUrlPath(this.originalPath);
223-
extension = StringUtils.getFilenameExtension(filename);
221+
extension = UriUtils.extractFileExtension(this.originalPath);
224222
if (!StringUtils.isEmpty(extension)) {
225223
int end = this.originalPath.length() - (extension.length() + 1);
226224
replacePath(this.originalPath.substring(0, end));

0 commit comments

Comments
 (0)