diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilder.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilder.java index 940118866f4c..c88c3348d5c5 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilder.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -75,6 +75,9 @@ class DefaultServerRequestBuilder implements ServerRequest.Builder { private URI uri; + @Nullable + private String contextPath; + private final HttpHeaders headers = new HttpHeaders(); private final MultiValueMap cookies = new LinkedMultiValueMap<>(); @@ -90,6 +93,7 @@ class DefaultServerRequestBuilder implements ServerRequest.Builder { this.exchange = other.exchange(); this.methodName = other.methodName(); this.uri = other.uri(); + this.contextPath = other.requestPath().contextPath().value(); this.headers.addAll(other.headers().asHttpHeaders()); this.cookies.addAll(other.cookies()); this.attributes.putAll(other.attributes()); @@ -110,6 +114,12 @@ public ServerRequest.Builder uri(URI uri) { return this; } + @Override + public ServerRequest.Builder contextPath(@Nullable String contextPath) { + this.contextPath = contextPath; + return this; + } + @Override public ServerRequest.Builder header(String headerName, String... headerValues) { for (String headerValue : headerValues) { @@ -177,7 +187,7 @@ public ServerRequest.Builder attributes(Consumer> attributes @Override public ServerRequest build() { ServerHttpRequest serverHttpRequest = new BuiltServerHttpRequest(this.exchange.getRequest().getId(), - this.methodName, this.uri, this.headers, this.cookies, this.body); + this.methodName, this.uri, this.contextPath, this.headers, this.cookies, this.body); ServerWebExchange exchange = new DelegatingServerWebExchange( serverHttpRequest, this.attributes, this.exchange, this.messageReaders); return new DefaultServerRequest(exchange, this.messageReaders); @@ -204,13 +214,13 @@ private static class BuiltServerHttpRequest implements ServerHttpRequest { private final Flux body; - public BuiltServerHttpRequest(String id, String method, URI uri, HttpHeaders headers, - MultiValueMap cookies, Flux body) { + public BuiltServerHttpRequest(String id, String method, URI uri, @Nullable String contextPath, + HttpHeaders headers, MultiValueMap cookies, Flux body) { this.id = id; this.method = method; this.uri = uri; - this.path = RequestPath.parse(uri, null); + this.path = RequestPath.parse(uri, contextPath); this.headers = HttpHeaders.readOnlyHttpHeaders(headers); this.cookies = unmodifiableCopy(cookies); this.queryParams = parseQueryParams(uri); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerRequest.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerRequest.java index 95eec309dc71..273434b1e13f 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerRequest.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -527,6 +527,14 @@ interface Builder { */ Builder uri(URI uri); + /** + * Set the context path of the request. + * @param contextPath the new context path + * @return this builder + * @since 5.3.23 + */ + Builder contextPath(@Nullable String contextPath); + /** * Add the given header value(s) under the given name. * @param headerName the header name diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilderTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilderTests.java index 6c312c0f57da..08179d75b3bf 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilderTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.web.reactive.function.server; +import java.net.URI; import java.nio.charset.StandardCharsets; import org.junit.jupiter.api.Test; @@ -56,8 +57,11 @@ public void from() { .map(s -> s.getBytes(StandardCharsets.UTF_8)) .map(DefaultDataBufferFactory.sharedInstance::wrap); + URI uri = URI.create("https://example2.com/foo/bar"); ServerRequest result = ServerRequest.from(other) .method(HttpMethod.HEAD) + .uri(uri) + .contextPath("/foo") .headers(httpHeaders -> httpHeaders.set("foo", "baar")) .cookies(cookies -> cookies.set("baz", ResponseCookie.from("baz", "quux").build())) .attribute("attr2", "value2") @@ -66,6 +70,9 @@ public void from() { .build(); assertThat(result.method()).isEqualTo(HttpMethod.HEAD); + assertThat(result.uri()).isEqualTo(uri); + assertThat(result.requestPath().pathWithinApplication().value()).isEqualTo("/bar"); + assertThat(result.requestPath().contextPath().value()).isEqualTo("/foo"); assertThat(result.headers().asHttpHeaders()).hasSize(1); assertThat(result.headers().asHttpHeaders().getFirst("foo")).isEqualTo("baar"); assertThat(result.cookies()).hasSize(1);