[Website] Use content-type: application/octet-stream for CORS proxy requests#3364
Merged
[Website] Use content-type: application/octet-stream for CORS proxy requests#3364
content-type: application/octet-stream for CORS proxy requests#3364Conversation
When PHP receives a multipart/form-data POST request, it automatically parses the body into $_POST and $_FILES, emptying php://input. If file uploads are disabled or fail on the production server, both $_POST and $_FILES end up empty, and the proxy falls back to reading from the already-empty php://input. This causes curl to fail with "client read function EOF fail, only 0/N of needed bytes read". The fix wraps the Content-Type header before sending through the CORS proxy: multipart/form-data is replaced with application/octet-stream (which PHP doesn't auto-parse), and the original Content-Type is stored in X-Cors-Proxy-Content-Type. The proxy restores the original Content-Type for the outgoing curl request to the target server.
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes multipart/form-data POST bodies being lost when retrying requests via the PHP CORS proxy by preventing PHP from auto-parsing multipart requests and ensuring the proxy forwards the raw body correctly.
Changes:
- Wrap
multipart/form-dataContent-Type asapplication/octet-stream(and preserve original inx-cors-proxy-content-type) before proxying. - Restore the original
Content-Typein the PHP proxy while blocking the internal wrapper header from being forwarded. - Add a unit test covering Content-Type wrapping and body preservation on the proxy retry path.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| packages/playground/php-cors-proxy/cors-proxy.php | Accepts the new wrapper header, prevents it from being forwarded, and restores the original Content-Type for outgoing curl requests. |
| packages/php-wasm/web-service-worker/src/fetch-with-cors-proxy.ts | Wraps multipart Content-Type and buffers request bodies before proxying to avoid streaming/body-consumption issues. |
| packages/php-wasm/web-service-worker/src/fetch-with-cors-proxy.spec.ts | Adds coverage ensuring Content-Type wrapping and request body integrity during proxy retry. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
packages/php-wasm/web-service-worker/src/fetch-with-cors-proxy.ts
Outdated
Show resolved
Hide resolved
… omission Reject X-Cors-Proxy-Content-Type values containing CR/LF characters to prevent header injection toward the upstream server. Use explicit null check instead of truthiness. Add comment explaining why init is not forwarded to duplexSafeFetch in the retry path.
The mock CORS proxy in the test needs to restore X-Cors-Proxy-Content-Type back to Content-Type when forwarding to the target, matching the behavior of the real PHP CORS proxy.
Move body buffering from the CORS proxy catch block into duplexSafeFetch so it applies universally. This avoids duplex streaming issues for all protocols and ensures the CORS proxy always receives a fully buffered body.
Direct requests (localhost, no-proxy HTTPS) now pass through to fetch() without buffering. Only CORS proxy retries buffer the body. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Streaming bodies over HTTP/1.1 fail in Chrome due to ALPN negotiation. Buffer only when the CORS proxy URL uses http:// (dev server), not always. Also fix cloneRequest to properly pass through body overrides.
content-type: application/octet-stream for CORS proxy requests
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When sending requests through the CORS proxy, PHP runtime automatically parses the
multipart/form-databody into$_POST/$_FILES, emptyingphp://inputand removing our ability to pass through the unchanged request body.This PR:
application/octet-streamX-Cors-Proxy-Content-TypeduplexSafeFetchfunction. We only buffer when sending to the local dev server's CORS proxy. It turns out that change was misguided and we can actually send streamed request bodies to the production CORS proxy.Deployment note
The Playground changes and the CORS proxy changes must be deployed at the same time.
Test plan
npx nx test php-wasm-web-service-worker— all tests pass including Content-Type wrapping and body buffering testsnpx nx test playground-php-cors-proxy— CORS proxy tests pass