-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
[6.1] - Fix JHTTP socket transport http version #43130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 6.1-dev
Are you sure you want to change the base?
Changes from 11 commits
bfbdc1f
5ee6f13
f3c262e
b034f84
3c13688
0412073
261fff0
be645ea
4b59389
f5a31e0
c6a54be
bc2e6b4
1e8a9f5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -86,7 +86,7 @@ public function request($method, UriInterface $uri, $data = null, array $headers | |
|
|
||
| // Build the request payload. | ||
| $request = []; | ||
| $request[] = strtoupper($method) . ' ' . ((empty($path)) ? '/' : $path) . ' HTTP/1.0'; | ||
| $request[] = strtoupper($method) . ' ' . ((empty($path)) ? '/' : $path) . ' HTTP/1.1'; | ||
| $request[] = 'Host: ' . $uri->getHost(); | ||
|
|
||
| // If an explicit user agent is given use it. | ||
|
|
@@ -101,6 +101,11 @@ public function request($method, UriInterface $uri, $data = null, array $headers | |
| } | ||
| } | ||
|
|
||
| // HTTP/1.1 streams using the socket wrapper require a Connection: close header | ||
| if (!isset($headers['Connection'])) { | ||
| $request[] = 'Connection: close'; | ||
| } | ||
|
|
||
| // Set any custom transport options | ||
| foreach ($this->getOption('transport.socket', []) as $value) { | ||
| $request[] = $value; | ||
|
|
@@ -174,6 +179,12 @@ protected function getResponse($content) | |
| $statusCode = (int) $code; | ||
| $verifiedHeaders = $this->processHeaders($headers); | ||
|
|
||
| // If we have a HTTP 1.1 Response with chunked encoding then we have to decode the message | ||
| if (\array_key_exists('Transfer-Encoding', $verifiedHeaders) && | ||
| $verifiedHeaders['Transfer-Encoding'][0] === 'chunked') { | ||
| $body = static::httpChunkedDecode($body); | ||
| } | ||
|
|
||
| $streamInterface = new StreamResponse('php://memory', 'rw'); | ||
| $streamInterface->write($body); | ||
|
|
||
|
|
@@ -275,4 +286,45 @@ public static function isSupported() | |
| { | ||
| return \function_exists('fsockopen') && \is_callable('fsockopen') && !Factory::getApplication()->get('proxy_enable'); | ||
| } | ||
|
|
||
| /** | ||
| * De-chunks a http 'transfer-encoding: chunked' message for when decoding a HTTP 1.1 server message. | ||
| * | ||
| * @param string $chunk The encoded message | ||
| * | ||
| * @return string The decoded message. If $chunk wasn't encoded properly it will be returned unmodified. | ||
| */ | ||
| public static function httpChunkedDecode(string $chunk): string | ||
| { | ||
| $pos = 0; | ||
| $len = \strlen($chunk); | ||
| $resp = ''; | ||
|
|
||
| while (($pos < $len) | ||
| && ($chunkLenHex = substr($chunk, $pos, ($newlineAt = strpos($chunk, "\n", $pos + 1)) - $pos))) { | ||
richard67 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (!static::isHex(rtrim($chunkLenHex))) { | ||
| trigger_error('Value is not properly chunk encoded', E_USER_WARNING); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess that should be an exception, right?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wasn't sure. When it's hard to find examples of when this might fail - hard to know if it can ever not be a hex in genuine page output. |
||
| return $chunk; | ||
| } | ||
|
|
||
| $pos = $newlineAt++; | ||
| $chunkLen = hexdec(rtrim($chunkLenHex, "\r\n")); | ||
| $resp .= substr($chunk, $pos + 1, $chunkLen); | ||
| $pos = strpos($chunk, "\n", $pos + $chunkLen) + 1; | ||
| } | ||
|
|
||
| return $resp; | ||
| } | ||
|
|
||
| /** | ||
| * Determine if a string can represent a number in hexadecimal | ||
| * | ||
| * @param string $hex | ||
| * | ||
| * @return boolean | ||
| */ | ||
| private static function isHex(string $hex): bool | ||
| { | ||
| return empty($hex) || (@preg_match("/^[a-f0-9]{2,}$/i", $hex) && !(\strlen($hex) & 1)); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.