Skip to content

Commit ecb351c

Browse files
committed
return 404 in case of no media type found
1 parent b51f067 commit ecb351c

File tree

1 file changed

+75
-19
lines changed

1 file changed

+75
-19
lines changed

org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java

Lines changed: 75 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -96,17 +96,43 @@ public void handleRequest(HttpServletRequest request, HttpServletResponse respon
9696
throws ServletException, IOException {
9797

9898
checkAndPrepare(request, response, true);
99+
100+
// check whether a matching resource exists
99101
Resource resource = getResource(request);
100102
if (resource == null) {
103+
logger.debug("No matching resource found - returning 404");
101104
response.sendError(HttpServletResponse.SC_NOT_FOUND);
102105
return;
103106
}
104-
setHeaders(resource, response);
105-
if (new ServletWebRequest(request, response).checkNotModified(resource.lastModified()) ||
106-
METHOD_HEAD.equals(request.getMethod())) {
107+
108+
// check the resource's media type
109+
MediaType mediaType = getMediaType(resource);
110+
if (mediaType != null) {
111+
if (logger.isDebugEnabled()) {
112+
logger.debug("Determined media type [" + mediaType + "] for " + resource);
113+
}
114+
}
115+
else {
116+
if (logger.isDebugEnabled()) {
117+
logger.debug("No media type found for " + resource + " - returning 404");
118+
}
119+
response.sendError(HttpServletResponse.SC_NOT_FOUND);
107120
return;
108121
}
109-
writeContent(resource, response);
122+
123+
// header phase
124+
setHeaders(response, resource, mediaType);
125+
if (new ServletWebRequest(request, response).checkNotModified(resource.lastModified())) {
126+
logger.debug("Resource not modified - returning 304");
127+
return;
128+
}
129+
130+
// content phase
131+
if (METHOD_HEAD.equals(request.getMethod())) {
132+
logger.trace("HEAD request - skipping content");
133+
return;
134+
}
135+
writeContent(response, resource);
110136
}
111137

112138
protected Resource getResource(HttpServletRequest request) {
@@ -115,42 +141,72 @@ protected Resource getResource(HttpServletRequest request) {
115141
throw new IllegalStateException("Required request attribute '" +
116142
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE + "' is not set");
117143
}
144+
118145
if (!StringUtils.hasText(path) || path.contains("WEB-INF") || path.contains("META-INF")) {
146+
if (logger.isDebugEnabled()) {
147+
logger.debug("Ignoring invalid resource path [" + path + "]");
148+
}
119149
return null;
120150
}
121-
for (Resource resourcePath : this.locations) {
151+
152+
for (Resource location : this.locations) {
122153
try {
123-
Resource resource = resourcePath.createRelative(path);
154+
if (logger.isDebugEnabled()) {
155+
logger.debug("Trying relative path [" + path + "] against base location: " + location);
156+
}
157+
Resource resource = location.createRelative(path);
124158
if (resource.exists() && resource.isReadable()) {
159+
if (logger.isDebugEnabled()) {
160+
logger.debug("Found matching resource: " + resource);
161+
}
125162
return resource;
126163
}
164+
else if (logger.isTraceEnabled()) {
165+
logger.trace("Relative resource doesn't exist or isn't readable: " + resource);
166+
}
127167
}
128168
catch (IOException ex) {
129-
// resource not found
130-
return null;
169+
logger.debug("Failed to create relative resource - trying next resource location", ex);
131170
}
132171
}
133172
return null;
134173
}
135174

136-
protected void setHeaders(Resource resource, HttpServletResponse response) throws IOException {
137-
MediaType mediaType = getMediaType(resource);
138-
if (mediaType != null) {
139-
response.setContentType(mediaType.toString());
140-
}
175+
/**
176+
* Determine an appropriate media type for the given resource.
177+
* @param resource the resource to check
178+
* @return the corresponding media type, or <code>null</code> if none found
179+
*/
180+
protected MediaType getMediaType(Resource resource) {
181+
String mimeType = getServletContext().getMimeType(resource.getFilename());
182+
return (StringUtils.hasText(mimeType) ? MediaType.parseMediaType(mimeType) : null);
183+
}
184+
185+
/**
186+
* Set headers on the given servlet response.
187+
* Called for GET requests as well as HEAD requests.
188+
* @param response current servlet response
189+
* @param resource the identified resource (never <code>null</code>)
190+
* @param mediaType the resource's media type (never <code>null</code>)
191+
* @throws IOException in case of errors while setting the headers
192+
*/
193+
protected void setHeaders(HttpServletResponse response, Resource resource, MediaType mediaType) throws IOException {
141194
long length = resource.contentLength();
142195
if (length > Integer.MAX_VALUE) {
143196
throw new IOException("Resource content too long (beyond Integer.MAX_VALUE): " + resource);
144197
}
145198
response.setContentLength((int) length);
199+
response.setContentType(mediaType.toString());
146200
}
147201

148-
protected MediaType getMediaType(Resource resource) {
149-
String mimeType = getServletContext().getMimeType(resource.getFilename());
150-
return (StringUtils.hasText(mimeType) ? MediaType.parseMediaType(mimeType) : null);
151-
}
152-
153-
protected void writeContent(Resource resource, HttpServletResponse response) throws IOException {
202+
/**
203+
* Write the actual content out to the given servlet response,
204+
* streaming the resource's content.
205+
* @param response current servlet response
206+
* @param resource the identified resource (never <code>null</code>)
207+
* @throws IOException in case of errors while writing the content
208+
*/
209+
protected void writeContent(HttpServletResponse response, Resource resource) throws IOException {
154210
FileCopyUtils.copy(resource.getInputStream(), response.getOutputStream());
155211
}
156212

0 commit comments

Comments
 (0)