Skip to content

Commit 4f810db

Browse files
authored
[CORS Proxy] Support chunked encoding when running in Apache/Nginx/etc (#2114)
Adds support for `transfer-encoding: chunked` on Apache, Nginx, and other web servers. #2077 added support for `transfer-encoding: chunked` in a way that works on a local PHP dev server. The proxy manually chunks the output bytes and outputs each chunk's header, separator, body, and trailer. However, it doesn't work on playground.wordpress.net because the web server there handles the chunked encoding on its own. The bytes echoed by cors-proxy.php are treated as body bytes, which messes up the response body. This PR restricts the manual chunking to a local CLI dev server. ## Testing instructions Run cors-proxy.php in Apache or so and confirm that requesting resources served with chunked encoding works with this patch but not without it. One such URL is https://adamadam.blog/feed/.
1 parent 5fa2cfa commit 4f810db

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

packages/playground/php-cors-proxy/cors-proxy.php

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,33 @@
9797
};
9898

9999
function send_response_chunk($data) {
100-
global $is_chunked_response;
101-
if ($is_chunked_response) {
100+
if (should_send_as_chunked_response()) {
101+
// We need to manually chunk the response when running in the PHP
102+
// built-in server. It won't handle that for us.
102103
echo sprintf("%s\r\n%s\r\n", dechex(strlen($data)), $data);
103104
} else {
105+
// When running behing an Apache or Nginx or another webserver,
106+
// it will handle the chunking for us. Manually sending the chunk
107+
// header, \r\n separator, body, and \r\n trailer isn't just
108+
// unnecessary, but it would actually include those bytes in the
109+
// response body.
104110
echo $data;
105111
}
106112
@ob_flush();
107113
@flush();
108114
}
109115

116+
/**
117+
* We need to manually chunk the response when running the PHP
118+
* dev server AND the transfer-encoding header is set to chunked.
119+
*
120+
* Apache, Nginx, etc. will handle the chunking for us.
121+
*/
122+
function should_send_as_chunked_response() {
123+
global $is_chunked_response;
124+
return $is_chunked_response && php_sapi_name() === 'cli-server';
125+
}
126+
110127
// Pin the hostname resolution to an IP we've resolved earlier
111128
curl_setopt($ch, CURLOPT_RESOLVE, [
112129
"$host:80:$resolvedIp",
@@ -255,7 +272,9 @@ function(
255272
// Close cURL session
256273
curl_close($ch);
257274

258-
// Only send chunked transfer encoding footer if we're using chunked encoding
259-
if ($is_chunked_response) {
275+
// Only send chunked transfer encoding footer if we're using chunked encoding.
276+
// We need to manually send the footer when running in the PHP built-in server
277+
// because, unlike apache or nginx, it won't handle that for us.
278+
if (should_send_as_chunked_response()) {
260279
echo "0\r\n\r\n";
261280
}

0 commit comments

Comments
 (0)