Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ public final class HttpMethod implements Comparable<HttpMethod>, Serializable {
*/
public static final HttpMethod DELETE = new HttpMethod("DELETE");

/**
* The HTTP method {@code QUERY}.
* @see <a href="https://www.rfc-editor.org/info/rfc10008">RFC 10008</a>
*/
public static final HttpMethod QUERY = new HttpMethod("QUERY");

/**
* The HTTP method {@code OPTIONS}.
* @see <a href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.2">HTTP 1.1, section 9.2</a>
Expand All @@ -85,7 +91,7 @@ public final class HttpMethod implements Comparable<HttpMethod>, Serializable {
*/
public static final HttpMethod TRACE = new HttpMethod("TRACE");

private static final HttpMethod[] values = new HttpMethod[] { GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE };
private static final HttpMethod[] values = new HttpMethod[] { GET, HEAD, POST, PUT, PATCH, DELETE, QUERY, OPTIONS, TRACE };


private final String name;
Expand All @@ -98,7 +104,7 @@ private HttpMethod(String name) {
/**
* Returns an array containing the standard HTTP methods. Specifically,
* this method returns an array containing {@link #GET}, {@link #HEAD},
* {@link #POST}, {@link #PUT}, {@link #PATCH}, {@link #DELETE},
* {@link #POST}, {@link #PUT}, {@link #PATCH}, {@link #DELETE}, {@link #QUERY},
* {@link #OPTIONS}, and {@link #TRACE}.
*
* <p>Note that the returned value does not include any HTTP methods defined
Expand Down Expand Up @@ -135,6 +141,7 @@ public static HttpMethod valueOf(String method) {
case "PUT" -> PUT;
case "PATCH" -> PATCH;
case "DELETE" -> DELETE;
case "QUERY" -> QUERY;
case "OPTIONS" -> OPTIONS;
case "TRACE" -> TRACE;
default -> new HttpMethod(method);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.classic.methods.HttpPut;
import org.apache.hc.client5.http.classic.methods.HttpTrace;
import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
import org.apache.hc.client5.http.config.Configurable;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.classic.HttpClients;
Expand Down Expand Up @@ -294,6 +295,9 @@ else if (HttpMethod.PATCH.equals(httpMethod)) {
else if (HttpMethod.DELETE.equals(httpMethod)) {
return new HttpDelete(uri);
}
else if (HttpMethod.QUERY.equals(httpMethod)) {
return new HttpUriRequestBase(httpMethod.name(), uri);
}
else if (HttpMethod.OPTIONS.equals(httpMethod)) {
return new HttpOptions(uri);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@

/**
* The HTTP request methods to map to, narrowing the primary mapping:
* GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE.
* GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, QUERY, TRACE.
* <p><b>Supported at the type level as well as at the method level!</b>
* When used at the type level, all method-level mappings inherit this
* HTTP method restriction.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@
* {@link RequestMapping#method()} attribute of the {@link RequestMapping} annotation.
*
* <p>Note that, by default, {@link org.springframework.web.servlet.DispatcherServlet}
* supports GET, HEAD, POST, PUT, PATCH, and DELETE only. DispatcherServlet will
* process TRACE and OPTIONS with the default HttpServlet behavior unless explicitly
* told to dispatch those request types as well: Check out the "dispatchOptionsRequest"
* and "dispatchTraceRequest" properties, switching them to "true" if necessary.
* supports GET, HEAD, POST, PUT, PATCH, DELETE, and custom methods such as QUERY.
* DispatcherServlet will process TRACE and OPTIONS with the default HttpServlet
* behavior unless explicitly told to dispatch those request types as well:
* check out the "dispatchOptionsRequest" and "dispatchTraceRequest" properties,
* switching them to "true" if necessary.
*
* @author Juergen Hoeller
* @since 2.5
Expand All @@ -39,7 +40,7 @@
*/
public enum RequestMethod {

GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
GET, HEAD, POST, PUT, PATCH, DELETE, QUERY, OPTIONS, TRACE;


/**
Expand All @@ -58,6 +59,7 @@ public enum RequestMethod {
case "PUT" -> PUT;
case "PATCH" -> PATCH;
case "DELETE" -> DELETE;
case "QUERY" -> QUERY;
case "OPTIONS" -> OPTIONS;
case "TRACE" -> TRACE;
default -> null;
Expand Down Expand Up @@ -90,6 +92,7 @@ public HttpMethod asHttpMethod() {
case PUT -> HttpMethod.PUT;
case PATCH -> HttpMethod.PATCH;
case DELETE -> HttpMethod.DELETE;
case QUERY -> HttpMethod.QUERY;
case OPTIONS -> HttpMethod.OPTIONS;
case TRACE -> HttpMethod.TRACE;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ void comparison() {
void values() {
HttpMethod[] values = HttpMethod.values();
assertThat(values).containsExactly(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.POST, HttpMethod.PUT,
HttpMethod.PATCH, HttpMethod.DELETE, HttpMethod.OPTIONS, HttpMethod.TRACE);
HttpMethod.PATCH, HttpMethod.DELETE, HttpMethod.QUERY, HttpMethod.OPTIONS, HttpMethod.TRACE);

// check defensive copy
values[0] = HttpMethod.POST;
assertThat(HttpMethod.values()).containsExactly(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.POST, HttpMethod.PUT,
HttpMethod.PATCH, HttpMethod.DELETE, HttpMethod.OPTIONS, HttpMethod.TRACE);
HttpMethod.PATCH, HttpMethod.DELETE, HttpMethod.QUERY, HttpMethod.OPTIONS, HttpMethod.TRACE);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ protected ClientHttpRequestFactory createRequestFactory() {
void httpMethods() throws Exception {
super.httpMethods();
assertHttpMethod("patch", HttpMethod.PATCH);
assertHttpMethod("query", HttpMethod.QUERY);
}

@Test
Expand Down Expand Up @@ -186,7 +187,7 @@ void shouldSetContentLengthWhenEmptyBody(HttpMethod method) throws Exception {
}

static Stream<HttpMethod> unsafeHttpMethods() {
return Stream.of(HttpMethod.POST, HttpMethod.PUT, HttpMethod.DELETE, HttpMethod.PATCH);
return Stream.of(HttpMethod.POST, HttpMethod.PUT, HttpMethod.DELETE, HttpMethod.PATCH, HttpMethod.QUERY);
}

@ParameterizedTest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class RequestMethodTests {

@Test
void resolveString() {
String[] methods = new String[]{"GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "TRACE"};
String[] methods = new String[]{"GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "QUERY", "OPTIONS", "TRACE"};
for (String httpMethod : methods) {
RequestMethod requestMethod = RequestMethod.resolve(httpMethod);
assertThat(requestMethod).isNotNull();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ void getHandlerMediaTypeNotSupportedWithParseError(TestRequestMappingInfoHandler
void getHandlerHttpOptions(TestRequestMappingInfoHandlerMapping mapping) throws Exception {
testHttpOptions(mapping, "/foo", "GET,HEAD,OPTIONS", null);
testHttpOptions(mapping, "/person/1", "PUT,OPTIONS", null);
testHttpOptions(mapping, "/persons", "GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS", null);
testHttpOptions(mapping, "/persons", "GET,HEAD,POST,PUT,PATCH,DELETE,QUERY,OPTIONS", null);
testHttpOptions(mapping, "/something", "PUT,POST", null);
testHttpOptions(mapping, "/qux", "PATCH,GET,HEAD,OPTIONS", new MediaType("foo", "bar"));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ void getAllowHeaderWithConstructorTrue() {
@Test
void getAllowHeaderWithConstructorFalse() {
WebContentGenerator generator = new TestWebContentGenerator(false);
assertThat(generator.getAllowHeader()).isEqualTo("GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS");
assertThat(generator.getAllowHeader()).isEqualTo("GET,HEAD,POST,PUT,PATCH,DELETE,QUERY,OPTIONS");
}

@Test
Expand All @@ -59,7 +59,8 @@ void getAllowHeaderWithSupportedMethodsSetter() {
void getAllowHeaderWithSupportedMethodsSetterEmpty() {
WebContentGenerator generator = new TestWebContentGenerator();
generator.setSupportedMethods();
assertThat(generator.getAllowHeader()).as("Effectively \"no restriction\" on supported methods").isEqualTo("GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS");
assertThat(generator.getAllowHeader()).as("Effectively \"no restriction\" on supported methods")
.isEqualTo("GET,HEAD,POST,PUT,PATCH,DELETE,QUERY,OPTIONS");
}

@Test
Expand Down