harshkha3417 opened a new pull request, #7822:
URL: https://github.com/apache/shenyu/pull/7822
Fixes #7807.
### Motivation
When ShenYu Admin runs in cluster mode, follower nodes forward requests to
the master node via `ClusterForwardFilter`. Previously,
`copyHeaders(responseEntity.getHeaders(), response)` blindly copied all
response headers from the master directly into the client-facing
`HttpServletResponse`.
Because the master node responds with chunked transfer encoding
(`Transfer-Encoding: chunked`), which `RestTemplate` decodes into raw bytes:
1. When clients send `Connection: close`, the follower emits
`Transfer-Encoding: chunked` in the response headers while Tomcat emits an
unchunked stream. HTTP clients fail when trying to parse the unchunked body as
chunk-length hex, crashing with `IncompleteRead` or protocol errors.
2. When clients send `Connection: keep-alive`, Tomcat chunk-encodes the
stream and adds its own framing headers, resulting in duplicated
`Transfer-Encoding: chunked` lines and duplicated `Connection: keep-alive,
keep-alive` values.
3. On the request side, client hop-by-hop headers and the follower's `Host`
header were forwarded to the master instead of letting the HTTP client handle
connection framing.
### Modifications
1. **Hop-by-Hop & Framing Header Filtering**:
- Filter standard hop-by-hop headers (`Connection`, `Keep-Alive`,
`Proxy-Authenticate`, `Proxy-Authorization`, `TE`, `Trailer`,
`Transfer-Encoding`, `Upgrade`) in both request and response copying in
`ClusterForwardFilter`.
- Dynamically inspect and strip any custom tokens listed in `Connection`
header values.
- On the response side, strip `Content-Length` from the master and
explicitly set `response.setContentLength(body.length)` based on actual decoded
payload bytes (omitted on 204 / 304).
- On the request side, strip client `Host`, `Content-Length`, and
hop-by-hop headers to allow `RestTemplate` to target the master correctly.
Support multi-valued request headers.
2. **Test Coverage**:
- Added `ClusterForwardFilterTest` covering:
- Unit tests for request header filtering (`Host`, `Connection`,
`Content-Length`, `Transfer-Encoding`, custom connection tokens).
- Unit tests for response header filtering (`Transfer-Encoding`,
`Connection`, `Keep-Alive`, `Content-Length`, custom tokens).
- Real HTTP integration test with master returning chunked encoding and
embedded Tomcat follower under `Connection: close` verifying complete read
without `IncompleteRead`, absence of `Transfer-Encoding: chunked`, and valid
`Content-Length`.
- Real HTTP integration test with embedded Tomcat follower under
`Connection: keep-alive` verifying absence of duplicate `Transfer-Encoding` and
duplicate `Connection` headers.
### Verification
- Passed `./mvnw test -pl shenyu-admin -Dtest=ClusterForwardFilterTest`
- Passed `./mvnw checkstyle:check -pl shenyu-admin` (0 violations)
- Passed `./mvnw apache-rat:check -pl shenyu-admin` (0 unapproved files)
--
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]