Skip to content

Fix isCommitted() check in response header filters#4115

Open
chenws1012 wants to merge 1 commit into
spring-cloud:mainfrom
chenws1012:fix/response-header-iscommitted-check
Open

Fix isCommitted() check in response header filters#4115
chenws1012 wants to merge 1 commit into
spring-cloud:mainfrom
chenws1012:fix/response-header-iscommitted-check

Conversation

@chenws1012
Copy link
Copy Markdown

@chenws1012 chenws1012 commented Mar 25, 2026

What changes were proposed in this pull request?

Add isCommitted() check to response header filters to prevent
UnsupportedOperationException when response is already committed
by filters like RequestRateLimiter.

Fix versions affected

  • 4.0.x
  • 4.1.x
  • 4.2.x
  • 5.0.x

What is the issue related to this PR?

Fixes #3718

How was this patch tested?

Existing tests pass. The issue occurs when:

  1. RequestRateLimiter rejects a request (response committed)
  2. Post-processing response header filters try to modify headers

With this fix, filters check isCommitted() before modification.

Checklist

  • Code compiled successfully
  • Tests pass (./mvnw test)
  • Added documentation (if needed)
  • Commit message follows conventions

Add isCommitted() check to prevent UnsupportedOperationException
when modifying response headers after request is rejected by
filters like RequestRateLimiter.

Affected filters:
- SetResponseHeaderGatewayFilterFactory
- DedupeResponseHeaderGatewayFilterFactory
- SecureHeadersGatewayFilterFactory
- RewriteResponseHeaderGatewayFilterFactory
- RewriteLocationResponseHeaderGatewayFilterFactory

Fixes spring-cloudgh-3718

Signed-off-by: chenwenshun <chenwenshun@gmail.com>
@chenws1012 chenws1012 force-pushed the fix/response-header-iscommitted-check branch 2 times, most recently from f0e9f45 to 41a238a Compare March 25, 2026 07:42
@allo-zh
Copy link
Copy Markdown

allo-zh commented May 27, 2026

I am encountering the same problem in NettyRoutingFilter:

if (!filteredResponseHeaders.containsKey(HttpHeaders.TRANSFER_ENCODING)
       && filteredResponseHeaders.containsKey(HttpHeaders.CONTENT_LENGTH)) {
    // It is not valid to have both the transfer-encoding header and
    // the content-length header.
    // Remove the transfer-encoding header in the response if the
    // content-length header is present.
    response.getHeaders().remove(HttpHeaders.TRANSFER_ENCODING);
}

It would be great if this could also be included in the fix.
Any idea when this may be merged?

Copy link
Copy Markdown
Contributor

@ryanjbaxter ryanjbaxter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you submit this against the 4.3.x branch?

.then(Mono.fromRunnable(() -> dedupe(exchange.getResponse().getHeaders(), config)));
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
if (!exchange.getResponse().isCommitted()) {
dedupe(exchange.getResponse().getHeaders(), config);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to what AddResponseHeaderGatewayFilterFactory does it would be good to add the check to dedupe. Similar comment applies to the other filters

* fix for issue #3718 where filters like RequestRateLimiter commit the response, but
* post-processing response header filters still try to modify headers.
*
* @author issue #3718
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the author tag

* A filter that commits the response without calling chain.filter(), simulating
* behavior of filters like RequestRateLimiter when denying a request.
*/
static class CommitResponseFilter implements GatewayFilter {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably implement Ordered to make runs before the other filters.

Copy link
Copy Markdown
Member

@spencergibb spencergibb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without having investigated much, this looks like a bandaid to a bigger problem. I'd rather fix the root problem than cover it up. This looks to just do nothing, which seems worse to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Exception with RequestRateLimiter filter combined with response header filters

5 participants