Cache ServerHttpRequest::getMethod in AbstractServerHttpRequest
This commit ensures that the HttpMethod, exposed through ServerHttpRequest::getMethod, is cached in AbstractServerHttpRequest so that potentially expensive HTTP method lookups are only done once. Closes gh-30139
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -54,8 +54,6 @@ import org.springframework.web.util.UriComponentsBuilder;
|
|||||||
*/
|
*/
|
||||||
public final class MockServerHttpRequest extends AbstractServerHttpRequest {
|
public final class MockServerHttpRequest extends AbstractServerHttpRequest {
|
||||||
|
|
||||||
private final HttpMethod httpMethod;
|
|
||||||
|
|
||||||
private final MultiValueMap<String, HttpCookie> cookies;
|
private final MultiValueMap<String, HttpCookie> cookies;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -74,8 +72,7 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest {
|
|||||||
@Nullable InetSocketAddress localAddress, @Nullable InetSocketAddress remoteAddress,
|
@Nullable InetSocketAddress localAddress, @Nullable InetSocketAddress remoteAddress,
|
||||||
@Nullable SslInfo sslInfo, Publisher<? extends DataBuffer> body) {
|
@Nullable SslInfo sslInfo, Publisher<? extends DataBuffer> body) {
|
||||||
|
|
||||||
super(uri, contextPath, headers);
|
super(httpMethod, uri, contextPath, headers);
|
||||||
this.httpMethod = httpMethod;
|
|
||||||
this.cookies = cookies;
|
this.cookies = cookies;
|
||||||
this.localAddress = localAddress;
|
this.localAddress = localAddress;
|
||||||
this.remoteAddress = remoteAddress;
|
this.remoteAddress = remoteAddress;
|
||||||
@@ -84,11 +81,6 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpMethod getMethod() {
|
|
||||||
return this.httpMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public InetSocketAddress getLocalAddress() {
|
public InetSocketAddress getLocalAddress() {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -24,8 +24,10 @@ import java.util.regex.Pattern;
|
|||||||
|
|
||||||
import org.springframework.http.HttpCookie;
|
import org.springframework.http.HttpCookie;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.server.RequestPath;
|
import org.springframework.http.server.RequestPath;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
@@ -49,6 +51,10 @@ public abstract class AbstractServerHttpRequest implements ServerHttpRequest {
|
|||||||
|
|
||||||
private final HttpHeaders headers;
|
private final HttpHeaders headers;
|
||||||
|
|
||||||
|
// TODO: remove @Nullable once deprecated constructors have been removed
|
||||||
|
@Nullable
|
||||||
|
private final HttpMethod method;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private MultiValueMap<String, String> queryParams;
|
private MultiValueMap<String, String> queryParams;
|
||||||
|
|
||||||
@@ -71,11 +77,35 @@ public abstract class AbstractServerHttpRequest implements ServerHttpRequest {
|
|||||||
* @param contextPath the context path for the request
|
* @param contextPath the context path for the request
|
||||||
* @param headers the headers for the request (as {@link MultiValueMap})
|
* @param headers the headers for the request (as {@link MultiValueMap})
|
||||||
* @since 5.3
|
* @since 5.3
|
||||||
|
* @deprecated since 6.0.8, in favor of {@link #AbstractServerHttpRequest(HttpMethod, URI, String, MultiValueMap)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "6.0.8", forRemoval = true)
|
||||||
public AbstractServerHttpRequest(URI uri, @Nullable String contextPath, MultiValueMap<String, String> headers) {
|
public AbstractServerHttpRequest(URI uri, @Nullable String contextPath, MultiValueMap<String, String> headers) {
|
||||||
this.uri = uri;
|
this.uri = uri;
|
||||||
this.path = RequestPath.parse(uri, contextPath);
|
this.path = RequestPath.parse(uri, contextPath);
|
||||||
this.headers = HttpHeaders.readOnlyHttpHeaders(headers);
|
this.headers = HttpHeaders.readOnlyHttpHeaders(headers);
|
||||||
|
this.method = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor with the method, URI and headers for the request.
|
||||||
|
* @param method the HTTP method for the request
|
||||||
|
* @param uri the URI for the request
|
||||||
|
* @param contextPath the context path for the request
|
||||||
|
* @param headers the headers for the request (as {@link MultiValueMap})
|
||||||
|
* @since 6.0.8
|
||||||
|
*/
|
||||||
|
public AbstractServerHttpRequest(HttpMethod method, URI uri, @Nullable String contextPath,
|
||||||
|
MultiValueMap<String, String> headers) {
|
||||||
|
|
||||||
|
Assert.notNull(method, "Method must not be null");
|
||||||
|
Assert.notNull(uri, "Uri must not be null");
|
||||||
|
Assert.notNull(headers, "Headers must not be null");
|
||||||
|
|
||||||
|
this.method = method;
|
||||||
|
this.uri = uri;
|
||||||
|
this.path = RequestPath.parse(uri, contextPath);
|
||||||
|
this.headers = HttpHeaders.readOnlyHttpHeaders(headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,11 +113,14 @@ public abstract class AbstractServerHttpRequest implements ServerHttpRequest {
|
|||||||
* @param uri the URI for the request
|
* @param uri the URI for the request
|
||||||
* @param contextPath the context path for the request
|
* @param contextPath the context path for the request
|
||||||
* @param headers the headers for the request (as {@link HttpHeaders})
|
* @param headers the headers for the request (as {@link HttpHeaders})
|
||||||
|
* @deprecated since 6.0.8, in favor of {@link #AbstractServerHttpRequest(HttpMethod, URI, String, MultiValueMap)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "6.0.8", forRemoval = true)
|
||||||
public AbstractServerHttpRequest(URI uri, @Nullable String contextPath, HttpHeaders headers) {
|
public AbstractServerHttpRequest(URI uri, @Nullable String contextPath, HttpHeaders headers) {
|
||||||
this.uri = uri;
|
this.uri = uri;
|
||||||
this.path = RequestPath.parse(uri, contextPath);
|
this.path = RequestPath.parse(uri, contextPath);
|
||||||
this.headers = HttpHeaders.readOnlyHttpHeaders(headers);
|
this.headers = HttpHeaders.readOnlyHttpHeaders(headers);
|
||||||
|
this.method = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -112,6 +145,18 @@ public abstract class AbstractServerHttpRequest implements ServerHttpRequest {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpMethod getMethod() {
|
||||||
|
// TODO: remove null check once deprecated constructors have been removed
|
||||||
|
if (this.method != null) {
|
||||||
|
return this.method;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IllegalStateException("No HttpMethod provided in constructor, " +
|
||||||
|
"and AbstractServerHttpRequest::getMethod not overridden");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public URI getURI() {
|
public URI getURI() {
|
||||||
return this.uri;
|
return this.uri;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -177,8 +177,6 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder {
|
|||||||
|
|
||||||
private static class MutatedServerHttpRequest extends AbstractServerHttpRequest {
|
private static class MutatedServerHttpRequest extends AbstractServerHttpRequest {
|
||||||
|
|
||||||
private final HttpMethod method;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final SslInfo sslInfo;
|
private final SslInfo sslInfo;
|
||||||
|
|
||||||
@@ -194,19 +192,13 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder {
|
|||||||
HttpMethod method, @Nullable SslInfo sslInfo, @Nullable InetSocketAddress remoteAddress,
|
HttpMethod method, @Nullable SslInfo sslInfo, @Nullable InetSocketAddress remoteAddress,
|
||||||
HttpHeaders headers, Flux<DataBuffer> body, ServerHttpRequest originalRequest) {
|
HttpHeaders headers, Flux<DataBuffer> body, ServerHttpRequest originalRequest) {
|
||||||
|
|
||||||
super(uri, contextPath, headers);
|
super(method, uri, contextPath, headers);
|
||||||
this.method = method;
|
|
||||||
this.remoteAddress = (remoteAddress != null ? remoteAddress : originalRequest.getRemoteAddress());
|
this.remoteAddress = (remoteAddress != null ? remoteAddress : originalRequest.getRemoteAddress());
|
||||||
this.sslInfo = (sslInfo != null ? sslInfo : originalRequest.getSslInfo());
|
this.sslInfo = (sslInfo != null ? sslInfo : originalRequest.getSslInfo());
|
||||||
this.body = body;
|
this.body = body;
|
||||||
this.originalRequest = originalRequest;
|
this.originalRequest = originalRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpMethod getMethod() {
|
|
||||||
return this.method;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MultiValueMap<String, HttpCookie> initCookies() {
|
protected MultiValueMap<String, HttpCookie> initCookies() {
|
||||||
return this.originalRequest.getCookies();
|
return this.originalRequest.getCookies();
|
||||||
|
|||||||
@@ -63,17 +63,15 @@ class ReactorNetty2ServerHttpRequest extends AbstractServerHttpRequest {
|
|||||||
|
|
||||||
private final Netty5DataBufferFactory bufferFactory;
|
private final Netty5DataBufferFactory bufferFactory;
|
||||||
|
|
||||||
private final HttpMethod method;
|
|
||||||
|
|
||||||
|
|
||||||
public ReactorNetty2ServerHttpRequest(HttpServerRequest request, Netty5DataBufferFactory bufferFactory)
|
public ReactorNetty2ServerHttpRequest(HttpServerRequest request, Netty5DataBufferFactory bufferFactory)
|
||||||
throws URISyntaxException {
|
throws URISyntaxException {
|
||||||
|
|
||||||
super(initUri(request), "", new Netty5HeadersAdapter(request.requestHeaders()));
|
super(HttpMethod.valueOf(request.method().name()), initUri(request), "",
|
||||||
|
new Netty5HeadersAdapter(request.requestHeaders()));
|
||||||
Assert.notNull(bufferFactory, "DataBufferFactory must not be null");
|
Assert.notNull(bufferFactory, "DataBufferFactory must not be null");
|
||||||
this.request = request;
|
this.request = request;
|
||||||
this.bufferFactory = bufferFactory;
|
this.bufferFactory = bufferFactory;
|
||||||
this.method = HttpMethod.valueOf(request.method().name());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static URI initUri(HttpServerRequest request) throws URISyntaxException {
|
private static URI initUri(HttpServerRequest request) throws URISyntaxException {
|
||||||
@@ -142,11 +140,6 @@ class ReactorNetty2ServerHttpRequest extends AbstractServerHttpRequest {
|
|||||||
return uri;
|
return uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpMethod getMethod() {
|
|
||||||
return this.method;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MultiValueMap<String, HttpCookie> initCookies() {
|
protected MultiValueMap<String, HttpCookie> initCookies() {
|
||||||
MultiValueMap<String, HttpCookie> cookies = new LinkedMultiValueMap<>();
|
MultiValueMap<String, HttpCookie> cookies = new LinkedMultiValueMap<>();
|
||||||
|
|||||||
@@ -61,17 +61,15 @@ class ReactorServerHttpRequest extends AbstractServerHttpRequest {
|
|||||||
|
|
||||||
private final NettyDataBufferFactory bufferFactory;
|
private final NettyDataBufferFactory bufferFactory;
|
||||||
|
|
||||||
private final HttpMethod method;
|
|
||||||
|
|
||||||
|
|
||||||
public ReactorServerHttpRequest(HttpServerRequest request, NettyDataBufferFactory bufferFactory)
|
public ReactorServerHttpRequest(HttpServerRequest request, NettyDataBufferFactory bufferFactory)
|
||||||
throws URISyntaxException {
|
throws URISyntaxException {
|
||||||
|
|
||||||
super(initUri(request), "", new NettyHeadersAdapter(request.requestHeaders()));
|
super(HttpMethod.valueOf(request.method().name()), initUri(request), "",
|
||||||
|
new NettyHeadersAdapter(request.requestHeaders()));
|
||||||
Assert.notNull(bufferFactory, "DataBufferFactory must not be null");
|
Assert.notNull(bufferFactory, "DataBufferFactory must not be null");
|
||||||
this.request = request;
|
this.request = request;
|
||||||
this.bufferFactory = bufferFactory;
|
this.bufferFactory = bufferFactory;
|
||||||
this.method = HttpMethod.valueOf(request.method().name());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static URI initUri(HttpServerRequest request) throws URISyntaxException {
|
private static URI initUri(HttpServerRequest request) throws URISyntaxException {
|
||||||
@@ -112,10 +110,6 @@ class ReactorServerHttpRequest extends AbstractServerHttpRequest {
|
|||||||
return uri;
|
return uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpMethod getMethod() {
|
|
||||||
return this.method;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MultiValueMap<String, HttpCookie> initCookies() {
|
protected MultiValueMap<String, HttpCookie> initCookies() {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -90,7 +90,8 @@ class ServletServerHttpRequest extends AbstractServerHttpRequest {
|
|||||||
AsyncContext asyncContext, String servletPath, DataBufferFactory bufferFactory, int bufferSize)
|
AsyncContext asyncContext, String servletPath, DataBufferFactory bufferFactory, int bufferSize)
|
||||||
throws IOException, URISyntaxException {
|
throws IOException, URISyntaxException {
|
||||||
|
|
||||||
super(initUri(request), request.getContextPath() + servletPath, initHeaders(headers, request));
|
super(HttpMethod.valueOf(request.getMethod()), initUri(request), request.getContextPath() + servletPath,
|
||||||
|
initHeaders(headers, request));
|
||||||
|
|
||||||
Assert.notNull(bufferFactory, "'bufferFactory' must not be null");
|
Assert.notNull(bufferFactory, "'bufferFactory' must not be null");
|
||||||
Assert.isTrue(bufferSize > 0, "'bufferSize' must be greater than 0");
|
Assert.isTrue(bufferSize > 0, "'bufferSize' must be greater than 0");
|
||||||
@@ -162,11 +163,6 @@ class ServletServerHttpRequest extends AbstractServerHttpRequest {
|
|||||||
return (headers != null ? headers : headerValues);
|
return (headers != null ? headers : headerValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpMethod getMethod() {
|
|
||||||
return HttpMethod.valueOf(this.request.getMethod());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MultiValueMap<String, HttpCookie> initCookies() {
|
protected MultiValueMap<String, HttpCookie> initCookies() {
|
||||||
MultiValueMap<String, HttpCookie> httpCookies = new LinkedMultiValueMap<>();
|
MultiValueMap<String, HttpCookie> httpCookies = new LinkedMultiValueMap<>();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -64,7 +64,8 @@ class UndertowServerHttpRequest extends AbstractServerHttpRequest {
|
|||||||
public UndertowServerHttpRequest(HttpServerExchange exchange, DataBufferFactory bufferFactory)
|
public UndertowServerHttpRequest(HttpServerExchange exchange, DataBufferFactory bufferFactory)
|
||||||
throws URISyntaxException {
|
throws URISyntaxException {
|
||||||
|
|
||||||
super(initUri(exchange), "", new UndertowHeadersAdapter(exchange.getRequestHeaders()));
|
super(HttpMethod.valueOf(exchange.getRequestMethod().toString()), initUri(exchange), "",
|
||||||
|
new UndertowHeadersAdapter(exchange.getRequestHeaders()));
|
||||||
this.exchange = exchange;
|
this.exchange = exchange;
|
||||||
this.body = new RequestBodyPublisher(exchange, bufferFactory);
|
this.body = new RequestBodyPublisher(exchange, bufferFactory);
|
||||||
this.body.registerListeners(exchange);
|
this.body.registerListeners(exchange);
|
||||||
@@ -78,11 +79,6 @@ class UndertowServerHttpRequest extends AbstractServerHttpRequest {
|
|||||||
return new URI(requestUriAndQuery);
|
return new URI(requestUriAndQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpMethod getMethod() {
|
|
||||||
return HttpMethod.valueOf(this.exchange.getRequestMethod().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MultiValueMap<String, HttpCookie> initCookies() {
|
protected MultiValueMap<String, HttpCookie> initCookies() {
|
||||||
MultiValueMap<String, HttpCookie> cookies = new LinkedMultiValueMap<>();
|
MultiValueMap<String, HttpCookie> cookies = new LinkedMultiValueMap<>();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -55,8 +55,6 @@ import org.springframework.web.util.UriComponentsBuilder;
|
|||||||
*/
|
*/
|
||||||
public final class MockServerHttpRequest extends AbstractServerHttpRequest {
|
public final class MockServerHttpRequest extends AbstractServerHttpRequest {
|
||||||
|
|
||||||
private final HttpMethod httpMethod;
|
|
||||||
|
|
||||||
private final MultiValueMap<String, HttpCookie> cookies;
|
private final MultiValueMap<String, HttpCookie> cookies;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -75,8 +73,7 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest {
|
|||||||
@Nullable InetSocketAddress localAddress, @Nullable InetSocketAddress remoteAddress,
|
@Nullable InetSocketAddress localAddress, @Nullable InetSocketAddress remoteAddress,
|
||||||
@Nullable SslInfo sslInfo, Publisher<? extends DataBuffer> body) {
|
@Nullable SslInfo sslInfo, Publisher<? extends DataBuffer> body) {
|
||||||
|
|
||||||
super(uri, contextPath, headers);
|
super(httpMethod, uri, contextPath, headers);
|
||||||
this.httpMethod = httpMethod;
|
|
||||||
this.cookies = cookies;
|
this.cookies = cookies;
|
||||||
this.localAddress = localAddress;
|
this.localAddress = localAddress;
|
||||||
this.remoteAddress = remoteAddress;
|
this.remoteAddress = remoteAddress;
|
||||||
@@ -85,11 +82,6 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpMethod getMethod() {
|
|
||||||
return this.httpMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public InetSocketAddress getLocalAddress() {
|
public InetSocketAddress getLocalAddress() {
|
||||||
|
|||||||
Reference in New Issue
Block a user