[improve][proxy] Add regression tests for package upload with 'Expect: 100-continue'#25211
[improve][proxy] Add regression tests for package upload with 'Expect: 100-continue'#25211nodece merged 9 commits intoapache:masterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes proxy package uploads when clients send Expect: 100-continue by ensuring the proxy does not forward the Expect header to brokers, preventing Early EOF errors during large uploads.
Changes:
- Add request wrapping in
AdminProxyHandlerto strip theExpectheader whenExpect: 100-continueis present. - Add proxy package upload/download tests, including an
Expect: 100-continuescenario with a large multipart upload. - Improve mocked packages storage test implementation to read streams in chunks and add unit tests for large read/write correctness.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/AdminProxyHandler.java | Wraps requests that use Expect: 100-continue to prevent forwarding the Expect header to brokers. |
| pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/ProxyPackagesUploadTest.java | Adds integration coverage for uploading/downloading packages through the proxy, including Expect: 100-continue. |
| pulsar-proxy/pom.xml | Adds pulsar-package-core test-jar dependency for proxy tests using mock package storage. |
| pulsar-package-management/core/src/test/java/org/apache/pulsar/packages/management/core/MockedPackagesStorage.java | Refactors mocked storage writes to read streams in buffered chunks (supports large uploads). |
| pulsar-package-management/core/src/test/java/org/apache/pulsar/packages/management/core/MockedPackagesStorageTest.java | Adds a unit test validating mocked storage write/read correctness for large payloads. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/ProxyPackagesUploadTest.java
Show resolved
Hide resolved
pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/ProxyPackagesUploadTest.java
Outdated
Show resolved
Hide resolved
...core/src/test/java/org/apache/pulsar/packages/management/core/MockedPackagesStorageTest.java
Outdated
Show resolved
Hide resolved
...ent/core/src/test/java/org/apache/pulsar/packages/management/core/MockedPackagesStorage.java
Outdated
Show resolved
Hide resolved
...ent/core/src/test/java/org/apache/pulsar/packages/management/core/MockedPackagesStorage.java
Outdated
Show resolved
Hide resolved
pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/ProxyPackagesUploadTest.java
Outdated
Show resolved
Hide resolved
lhotari
left a comment
There was a problem hiding this comment.
- Added logic in
AdminProxyHandlerto detect requests with the
"Expect: 100-continue" header and wrap them using
NoExpectRequestWrapper, ensuring the header is not forwarded to the
broker and preventing Early EOF.- Introduced the
NoExpectRequestWrapperinner class to filter out the
"Expect" header from incoming requests.
I'm not sure if this is the correct approach. Expect: 100-continue is related to Transfer-Encoding: Chunked. Usually Transfer-Encoding: Chunked is used when Content-Length header isn't set due to the size of the body being unknown when the request is started.
While upgrading Jetty from 9.x to 12.x, I noticed that ProxyContinueProtocolHandler was missing from AdminProxyHandler:
A similar change should be implemented in branch-4.1, branch-4.0 and branch-3.0 to fix the Transfer-Encoding: Chunked and Expect: 100-continue support.
In addition, if httpMaxRequestSize is set in configuration, that would block Transfer-Encoding: Chunked:
I checked this claim that I made. It's not correct. |
The reason why this doesn't make sense is that the client won't be sending a body when the request contains |
|
Both the jetty 9.x and 12.x have this issue. |
|
Now, the client sent "Expect: 100-continue". Based on curl verbose output, it seems Jetty responds with "100 Continue" automatically. |
|
I will try to use the ProxyContinueProtocolHandler tomorrow. |
One possible approach would be to change the |
…and maintainability
|
Thanks for the suggestion, and I agree that this is a better and cleaner approach. After validating the behavior with packet captures, I realized that my previous change only guarantees correct handling of Your proposal to have |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 8 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/ProxyPackagesUploadTest.java
Show resolved
Hide resolved
pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/AdminProxyHandler.java
Show resolved
Hide resolved
pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/ProxyPackagesUploadTest.java
Show resolved
Hide resolved
pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/AdminProxyHandler.java
Outdated
Show resolved
Hide resolved
pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/AdminProxyHandler.java
Outdated
Show resolved
Hide resolved
...ent/core/src/test/java/org/apache/pulsar/packages/management/core/MockedPackagesStorage.java
Outdated
Show resolved
Hide resolved
...core/src/test/java/org/apache/pulsar/packages/management/core/MockedPackagesStorageTest.java
Outdated
Show resolved
Hide resolved
...core/src/test/java/org/apache/pulsar/packages/management/core/MockedPackagesStorageTest.java
Show resolved
Hide resolved
…/packages/management/core/MockedPackagesStorage.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…nProxyHandler.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…/packages/management/core/MockedPackagesStorageTest.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
...ent/core/src/test/java/org/apache/pulsar/packages/management/core/MockedPackagesStorage.java
Show resolved
Hide resolved
pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/ProxyPackagesUploadTest.java
Show resolved
Hide resolved
pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/ProxyPackagesUploadTest.java
Show resolved
Hide resolved
pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/AdminProxyHandler.java
Show resolved
Hide resolved
…: 100-continue' (apache#25211) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> (cherry picked from commit e8fedb1)
Motivation
This pull request introduces improvements and new tests for package management and proxy upload functionality in Pulsar.
Although PulsarAdmin (based on
async-http-client) does not send the'Expect: 100-continue'header by default, we observed in production that some HTTP clients (for examplecurlor other generic upload tools) do send thisheader when uploading large packages through the Pulsar proxy.
In older Pulsar versions, such requests may lead to Early EOF issues during package uploads through the proxy. Adding coverage for this scenario helps ensure that large uploads using
'Expect: 100-continue'work reliably andremain compatible with common HTTP clients.
Modifications
Package management improvements
MockedPackagesStorage.writeAsyncto read input streams using a buffer andByteArrayOutputStream, improving correctness for large files and for streams whereInputStream.available()is unreliable.MockedPackagesStorageTestto validate correct write and read behavior for large package data in the mocked storage implementation.Proxy upload tests
ProxyPackagesUploadTestto verify package upload and download through the Pulsar proxy and broker.'Expect: 100-continue'header to prevent regressions related to Early EOF issues observed in production.Codebase simplification
AdminProxyHandlerby reusing the HTTP client configuration from the superclass and customizing only the required protocol handlers, reducing code duplication and improving maintainability.Documentation
docdoc-requireddoc-not-neededdoc-complete