hanzhe-one opened a new pull request, #7920:
URL: https://github.com/apache/shenyu/pull/7920

   Fixes #7908.
   
   `AiResponseTransformerDecorator` decompressed a gzip upstream body into a 
`String` and used that decoded text for two purposes: building the model 
prompt, and — when the model failed or produced no usable body — writing the 
response body. The response headers were never touched, so the client got 
plaintext that still carried `Content-Encoding: gzip` and a `Content-Length` of 
the decoded text. A gzip-decoding client cannot read that fallback.
   
   ### Change
   
   Separate the prompt representation from the fallback wire representation:
   
   - Keep the original wire bytes next to the decoded prompt text; the decoded 
text is now only ever used to populate the prompt.
   - **Model error** (`onErrorResume`): write the original bytes back instead 
of the decoded `String`.
   - **Invalid or missing generated body**: write the original bytes back.
   - **Successful transformation**: the new body is always written as plain 
UTF-8, so an inherited `Content-Encoding` is removed rather than left to 
describe bytes it no longer matches. This covers a model that echoes the 
upstream `Content-Encoding: gzip` header into its generated headers.
   - Both fallbacks go through one `writeOriginalResponse` helper, which writes 
via `super.writeWith` so the upstream headers and status are preserved exactly.
   
   ### Tests
   
   Four regressions in `AiResponseTransformerPluginTest`, each asserting the 
client-visible bytes and headers:
   
   | Case | Expectation |
   | --- | --- |
   | gzip upstream, model error | original gzip bytes returned, 
`Content-Encoding: gzip` kept, gunzips to the upstream JSON |
   | gzip upstream, invalid generated body | same |
   | uncompressed upstream, model error | original bytes returned, no 
`Content-Encoding` |
   | gzip upstream, successful transformation | plain UTF-8 body, 
`Content-Encoding` removed |
   
   The gzip cases fail on the current code exactly as the issue reports — 
`array lengths differ, expected: <40> but was: <20>`, i.e. the 20-byte decoded 
text was returned under the gzip header — and the uncompressed control passes 
both before and after. All 68 tests in `shenyu-plugin-ai-response-transformer` 
pass with checkstyle; the `-am` build additionally runs 
`shenyu-plugin-ai-common`, where 
`OpenAiModelFactoryTest`/`DeepSeekModelFactoryTest` fail on this machine with 
`Unable to establish loopback connection` (NIO loopback is broken locally), 
unrelated to this change.
   
   ### Not in scope
   
   - #6811 (Inflater/resource closure) and #6756 (successful-output header 
mutation timing) are separate defects and are untouched here.
   - Whether the transformer should re-compress a transformed body when the 
client sent `Accept-Encoding: gzip` is a behavior question, not a correctness 
one; this PR only makes sure the headers never misdescribe the bytes actually 
written.
   
   - [x] I have read the [contribution 
guidelines](https://shenyu.apache.org/community/contributor-guide).
   - [x] I submit test cases (unit or integration tests) that back your changes.
   - [ ] Your local test passed `./mvnw clean install 
-Dmaven.javadoc.skip=true` (full build not run; module tests + checkstyle pass).
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to