Support encodeUrl mechanism via ServerHttpResponse
Issue: SPR-14529
This commit is contained in:
@@ -19,6 +19,7 @@ package org.springframework.http.server.reactive;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -66,6 +67,8 @@ public abstract class AbstractServerHttpResponse implements ServerHttpResponse {
|
||||
|
||||
private final MultiValueMap<String, ResponseCookie> cookies;
|
||||
|
||||
private Function<String, String> urlEncoder = url -> url;
|
||||
|
||||
private final AtomicReference<State> state = new AtomicReference<>(State.NEW);
|
||||
|
||||
private final List<Supplier<? extends Mono<Void>>> commitActions = new ArrayList<>(4);
|
||||
@@ -117,6 +120,16 @@ public abstract class AbstractServerHttpResponse implements ServerHttpResponse {
|
||||
CollectionUtils.unmodifiableMultiValueMap(this.cookies) : this.cookies);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encodeUrl(String url) {
|
||||
return (this.urlEncoder != null ? this.urlEncoder.apply(url) : url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerUrlEncoder(Function<String, String> encoder) {
|
||||
this.urlEncoder = (this.urlEncoder != null ? this.urlEncoder.andThen(encoder) : encoder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeCommit(Supplier<? extends Mono<Void>> action) {
|
||||
if (action != null) {
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.http.server.reactive;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
@@ -50,6 +52,24 @@ public interface ServerHttpResponse extends ReactiveHttpOutputMessage {
|
||||
*/
|
||||
MultiValueMap<String, ResponseCookie> getCookies();
|
||||
|
||||
/**
|
||||
* A mechanism for URL rewriting that applications and libraries such as
|
||||
* HTML template libraries to use consistently for all URLs emitted by
|
||||
* the application. Doing so enables the registration of URL encoders via
|
||||
* {@link #registerUrlEncoder} that can insert an id for authentication,
|
||||
* a nonce for CSRF protection, a version for a static resource, etc.
|
||||
* @param url the URL to encode
|
||||
* @return the encoded URL or the same
|
||||
*/
|
||||
String encodeUrl(String url);
|
||||
|
||||
/**
|
||||
* Register a URL rewriting function for use with {@link #encodeUrl}.
|
||||
* The function must return an encoded URL or the same URL.
|
||||
* @param encoder a URL encoding function to use
|
||||
*/
|
||||
void registerUrlEncoder(Function<String, String> encoder);
|
||||
|
||||
/**
|
||||
* Indicate that request handling is complete, allowing for any cleanup or
|
||||
* end-of-processing tasks to be performed such as applying header changes
|
||||
|
||||
@@ -42,6 +42,27 @@ import static org.junit.Assert.assertSame;
|
||||
*/
|
||||
public class ServerHttpResponseTests {
|
||||
|
||||
@Test
|
||||
public void encodeUrlDefault() throws Exception {
|
||||
TestServerHttpResponse response = new TestServerHttpResponse();
|
||||
assertEquals("/foo", response.encodeUrl("/foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeUrlWithEncoder() throws Exception {
|
||||
TestServerHttpResponse response = new TestServerHttpResponse();
|
||||
response.registerUrlEncoder(s -> s + "?nonce=123");
|
||||
assertEquals("/foo?nonce=123", response.encodeUrl("/foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeUrlWithMultipleEncoders() throws Exception {
|
||||
TestServerHttpResponse response = new TestServerHttpResponse();
|
||||
response.registerUrlEncoder(s -> s + ";p=abc");
|
||||
response.registerUrlEncoder(s -> s + "?q=123");
|
||||
assertEquals("/foo;p=abc?q=123", response.encodeUrl("/foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeWith() throws Exception {
|
||||
TestServerHttpResponse response = new TestServerHttpResponse();
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.mock.http.server.reactive.test;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
@@ -49,6 +50,8 @@ public class MockServerHttpResponse implements ServerHttpResponse {
|
||||
|
||||
private final MultiValueMap<String, ResponseCookie> cookies = new LinkedMultiValueMap<>();
|
||||
|
||||
private Function<String, String> urlEncoder = url -> url;
|
||||
|
||||
private Flux<DataBuffer> body;
|
||||
|
||||
private Flux<Publisher<DataBuffer>> bodyWithFlushes;
|
||||
@@ -77,6 +80,16 @@ public class MockServerHttpResponse implements ServerHttpResponse {
|
||||
return this.cookies;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encodeUrl(String url) {
|
||||
return (this.urlEncoder != null ? this.urlEncoder.apply(url) : url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerUrlEncoder(Function<String, String> encoder) {
|
||||
this.urlEncoder = (this.urlEncoder != null ? this.urlEncoder.andThen(encoder) : encoder);
|
||||
}
|
||||
|
||||
public Publisher<DataBuffer> getBody() {
|
||||
return this.body;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user