ForwardedHeaderTransformer handles encoding correctly
Issue: SPR-17525
This commit is contained in:
parent
0134c9d608
commit
7e9857a663
|
@ -22,6 +22,7 @@ import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
@ -36,6 +37,12 @@ import org.springframework.web.util.UriComponentsBuilder;
|
||||||
* <p>Alternatively if {@link #setRemoveOnly removeOnly} is set to "true",
|
* <p>Alternatively if {@link #setRemoveOnly removeOnly} is set to "true",
|
||||||
* then "Forwarded" and "X-Forwarded-*" headers are only removed, and not used.
|
* then "Forwarded" and "X-Forwarded-*" headers are only removed, and not used.
|
||||||
*
|
*
|
||||||
|
* <p>An instance of this class is typically declared as a bean with the name
|
||||||
|
* "forwardedHeaderTransformer" and detected by
|
||||||
|
* {@link WebHttpHandlerBuilder#applicationContext(ApplicationContext)}, or it
|
||||||
|
* can also be registered directly via
|
||||||
|
* {@link WebHttpHandlerBuilder#forwardedHeaderTransformer(ForwardedHeaderTransformer)}.
|
||||||
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 5.1
|
* @since 5.1
|
||||||
* @see <a href="https://tools.ietf.org/html/rfc7239">https://tools.ietf.org/html/rfc7239</a>
|
* @see <a href="https://tools.ietf.org/html/rfc7239">https://tools.ietf.org/html/rfc7239</a>
|
||||||
|
@ -85,7 +92,7 @@ public class ForwardedHeaderTransformer implements Function<ServerHttpRequest, S
|
||||||
if (hasForwardedHeaders(request)) {
|
if (hasForwardedHeaders(request)) {
|
||||||
ServerHttpRequest.Builder builder = request.mutate();
|
ServerHttpRequest.Builder builder = request.mutate();
|
||||||
if (!this.removeOnly) {
|
if (!this.removeOnly) {
|
||||||
URI uri = UriComponentsBuilder.fromHttpRequest(request).build().toUri();
|
URI uri = UriComponentsBuilder.fromHttpRequest(request).build(true).toUri();
|
||||||
builder.uri(uri);
|
builder.uri(uri);
|
||||||
String prefix = getForwardedPrefix(request);
|
String prefix = getForwardedPrefix(request);
|
||||||
if (prefix != null) {
|
if (prefix != null) {
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.net.URI;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
|
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
|
||||||
|
|
||||||
|
@ -100,6 +101,23 @@ public class ForwardedHeaderTransformerTests {
|
||||||
assertForwardedHeadersRemoved(request);
|
assertForwardedHeadersRemoved(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // SPR-17525
|
||||||
|
public void shouldNotDoubleEncode() throws Exception {
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.add("Forwarded", "host=84.198.58.199;proto=https");
|
||||||
|
|
||||||
|
ServerHttpRequest request = MockServerHttpRequest
|
||||||
|
.method(HttpMethod.GET, new URI("http://example.com/a%20b?q=a%2Bb"))
|
||||||
|
.headers(headers)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
request = this.requestMutator.apply(request);
|
||||||
|
|
||||||
|
assertEquals(new URI("https://84.198.58.199/a%20b?q=a%2Bb"), request.getURI());
|
||||||
|
assertForwardedHeadersRemoved(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private MockServerHttpRequest getRequest(HttpHeaders headers) {
|
private MockServerHttpRequest getRequest(HttpHeaders headers) {
|
||||||
return MockServerHttpRequest.get(BASE_URL).headers(headers).build();
|
return MockServerHttpRequest.get(BASE_URL).headers(headers).build();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue