diff --git a/core/src/main/java/org/apache/struts2/interceptor/httpmethod/HttpMethod.java b/core/src/main/java/org/apache/struts2/interceptor/httpmethod/HttpMethod.java index 8e9b850997..13d3ec283f 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/httpmethod/HttpMethod.java +++ b/core/src/main/java/org/apache/struts2/interceptor/httpmethod/HttpMethod.java @@ -18,6 +18,8 @@ */ package org.apache.struts2.interceptor.httpmethod; +import java.util.Locale; + /** * Enum represents possible http request types * @@ -36,8 +38,28 @@ public enum HttpMethod { CONNECT, PATCH; + /** + * Returns the {@link HttpMethod} for the given request method, or {@code null} if it is not + * one of the methods this enum knows about. + * + *
Use this for the method of an incoming request. The client chooses that token freely, + * so an unrecognised value is ordinary input rather than a programming error, and must not + * raise.
+ */ + public static HttpMethod parseOrNull(String httpRequestMethod) { + if (httpRequestMethod == null) { + return null; + } + + try { + return valueOf(httpRequestMethod.toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException e) { + return null; + } + } + public static HttpMethod parse(String httpRequestMethod) { - return valueOf(httpRequestMethod.toUpperCase()); + return valueOf(httpRequestMethod.toUpperCase(Locale.ROOT)); } } diff --git a/core/src/main/java/org/apache/struts2/interceptor/httpmethod/HttpMethodInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/httpmethod/HttpMethodInterceptor.java index c6dbfc0d3b..08b3614018 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/httpmethod/HttpMethodInterceptor.java +++ b/core/src/main/java/org/apache/struts2/interceptor/httpmethod/HttpMethodInterceptor.java @@ -95,7 +95,10 @@ public String intercept(ActionInvocation invocation) throws Exception { if (action instanceof HttpMethodAware) { LOG.debug("Action: {} implements: {}, setting request method: {}", action, HttpMethodAware.class.getSimpleName(), request.getMethod()); - ((HttpMethodAware) (action)).setMethod(HttpMethod.parse(request.getMethod())); + HttpMethod requestedHttpMethod = HttpMethod.parseOrNull(request.getMethod()); + if (requestedHttpMethod != null) { + ((HttpMethodAware) (action)).setMethod(requestedHttpMethod); + } } if (invocation.getProxy().isMethodSpecified()) { diff --git a/core/src/test/java/org/apache/struts2/interceptor/httpmethod/HttpMethodTest.java b/core/src/test/java/org/apache/struts2/interceptor/httpmethod/HttpMethodTest.java index c56ef5f7ae..2e624171fe 100644 --- a/core/src/test/java/org/apache/struts2/interceptor/httpmethod/HttpMethodTest.java +++ b/core/src/test/java/org/apache/struts2/interceptor/httpmethod/HttpMethodTest.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; public class HttpMethodTest { @@ -55,4 +56,58 @@ public void shouldValueOfThrowsException() { assertEquals(expected.getClass(), IllegalArgumentException.class); } + + @Test + public void shouldParseUnknownRequestMethod_asNull_notRaise() { + // given : a request method this enum does not know about, e.g. a WebDAV verb + String httpRequestMethod = "PROPFIND"; + + // when + HttpMethod httpMethod = HttpMethod.parseOrNull(httpRequestMethod); + + // then + assertNull(httpMethod); + } + + @Test + public void shouldParseKnownRequestMethod_regardlessOfCase() { + // given + String httpRequestMethod = "get"; + + // when + HttpMethod httpMethod = HttpMethod.parseOrNull(httpRequestMethod); + + // then + assertEquals(HttpMethod.GET, httpMethod); + } + + @Test + public void shouldParseNullRequestMethod_asNull() { + // given + String httpRequestMethod = null; + + // when + HttpMethod httpMethod = HttpMethod.parseOrNull(httpRequestMethod); + + // then + assertNull(httpMethod); + } + + @Test + public void shouldStillRejectUnknownMethodInConfiguration() { + // given : configuration is trusted input, an unknown name there is a real error + String configuredMethod = "PROPFIND"; + + // when + Throwable expected = null; + try { + HttpMethod.parse(configuredMethod); + } catch (IllegalArgumentException e) { + expected = e; + } + + // then + assertNotNull(expected); + } + }