Browse Source

HTTP OPTIONS lists all HTTP methods except TRACE

This is in line with the current behavior of HttpServlet that would
have been in used with dispatchOptionsRequest on the DispatcherSerlvet
set to false (the default prior to 4.3).

Issue: SPR-13130
pull/1120/head
Rossen Stoyanchev 10 years ago
parent
commit
2607a22537
  1. 10
      spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/AbstractController.java
  2. 7
      spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java
  3. 12
      spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java
  4. 2
      spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/ParameterizableViewControllerTests.java
  5. 2
      spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java
  6. 2
      spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java
  7. 4
      src/asciidoc/web-mvc.adoc

10
spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/AbstractController.java

@ -16,15 +16,11 @@ @@ -16,15 +16,11 @@
package org.springframework.web.servlet.mvc;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.http.HttpMethod;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.support.WebContentGenerator;
import org.springframework.web.util.WebUtils;
@ -155,10 +151,8 @@ public abstract class AbstractController extends WebContentGenerator implements @@ -155,10 +151,8 @@ public abstract class AbstractController extends WebContentGenerator implements
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws Exception {
String[] supportedMethods = getSupportedMethods();
if (HttpMethod.OPTIONS.matches(request.getMethod()) && !ObjectUtils.isEmpty(supportedMethods)) {
List<String> value = Arrays.asList(supportedMethods);
response.setHeader("Allow", StringUtils.collectionToCommaDelimitedString(value));
if (HttpMethod.OPTIONS.matches(request.getMethod())) {
response.setHeader("Allow", getAllowHeader());
return null;
}

7
spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java

@ -317,8 +317,11 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe @@ -317,8 +317,11 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
private static Set<HttpMethod> initAllowedHttpMethods(Set<String> declaredMethods) {
Set<HttpMethod> result = new LinkedHashSet<HttpMethod>(declaredMethods.size());
if (declaredMethods.isEmpty()) {
result.add(HttpMethod.GET);
result.add(HttpMethod.HEAD);
for (HttpMethod method : HttpMethod.values()) {
if (!HttpMethod.TRACE.equals(method)) {
result.add(method);
}
}
}
else {
boolean hasHead = declaredMethods.contains("HEAD");

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

@ -112,7 +112,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator @@ -112,7 +112,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
public ResourceHttpRequestHandler() {
super(HttpMethod.GET.name(), HttpMethod.HEAD.name(), HttpMethod.OPTIONS.name());
super(HttpMethod.GET.name(), HttpMethod.HEAD.name());
this.resourceResolvers.add(new PathResourceResolver());
}
@ -226,6 +226,11 @@ public class ResourceHttpRequestHandler extends WebContentGenerator @@ -226,6 +226,11 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
if (HttpMethod.OPTIONS.matches(request.getMethod())) {
response.setHeader("Allow", getAllowHeader());
return;
}
// Supported methods and required session
checkRequest(request);
@ -237,11 +242,6 @@ public class ResourceHttpRequestHandler extends WebContentGenerator @@ -237,11 +242,6 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
return;
}
if (HttpMethod.OPTIONS.matches(request.getMethod())) {
response.setHeader("Allow", "GET,HEAD");
return;
}
// Header phase
if (new ServletWebRequest(request, response).checkNotModified(resource.lastModified())) {
logger.trace("Resource not modified - returning 304");

2
spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/ParameterizableViewControllerTests.java

@ -77,7 +77,7 @@ public class ParameterizableViewControllerTests { @@ -77,7 +77,7 @@ public class ParameterizableViewControllerTests {
ModelAndView mav = this.controller.handleRequest(this.request, response);
assertNull(mav);
assertEquals("GET,HEAD", response.getHeader("Allow"));
assertEquals("GET,HEAD,OPTIONS", response.getHeader("Allow"));
}
}

2
spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java

@ -180,7 +180,7 @@ public class RequestMappingInfoHandlerMappingTests { @@ -180,7 +180,7 @@ public class RequestMappingInfoHandlerMappingTests {
public void getHandlerHttpOptions() throws Exception {
testHttpOptions("/foo", "GET,HEAD");
testHttpOptions("/person/1", "PUT");
testHttpOptions("/persons", "GET,HEAD");
testHttpOptions("/persons", "GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS");
testHttpOptions("/something", "PUT,POST");
}

2
spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java

@ -119,7 +119,7 @@ public class ResourceHttpRequestHandlerTests { @@ -119,7 +119,7 @@ public class ResourceHttpRequestHandlerTests {
this.handler.handleRequest(this.request, this.response);
assertEquals(200, this.response.getStatus());
assertEquals("GET,HEAD", this.response.getHeader("Allow"));
assertEquals("GET,HEAD,OPTIONS", this.response.getHeader("Allow"));
}
@Test

4
src/asciidoc/web-mvc.adoc

@ -1174,8 +1174,8 @@ the number of bytes are counted and the "Content-Length" header set. @@ -1174,8 +1174,8 @@ the number of bytes are counted and the "Content-Length" header set.
HTTP OPTIONS request is handled by setting the "Allow" response header to the
HTTP methods explicitly declared on all `@RequestMapping` methods with matching
URL patterns. When no HTTP methods are explicitly declared the "Allow" header
is set to "GET,HEAD". Therefore it's highly recommended to always explicitly
declare the HTTP method(s) an `@RequestMapping` method is meant to handle.
is set to "GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS". Ideally always declare the
HTTP method(s) an `@RequestMapping` method is intended to handle.
Although not necessary an `@RequestMapping` method can be mapped to and handle
either HTTP HEAD or HTTP OPTIONS, or both.

Loading…
Cancel
Save