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
This commit is contained in:
@@ -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
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
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
|
||||
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");
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user