aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/sabre/http/lib/Sapi.php
diff options
context:
space:
mode:
authorMario <mario@mariovavti.com>2019-11-10 12:49:51 +0000
committerMario <mario@mariovavti.com>2019-11-10 14:10:03 +0100
commit580c3f4ffe9608d2beb56d418c68b3b112420e76 (patch)
tree82335d01179ac361d3f547a4b8e8c598d302e9f3 /vendor/sabre/http/lib/Sapi.php
parentd22766f458a8539a40a57f3946459a9be1f21cd6 (diff)
downloadvolse-hubzilla-580c3f4ffe9608d2beb56d418c68b3b112420e76.tar.gz
volse-hubzilla-580c3f4ffe9608d2beb56d418c68b3b112420e76.tar.bz2
volse-hubzilla-580c3f4ffe9608d2beb56d418c68b3b112420e76.zip
another bulk of composer updates
(cherry picked from commit 6685381fd8db507493c3d7c1793f8c05c681bbce)
Diffstat (limited to 'vendor/sabre/http/lib/Sapi.php')
-rw-r--r--vendor/sabre/http/lib/Sapi.php141
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;
}
-
}