Skip to content

WebFlux RequestContext should support responseEncodedHtmlEscape like Spring MVC #36716

@husseinvr97

Description

@husseinvr97

Background

Spring MVC's RequestContext has had two HTML escape flags since Spring 4.1.2 (see SPR-12350 / #16955):

  • defaultHtmlEscape — the master switch; controls whether escaping happens at all
  • responseEncodedHtmlEscape — controls which HtmlUtils.htmlEscape() overload is used when escaping is active

PR #36400 (7.0.6) wired defaultHtmlEscape into WebFlux: WebHttpHandlerBuilderHttpWebHandlerAdapterServerWebExchange.HTML_ESCAPE_ATTRIBUTE → WebFlux RequestContext. That closes half the story. responseEncodedHtmlEscape was not included and remains completely absent from WebFlux.

What responseEncodedHtmlEscape does

When defaultHtmlEscape=true, the two flags combine as follows (from HtmlEscapingAwareTag):

if (isHtmlEscape()) {
    if (isResponseEncodedHtmlEscape()) {
        out = HtmlUtils.htmlEscape(content, response.getCharacterEncoding()); // encoding-aware
    } else {
        out = HtmlUtils.htmlEscape(content); // ISO-8859-1, escapes everything
    }
}

The difference matters in practice. Given the string "café" with a UTF-8 response:

Configuration Output
defaultHtmlEscape=false café
defaultHtmlEscape=true, responseEncodedHtmlEscape=false café <b>
defaultHtmlEscape=true, responseEncodedHtmlEscape=true café <b>

With a UTF-8 response, the encoding-aware path only escapes the 5 XML-significant characters and lets native UTF-8 characters pass through unchanged. The one-arg overload converts them to HTML entities unnecessarily. MVC's default for responseEncodedHtmlEscape falls back to true, so MVC apps automatically get the correct behavior. WebFlux apps with defaultHtmlEscape=true currently always take the ISO-8859-1 path because the second flag does not exist.

Proposed solution

Mirror the exact pattern from PR #36400 across the same four files:

  1. ServerWebExchange — add constant RESPONSE_ENCODED_HTML_ESCAPE_ATTRIBUTE

  2. WebHttpHandlerBuilder — add field and builder method responseEncodedHtmlEscape

  3. HttpWebHandlerAdapter — add field, setter, and stamp onto exchange in createExchange()

  4. WebFlux RequestContext — add field, read from exchange in constructor, expose isResponseEncodedHtmlEscape() and getResponseEncodedHtmlEscape(), and use an encoding-aware escape helper

The one difference from MVC is how the response charset is resolved. MVC calls response.getCharacterEncoding(). In WebFlux the equivalent is exchange.getResponse().getHeaders().getContentType().getCharset() with a UTF-8 fallback, which is consistent with how charset is resolved elsewhere in the framework. The default for isResponseEncodedHtmlEscape() falls back to true when unset, matching MVC exactly. No breaking change.

I implemented the defaultHtmlEscape wiring in PR #36400 and I'm prepared to open a PR and implement this follow-up across the same files

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions