Skip to content

Conversation

@thisishwan2
Copy link

Fixes GH-4025

Description

This PR addresses an issue where ModifyResponseBodyGatewayFilterFactory fails to handle Gzipped responses correctly when the configuration is set to use byte[].class.

Root Cause:

Currently, there is an optimization logic in extractBody and writeBody methods that explicitly skips decompression/compression if the target class is byte[]:

if (byte[].class.isAssignableFrom(inClass)) {
    return clientResponse.bodyToMono(inClass);
}

While this might have been intended for performance, it prevents users from modifying the actual payload logic when the response is Gzipped, as the filter passes raw compressed bytes to the rewrite function. This leads to parsing errors when the user code expects decompressed data.

Changes

Removed the if (byte[].class.isAssignableFrom(inClass)) check in both extractBody and writeBody methods.
Now, the filter consistently checks the Content-Encoding header and performs decompression/compression regardless of the target class type.

Verification

Added a new test case testModificationOfResponseBodyBytes in ModifyResponseBodyGatewayFilterFactoryGzipTests.
Verified that Gzipped responses are correctly decompressed, modified as strings, and recompressed even when inClass and outClass are set to byte[].

…ilterFactory

Fixes spring-cloudgh-4025

Signed-off-by: thisishwan2 <fill0006@naver.com>
@ryanjbaxter
Copy link
Contributor

I would rather investigate why GzipMessageBodyResolver is not working as the OP stated

@thisishwan2
Copy link
Author

@ryanjbaxter

I have investigated why the GzipMessageBodyResolver is not being triggered.
The GzipMessageBodyResolver is correctly registered, but it resides in the messageBodyDecoders map, which is specific to this gateway filter.

The problem is that the clientResponse.bodyToMono() call inside the if (byte[].class.isAssignableFrom(inClass)) block does not reference this map. It relies exclusively on the standard messageReaders configured in the WebFlux client.

Consequently, when the target class is byte[], the execution flow never reaches the logic that utilizes messageBodyDecoders. Instead, the request is intercepted by the standard ByteArrayDecoder (which ignores Gzip), resulting in the raw compressed bytes being returned without decompression.

Removing this if block forces the flow to proceed to the subsequent logic where messageBodyDecoders is actually checked, allowing GzipMessageBodyResolver to function as intended.

@ryanjbaxter
Copy link
Contributor

Why is ModifyResponseBodyGatewayFilterFactoryGzipTests passing then?

@thisishwan2
Copy link
Author

@ryanjbaxter

The reason ModifyResponseBodyGatewayFilterFactoryGzipTests.testModificationOfResponseBody() passes is that it explicitly configures the input type (inClass) as String.class, as shown here:

.filters(f -> f.modifyResponseBody(String.class, Map.class, ...))

Because inClass is String, the condition if (byte[].class.isAssignableFrom(inClass)) evaluates to false.

Consequently, the execution skips that problematic block and falls through to the subsequent logic. In this path, the code correctly utilizes the GzipMessageBodyResolver retrieved from messageBodyDecoders to handle the Gzip decompression.

The issue I am fixing is specific to cases where inClass is byte[], which gets trapped in that if block and bypasses the resolver.

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.

Issue with GatewayFilters and gzip

3 participants