diff options
author | Mario <mario@mariovavti.com> | 2019-11-10 14:18:18 +0100 |
---|---|---|
committer | Mario <mario@mariovavti.com> | 2019-11-10 14:18:18 +0100 |
commit | e1b923ab7d9070631b9bcf24fe1c42678f827169 (patch) | |
tree | 402fc0be56a0000701d969697ba1f271a66b8413 /vendor/sabre/http/lib/Sapi.php | |
parent | bed9876d68ac72a27f3c05fa3ed5c4ccad39b72e (diff) | |
parent | 580c3f4ffe9608d2beb56d418c68b3b112420e76 (diff) | |
download | volse-hubzilla-e1b923ab7d9070631b9bcf24fe1c42678f827169.tar.gz volse-hubzilla-e1b923ab7d9070631b9bcf24fe1c42678f827169.tar.bz2 volse-hubzilla-e1b923ab7d9070631b9bcf24fe1c42678f827169.zip |
Merge branch 'cherry-pick-6685381f' into 'dev'
another bulk of composer updates
See merge request hubzilla/core!1781
Diffstat (limited to 'vendor/sabre/http/lib/Sapi.php')
-rw-r--r-- | vendor/sabre/http/lib/Sapi.php | 141 |
1 files changed, 87 insertions, 54 deletions
diff --git a/vendor/sabre/http/lib/Sapi.php b/vendor/sabre/http/lib/Sapi.php index 054380e73..80254f3f3 100644 --- a/vendor/sabre/http/lib/Sapi.php +++ b/vendor/sabre/http/lib/Sapi.php @@ -1,9 +1,13 @@ <?php +declare(strict_types=1); + namespace Sabre\HTTP; +use InvalidArgumentException; + /** - * PHP SAPI + * PHP SAPI. * * This object is responsible for: * 1. Constructing a Request object based on the current HTTP request sent to @@ -28,56 +32,85 @@ namespace Sabre\HTTP; * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License */ -class Sapi { - +class Sapi +{ /** * This static method will create a new Request object, based on the * current PHP request. - * - * @return Request */ - static function getRequest() { + public static function getRequest(): Request + { + $serverArr = $_SERVER; + + if ('cli' === PHP_SAPI) { + // If we're running off the CLI, we're going to set some default + // settings. + $serverArr['REQUEST_URI'] = $_SERVER['REQUEST_URI'] ?? '/'; + $serverArr['REQUEST_METHOD'] = $_SERVER['REQUEST_METHOD'] ?? 'CLI'; + } - $r = self::createFromServerArray($_SERVER); + $r = self::createFromServerArray($serverArr); $r->setBody(fopen('php://input', 'r')); $r->setPostData($_POST); - return $r; + return $r; } /** * Sends the HTTP response back to a HTTP client. * * This calls php's header() function and streams the body to php://output. - * - * @param ResponseInterface $response - * @return void */ - static function sendResponse(ResponseInterface $response) { - - header('HTTP/' . $response->getHttpVersion() . ' ' . $response->getStatus() . ' ' . $response->getStatusText()); + public static function sendResponse(ResponseInterface $response) + { + header('HTTP/'.$response->getHttpVersion().' '.$response->getStatus().' '.$response->getStatusText()); foreach ($response->getHeaders() as $key => $value) { - foreach ($value as $k => $v) { - if ($k === 0) { - header($key . ': ' . $v); + if (0 === $k) { + header($key.': '.$v); } else { - header($key . ': ' . $v, false); + header($key.': '.$v, false); } } - } $body = $response->getBody(); - if (is_null($body)) return; + if (null === $body) { + return; + } + + if (is_callable($body)) { + $body(); + + return; + } $contentLength = $response->getHeader('Content-Length'); - if ($contentLength !== null) { + if (null !== $contentLength) { $output = fopen('php://output', 'wb'); - if (is_resource($body) && get_resource_type($body) == 'stream') { - if (PHP_INT_SIZE !== 4){ + if (is_resource($body) && 'stream' == get_resource_type($body)) { + if (PHP_INT_SIZE > 4) { // use the dedicated function on 64 Bit systems - stream_copy_to_stream($body, $output, $contentLength); + // a workaround to make PHP more possible to use mmap based copy, see https://github.com/sabre-io/http/pull/119 + $left = (int) $contentLength; + // copy with 4MiB chunks + $chunk_size = 4 * 1024 * 1024; + stream_set_chunk_size($output, $chunk_size); + // If this is a partial response, flush the beginning bytes until the first position that is a multiple of the page size. + $contentRange = $response->getHeader('Content-Range'); + // Matching "Content-Range: bytes 1234-5678/7890" + if (null !== $contentRange && preg_match('/^bytes\s([0-9]*)-([0-9]*)\//i', $contentRange, $matches) && '' !== $matches[1]) { + // 4kB should be the default page size on most architectures + $pageSize = 4096; + $offset = (int) $matches[1]; + $delta = ($offset % $pageSize) > 0 ? ($pageSize - $offset % $pageSize) : 0; + if ($delta > 0) { + $left -= stream_copy_to_stream($body, $output, min($delta, $left)); + } + } + while ($left > 0) { + $left -= stream_copy_to_stream($body, $output, min($left, $chunk_size)); + } } else { // workaround for 32 Bit systems to avoid stream_copy_to_stream while (!feof($body)) { @@ -85,7 +118,7 @@ class Sapi { } } } else { - fwrite($output, $body, $contentLength); + fwrite($output, $body, (int) $contentLength); } } else { file_put_contents('php://output', $body); @@ -94,18 +127,16 @@ class Sapi { if (is_resource($body)) { fclose($body); } - } /** * This static method will create a new Request object, based on a PHP * $_SERVER array. * - * @param array $serverArray - * @return Request + * REQUEST_URI and REQUEST_METHOD are required. */ - static function createFromServerArray(array $serverArray) { - + public static function createFromServerArray(array $serverArray): Request + { $headers = []; $method = null; $url = null; @@ -115,61 +146,61 @@ class Sapi { $hostName = 'localhost'; foreach ($serverArray as $key => $value) { - switch ($key) { - - case 'SERVER_PROTOCOL' : - if ($value === 'HTTP/1.0') { + case 'SERVER_PROTOCOL': + if ('HTTP/1.0' === $value) { $httpVersion = '1.0'; + } elseif ('HTTP/2.0' === $value) { + $httpVersion = '2.0'; } break; - case 'REQUEST_METHOD' : + case 'REQUEST_METHOD': $method = $value; break; - case 'REQUEST_URI' : + case 'REQUEST_URI': $url = $value; break; // These sometimes show up without a HTTP_ prefix - case 'CONTENT_TYPE' : + case 'CONTENT_TYPE': $headers['Content-Type'] = $value; break; - case 'CONTENT_LENGTH' : + case 'CONTENT_LENGTH': $headers['Content-Length'] = $value; break; // mod_php on apache will put credentials in these variables. // (fast)cgi does not usually do this, however. - case 'PHP_AUTH_USER' : + case 'PHP_AUTH_USER': if (isset($serverArray['PHP_AUTH_PW'])) { - $headers['Authorization'] = 'Basic ' . base64_encode($value . ':' . $serverArray['PHP_AUTH_PW']); + $headers['Authorization'] = 'Basic '.base64_encode($value.':'.$serverArray['PHP_AUTH_PW']); } break; // Similarly, mod_php may also screw around with digest auth. - case 'PHP_AUTH_DIGEST' : - $headers['Authorization'] = 'Digest ' . $value; + case 'PHP_AUTH_DIGEST': + $headers['Authorization'] = 'Digest '.$value; break; // Apache may prefix the HTTP_AUTHORIZATION header with // REDIRECT_, if mod_rewrite was used. - case 'REDIRECT_HTTP_AUTHORIZATION' : + case 'REDIRECT_HTTP_AUTHORIZATION': $headers['Authorization'] = $value; break; - case 'HTTP_HOST' : + case 'HTTP_HOST': $hostName = $value; $headers['Host'] = $value; break; - case 'HTTPS' : - if (!empty($value) && $value !== 'off') { + case 'HTTPS': + if (!empty($value) && 'off' !== $value) { $protocol = 'https'; } break; - default : - if (substr($key, 0, 5) === 'HTTP_') { + default: + if ('HTTP_' === substr($key, 0, 5)) { // It's a HTTP header // Normalizing it to be prettier @@ -182,21 +213,23 @@ class Sapi { // Turning spaces into dashes. $header = str_replace(' ', '-', $header); $headers[$header] = $value; - } break; - - } + } + if (null === $url) { + throw new InvalidArgumentException('The _SERVER array must have a REQUEST_URI key'); } + if (null === $method) { + throw new InvalidArgumentException('The _SERVER array must have a REQUEST_METHOD key'); + } $r = new Request($method, $url, $headers); $r->setHttpVersion($httpVersion); $r->setRawServerData($serverArray); - $r->setAbsoluteUrl($protocol . '://' . $hostName . $url); - return $r; + $r->setAbsoluteUrl($protocol.'://'.$hostName.$url); + return $r; } - } |