Skip to content
Open
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 @@ -47,12 +47,19 @@ public final class MockServerWebExchange extends DefaultServerWebExchange {

private MockServerWebExchange(
MockServerHttpRequest request, @Nullable WebSessionManager sessionManager,
@Nullable ApplicationContext applicationContext, @Nullable Principal principal) {
@Nullable ApplicationContext applicationContext , @Nullable Principal principal) {

this(request, sessionManager, applicationContext, null, principal);
}

private MockServerWebExchange(
MockServerHttpRequest request, @Nullable WebSessionManager sessionManager,
@Nullable ApplicationContext applicationContext , @Nullable Boolean defaultHtmlEscape, @Nullable Principal principal) {

super(request, new MockServerHttpResponse(),
sessionManager != null ? sessionManager : new DefaultWebSessionManager(),
ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver(),
applicationContext);
applicationContext , defaultHtmlEscape);

this.principalMono = (principal != null) ? Mono.just(principal) : Mono.empty();
}
Expand Down Expand Up @@ -125,6 +132,8 @@ public static class Builder {

private @Nullable ApplicationContext applicationContext;

private @Nullable Boolean defaultHtmlEscape;

private @Nullable Principal principal;

public Builder(MockServerHttpRequest request) {
Expand Down Expand Up @@ -163,6 +172,18 @@ public Builder applicationContext(ApplicationContext applicationContext) {
return this;
}

/**
* Set the default HTML escape setting for the exchange.
* @param defaultHtmlEscape whether to enable default HTML escaping,
* or {@code null} if not configured
* @return this builder
* @since 7.0
*/
public Builder defaultHtmlEscape(@Nullable Boolean defaultHtmlEscape) {
this.defaultHtmlEscape = defaultHtmlEscape;
return this;
}

/**
* Provide a user to associate with the exchange.
* @param principal the principal to use
Expand All @@ -178,7 +199,7 @@ public Builder principal(@Nullable Principal principal) {
*/
public MockServerWebExchange build() {
return new MockServerWebExchange(
this.request, this.sessionManager, this.applicationContext, this.principal);
this.request, this.sessionManager, this.applicationContext, this.defaultHtmlEscape, this.principal);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,15 @@ default Mono<Void> cleanupMultipart() {
*/
@Nullable ApplicationContext getApplicationContext();

/**
* Return the default HTML escape setting available for the current request,
* or {@code null} if no default was configured at the handler level.
* @return whether default HTML escaping is enabled, or {@code null} if not configured
* @since 7.0
* @see org.springframework.web.server.adapter.WebHttpHandlerBuilder#defaultHtmlEscape(boolean)
*/
@Nullable Boolean getDefaultHtmlEscape();

/**
* Returns {@code true} if the one of the {@code checkNotModified} methods
* in this contract were used and they returned true.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ public LocaleContext getLocaleContext() {
return getDelegate().getApplicationContext();
}

@Override
public @Nullable Boolean getDefaultHtmlEscape() {
return getDelegate().getDefaultHtmlEscape();
}

@Override
public Mono<MultiValueMap<String, String>> getFormData() {
return getDelegate().getFormData();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ public class DefaultServerWebExchange implements ServerWebExchange {

private final @Nullable ApplicationContext applicationContext;

private final @Nullable Boolean defaultHtmlEscape;

private volatile boolean notModified;

private Function<String, String> urlTransformer = url -> url;
Expand All @@ -114,12 +116,19 @@ public DefaultServerWebExchange(ServerHttpRequest request, ServerHttpResponse re
WebSessionManager sessionManager, ServerCodecConfigurer codecConfigurer,
LocaleContextResolver localeContextResolver) {

this(request, response, sessionManager, codecConfigurer, localeContextResolver, null);
this(request, response, sessionManager, codecConfigurer, localeContextResolver, null , null);
}

public DefaultServerWebExchange(ServerHttpRequest request, ServerHttpResponse response,
WebSessionManager sessionManager, ServerCodecConfigurer codecConfigurer,
LocaleContextResolver localeContextResolver , @Nullable ApplicationContext applicationContext) {

this(request, response, sessionManager, codecConfigurer, localeContextResolver, applicationContext , null);
}

protected DefaultServerWebExchange(ServerHttpRequest request, ServerHttpResponse response,
WebSessionManager sessionManager, ServerCodecConfigurer codecConfigurer,
LocaleContextResolver localeContextResolver, @Nullable ApplicationContext applicationContext) {
LocaleContextResolver localeContextResolver, @Nullable ApplicationContext applicationContext , @Nullable Boolean defaultHtmlEscape) {

Assert.notNull(request, "'request' is required");
Assert.notNull(response, "'response' is required");
Expand All @@ -137,6 +146,7 @@ protected DefaultServerWebExchange(ServerHttpRequest request, ServerHttpResponse
this.formDataMono = initFormData(request, codecConfigurer, getLogPrefix());
this.multipartDataMono = initMultipartData(codecConfigurer, getLogPrefix());
this.applicationContext = applicationContext;
this.defaultHtmlEscape = defaultHtmlEscape;

if (request instanceof AbstractServerHttpRequest abstractServerHttpRequest) {
abstractServerHttpRequest.setAttributesSupplier(() -> this.attributes);
Expand Down Expand Up @@ -278,6 +288,11 @@ public LocaleContext getLocaleContext() {
return this.applicationContext;
}

@Override
public @Nullable Boolean getDefaultHtmlEscape() {
return this.defaultHtmlEscape;
}

@Override
public boolean isNotModified() {
return this.notModified;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ public class HttpWebHandlerAdapter extends WebHandlerDecorator implements HttpHa

private @Nullable ApplicationContext applicationContext;

private @Nullable Boolean defaultHtmlEscape;

/** Whether to log potentially sensitive info (form data at DEBUG, headers at TRACE). */
private boolean enableLoggingRequestDetails = false;

Expand Down Expand Up @@ -250,6 +252,26 @@ public void setApplicationContext(ApplicationContext applicationContext) {
return this.applicationContext;
}

/**
* Configure a default HTML escape setting to apply to every
* {@link org.springframework.web.server.ServerWebExchange} created
* by this adapter.
* @param defaultHtmlEscape whether to enable default HTML escaping
* @since 7.0
*/
public void setDefaultHtmlEscape(Boolean defaultHtmlEscape) {
this.defaultHtmlEscape = defaultHtmlEscape;
}

/**
* Return the configured default HTML escape setting,
* or {@code null} if not configured.
* @since 7.0
*/
public @Nullable Boolean getDefaultHtmlEscape() {
return this.defaultHtmlEscape;
}

/**
* This method must be invoked after all properties have been set to
* complete initialization.
Expand Down Expand Up @@ -300,7 +322,7 @@ public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response)

protected ServerWebExchange createExchange(ServerHttpRequest request, ServerHttpResponse response) {
return new DefaultServerWebExchange(request, response, this.sessionManager,
getCodecConfigurer(), getLocaleContextResolver(), this.applicationContext);
getCodecConfigurer(), getLocaleContextResolver(), this.applicationContext , this.defaultHtmlEscape);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ public final class WebHttpHandlerBuilder {

private final List<WebExceptionHandler> exceptionHandlers = new ArrayList<>();

private @Nullable Boolean defaultHtmlEscape;

private @Nullable Function<HttpHandler, HttpHandler> httpHandlerDecorator;

private @Nullable WebSessionManager sessionManager;
Expand Down Expand Up @@ -130,6 +132,7 @@ private WebHttpHandlerBuilder(WebHttpHandlerBuilder other) {
this.observationRegistry = other.observationRegistry;
this.observationConvention = other.observationConvention;
this.httpHandlerDecorator = other.httpHandlerDecorator;
this.defaultHtmlEscape = other.defaultHtmlEscape;
}


Expand Down Expand Up @@ -289,6 +292,26 @@ public boolean hasSessionManager() {
return (this.sessionManager != null);
}

/**
* Configure a default HTML escape setting to apply to the created
* {@link org.springframework.web.server.ServerWebExchange}.
* @param defaultHtmlEscape whether to enable default HTML escaping
* @return this builder
* @since 7.0
*/
public WebHttpHandlerBuilder defaultHtmlEscape(Boolean defaultHtmlEscape) {
this.defaultHtmlEscape = defaultHtmlEscape;
return this;
}

/**
* Return whether a default HTML escape setting has been configured.
* @since 7.0
*/
public boolean hasDefaultHtmlEscape() {
return (this.defaultHtmlEscape != null);
}

/**
* Configure the {@link ServerCodecConfigurer} to set on the {@code WebServerExchange}.
* @param codecConfigurer the codec configurer
Expand Down Expand Up @@ -424,6 +447,9 @@ public HttpHandler build() {
if (this.applicationContext != null) {
adapted.setApplicationContext(this.applicationContext);
}
if(this.defaultHtmlEscape != null) {
adapted.setDefaultHtmlEscape(this.defaultHtmlEscape);
}
adapted.afterPropertiesSet();

return (this.httpHandlerDecorator != null ? this.httpHandlerDecorator.apply(adapted) : adapted);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,48 @@ void cloneWithApplicationContext() {
assertThat(((HttpWebHandlerAdapter) builder.clone().build()).getApplicationContext()).isSameAs(context);
}

@Test
void defaultHtmlEscape() {
HttpHandler httpHandler = WebHttpHandlerBuilder
.webHandler(exchange -> Mono.empty())
.defaultHtmlEscape(true)
.build();

assertThat(httpHandler).isInstanceOf(HttpWebHandlerAdapter.class);
assertThat(((HttpWebHandlerAdapter) httpHandler).getDefaultHtmlEscape()).isTrue();
}

@Test
void defaultHtmlEscapeSetToFalse() {
HttpHandler httpHandler = WebHttpHandlerBuilder
.webHandler(exchange -> Mono.empty())
.defaultHtmlEscape(false)
.build();

assertThat(httpHandler).isInstanceOf(HttpWebHandlerAdapter.class);
assertThat(((HttpWebHandlerAdapter) httpHandler).getDefaultHtmlEscape()).isFalse();
}

@Test
void defaultHtmlEscapeNotConfigured() {
HttpHandler httpHandler = WebHttpHandlerBuilder
.webHandler(exchange -> Mono.empty())
.build();

assertThat(httpHandler).isInstanceOf(HttpWebHandlerAdapter.class);
assertThat(((HttpWebHandlerAdapter) httpHandler).getDefaultHtmlEscape()).isNull();
}

@Test
void cloneWithDefaultHtmlEscape() {
WebHttpHandlerBuilder builder = WebHttpHandlerBuilder
.webHandler(exchange -> Mono.empty())
.defaultHtmlEscape(true);

assertThat(((HttpWebHandlerAdapter) builder.build()).getDefaultHtmlEscape()).isTrue();
assertThat(((HttpWebHandlerAdapter) builder.clone().build()).getDefaultHtmlEscape()).isTrue();
}

@Test
void httpHandlerDecorator() {
BiFunction<ServerHttpRequest, String, ServerHttpRequest> mutator =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@
public final class MockServerWebExchange extends DefaultServerWebExchange {


private MockServerWebExchange(MockServerHttpRequest request, WebSessionManager sessionManager) {
private MockServerWebExchange(MockServerHttpRequest request, WebSessionManager sessionManager, Boolean defaultHtmlEscape) {
super(request, new MockServerHttpResponse(), sessionManager,
ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver());
ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver() , null, defaultHtmlEscape);
}


Expand Down Expand Up @@ -101,6 +101,8 @@ public static class Builder {

private @Nullable WebSessionManager sessionManager;

private @Nullable Boolean defaultHtmlEscape;


public Builder(MockServerHttpRequest request) {
this.request = request;
Expand All @@ -127,12 +129,22 @@ public Builder sessionManager(WebSessionManager sessionManager) {
return this;
}

/**
* Configure the default HTML escaping setting for the exchange.
* @param defaultHtmlEscape the default HTML escaping setting to use
* @since 5.3.8
*/
public Builder defaultHtmlEscape(boolean defaultHtmlEscape) {
this.defaultHtmlEscape = defaultHtmlEscape;
return this;
}

/**
* Build the {@code MockServerWebExchange} instance.
*/
public MockServerWebExchange build() {
return new MockServerWebExchange(this.request,
this.sessionManager != null ? this.sessionManager : new DefaultWebSessionManager());
this.sessionManager != null ? this.sessionManager : new DefaultWebSessionManager(),this.defaultHtmlEscape);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,11 @@ public LocaleContext getLocaleContext() {
return this.delegate.getApplicationContext();
}

@Override
public @Nullable Boolean getDefaultHtmlEscape() {
return this.delegate.getDefaultHtmlEscape();
}

@Override
public boolean isNotModified() {
return this.delegate.isNotModified();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public RequestContext(ServerWebExchange exchange, Map<String, Object> model, Mes
tzaLocaleContext.getTimeZone() : null);
this.timeZone = (timeZone != null ? timeZone : TimeZone.getDefault());

this.defaultHtmlEscape = null; // TODO
this.defaultHtmlEscape = exchange.getDefaultHtmlEscape() != null ? exchange.getDefaultHtmlEscape() : Boolean.FALSE;
this.dataValueProcessor = dataValueProcessor;
}

Expand Down Expand Up @@ -150,7 +150,6 @@ public void changeLocale(Locale locale, TimeZone timeZone) {
/**
* (De)activate default HTML escaping for messages and errors, for the scope
* of this RequestContext.
* <p>TODO: currently no application-wide setting ...
*/
public void setDefaultHtmlEscape(boolean defaultHtmlEscape) {
this.defaultHtmlEscape = defaultHtmlEscape;
Expand All @@ -165,10 +164,11 @@ public boolean isDefaultHtmlEscape() {
}

/**
* Return the default HTML escape setting, differentiating between no default
* specified and an explicit value.
* @return whether default HTML escaping is enabled (null = no explicit default)
*/
* Return the default HTML escape setting, differentiating between no default
* specified and an explicit value.
* @return whether default HTML escaping is enabled (null = no explicit default
* specified at the handler level or the request context level)
*/
public @Nullable Boolean getDefaultHtmlEscape() {
return this.defaultHtmlEscape;
}
Expand Down
Loading