aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/sabre/http/lib
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/sabre/http/lib')
-rw-r--r--vendor/sabre/http/lib/Auth/AWS.php134
-rw-r--r--vendor/sabre/http/lib/Auth/AbstractAuth.php36
-rw-r--r--vendor/sabre/http/lib/Auth/Basic.php25
-rw-r--r--vendor/sabre/http/lib/Auth/Bearer.php25
-rw-r--r--vendor/sabre/http/lib/Auth/Digest.php131
-rw-r--r--vendor/sabre/http/lib/Client.php325
-rw-r--r--vendor/sabre/http/lib/ClientException.php6
-rw-r--r--vendor/sabre/http/lib/ClientHttpException.php32
-rw-r--r--vendor/sabre/http/lib/HttpException.php9
-rw-r--r--vendor/sabre/http/lib/Message.php163
-rw-r--r--vendor/sabre/http/lib/MessageDecoratorTrait.php117
-rw-r--r--vendor/sabre/http/lib/MessageInterface.php73
-rw-r--r--vendor/sabre/http/lib/Request.php189
-rw-r--r--vendor/sabre/http/lib/RequestDecorator.php130
-rw-r--r--vendor/sabre/http/lib/RequestInterface.php73
-rw-r--r--vendor/sabre/http/lib/Response.php75
-rw-r--r--vendor/sabre/http/lib/ResponseDecorator.php42
-rw-r--r--vendor/sabre/http/lib/ResponseInterface.php19
-rw-r--r--vendor/sabre/http/lib/Sapi.php141
-rw-r--r--vendor/sabre/http/lib/URLUtil.php103
-rw-r--r--vendor/sabre/http/lib/Util.php74
-rw-r--r--vendor/sabre/http/lib/Version.php13
-rw-r--r--vendor/sabre/http/lib/functions.php183
23 files changed, 839 insertions, 1279 deletions
diff --git a/vendor/sabre/http/lib/Auth/AWS.php b/vendor/sabre/http/lib/Auth/AWS.php
index 5e176646a..ffda3cf15 100644
--- a/vendor/sabre/http/lib/Auth/AWS.php
+++ b/vendor/sabre/http/lib/Auth/AWS.php
@@ -1,11 +1,13 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP\Auth;
-use Sabre\HTTP\Util;
+use Sabre\HTTP;
/**
- * HTTP AWS Authentication handler
+ * HTTP AWS Authentication handler.
*
* Use this class to leverage amazon's AWS authentication header
*
@@ -13,24 +15,24 @@ use Sabre\HTTP\Util;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-class AWS extends AbstractAuth {
-
+class AWS extends AbstractAuth
+{
/**
- * The signature supplied by the HTTP client
+ * The signature supplied by the HTTP client.
*
* @var string
*/
private $signature = null;
/**
- * The accesskey supplied by the HTTP client
+ * The accesskey supplied by the HTTP client.
*
* @var string
*/
private $accessKey = null;
/**
- * An error code, if any
+ * An error code, if any.
*
* This value will be filled with one of the ERR_* constants
*
@@ -45,47 +47,45 @@ class AWS extends AbstractAuth {
const ERR_INVALIDSIGNATURE = 5;
/**
- * Gathers all information from the headers
+ * Gathers all information from the headers.
*
* This method needs to be called prior to anything else.
- *
- * @return bool
*/
- function init() {
-
+ public function init(): bool
+ {
$authHeader = $this->request->getHeader('Authorization');
+
+ if (null === $authHeader) {
+ $this->errorCode = self::ERR_NOAWSHEADER;
+
+ return false;
+ }
$authHeader = explode(' ', $authHeader);
- if ($authHeader[0] != 'AWS' || !isset($authHeader[1])) {
+ if ('AWS' !== $authHeader[0] || !isset($authHeader[1])) {
$this->errorCode = self::ERR_NOAWSHEADER;
- return false;
+
+ return false;
}
list($this->accessKey, $this->signature) = explode(':', $authHeader[1]);
return true;
-
}
/**
- * Returns the username for the request
- *
- * @return string
+ * Returns the username for the request.
*/
- function getAccessKey() {
-
+ public function getAccessKey(): string
+ {
return $this->accessKey;
-
}
/**
- * Validates the signature based on the secretKey
- *
- * @param string $secretKey
- * @return bool
+ * Validates the signature based on the secretKey.
*/
- function validate($secretKey) {
-
+ public function validate(string $secretKey): bool
+ {
$contentMD5 = $this->request->getHeader('Content-MD5');
if ($contentMD5) {
@@ -93,57 +93,53 @@ class AWS extends AbstractAuth {
$body = $this->request->getBody();
$this->request->setBody($body);
- if ($contentMD5 != base64_encode(md5($body, true))) {
+ if ($contentMD5 !== base64_encode(md5((string) $body, true))) {
// content-md5 header did not match md5 signature of body
$this->errorCode = self::ERR_MD5CHECKSUMWRONG;
+
return false;
}
-
}
- if (!$requestDate = $this->request->getHeader('x-amz-date'))
+ if (!$requestDate = $this->request->getHeader('x-amz-date')) {
$requestDate = $this->request->getHeader('Date');
+ }
- if (!$this->validateRFC2616Date($requestDate))
+ if (!$this->validateRFC2616Date((string) $requestDate)) {
return false;
+ }
$amzHeaders = $this->getAmzHeaders();
$signature = base64_encode(
$this->hmacsha1($secretKey,
- $this->request->getMethod() . "\n" .
- $contentMD5 . "\n" .
- $this->request->getHeader('Content-type') . "\n" .
- $requestDate . "\n" .
- $amzHeaders .
+ $this->request->getMethod()."\n".
+ $contentMD5."\n".
+ $this->request->getHeader('Content-type')."\n".
+ $requestDate."\n".
+ $amzHeaders.
$this->request->getUrl()
)
);
- if ($this->signature != $signature) {
-
+ if ($this->signature !== $signature) {
$this->errorCode = self::ERR_INVALIDSIGNATURE;
- return false;
+ return false;
}
return true;
-
}
-
/**
- * Returns an HTTP 401 header, forcing login
+ * Returns an HTTP 401 header, forcing login.
*
* This should be called when username and password are incorrect, or not supplied at all
- *
- * @return void
*/
- function requireLogin() {
-
+ public function requireLogin()
+ {
$this->response->addHeader('WWW-Authenticate', 'AWS');
$this->response->setStatus(401);
-
}
/**
@@ -154,17 +150,15 @@ class AWS extends AbstractAuth {
*
* This function also makes sure the Date header is within 15 minutes of the operating
* system date, to prevent replay attacks.
- *
- * @param string $dateHeader
- * @return bool
*/
- protected function validateRFC2616Date($dateHeader) {
-
- $date = Util::parseHTTPDate($dateHeader);
+ protected function validateRFC2616Date(string $dateHeader): bool
+ {
+ $date = HTTP\parseDate($dateHeader);
// Unknown format
if (!$date) {
$this->errorCode = self::ERR_INVALIDDATEFORMAT;
+
return false;
}
@@ -174,47 +168,40 @@ class AWS extends AbstractAuth {
// We allow 15 minutes around the current date/time
if ($date > $max || $date < $min) {
$this->errorCode = self::ERR_REQUESTTIMESKEWED;
+
return false;
}
- return $date;
-
+ return true;
}
/**
- * Returns a list of AMZ headers
- *
- * @return string
+ * Returns a list of AMZ headers.
*/
- protected function getAmzHeaders() {
-
+ protected function getAmzHeaders(): string
+ {
$amzHeaders = [];
$headers = $this->request->getHeaders();
foreach ($headers as $headerName => $headerValue) {
- if (strpos(strtolower($headerName), 'x-amz-') === 0) {
- $amzHeaders[strtolower($headerName)] = str_replace(["\r\n"], [' '], $headerValue[0]) . "\n";
+ if (0 === strpos(strtolower($headerName), 'x-amz-')) {
+ $amzHeaders[strtolower($headerName)] = str_replace(["\r\n"], [' '], $headerValue[0])."\n";
}
}
ksort($amzHeaders);
$headerStr = '';
foreach ($amzHeaders as $h => $v) {
- $headerStr .= $h . ':' . $v;
+ $headerStr .= $h.':'.$v;
}
return $headerStr;
-
}
/**
- * Generates an HMAC-SHA1 signature
- *
- * @param string $key
- * @param string $message
- * @return string
+ * Generates an HMAC-SHA1 signature.
*/
- private function hmacsha1($key, $message) {
-
+ private function hmacsha1(string $key, string $message): string
+ {
if (function_exists('hash_hmac')) {
return hash_hmac('sha1', $message, $key, true);
}
@@ -226,9 +213,8 @@ class AWS extends AbstractAuth {
$key = str_pad($key, $blocksize, chr(0x00));
$ipad = str_repeat(chr(0x36), $blocksize);
$opad = str_repeat(chr(0x5c), $blocksize);
- $hmac = pack('H*', sha1(($key ^ $opad) . pack('H*', sha1(($key ^ $ipad) . $message))));
- return $hmac;
+ $hmac = pack('H*', sha1(($key ^ $opad).pack('H*', sha1(($key ^ $ipad).$message))));
+ return $hmac;
}
-
}
diff --git a/vendor/sabre/http/lib/Auth/AbstractAuth.php b/vendor/sabre/http/lib/Auth/AbstractAuth.php
index ae45b3ee2..ada6bf0f0 100644
--- a/vendor/sabre/http/lib/Auth/AbstractAuth.php
+++ b/vendor/sabre/http/lib/Auth/AbstractAuth.php
@@ -1,5 +1,7 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP\Auth;
use Sabre\HTTP\RequestInterface;
@@ -14,60 +16,50 @@ use Sabre\HTTP\ResponseInterface;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-abstract class AbstractAuth {
-
+abstract class AbstractAuth
+{
/**
- * Authentication realm
+ * Authentication realm.
*
* @var string
*/
protected $realm;
/**
- * Request object
+ * Request object.
*
* @var RequestInterface
*/
protected $request;
/**
- * Response object
+ * Response object.
*
* @var ResponseInterface
*/
protected $response;
/**
- * Creates the object
- *
- * @param string $realm
- * @return void
+ * Creates the object.
*/
- function __construct($realm = 'SabreTooth', RequestInterface $request, ResponseInterface $response) {
-
+ public function __construct(string $realm = 'SabreTooth', RequestInterface $request, ResponseInterface $response)
+ {
$this->realm = $realm;
$this->request = $request;
$this->response = $response;
-
}
/**
* This method sends the needed HTTP header and statuscode (401) to force
* the user to login.
- *
- * @return void
*/
- abstract function requireLogin();
+ abstract public function requireLogin();
/**
- * Returns the HTTP realm
- *
- * @return string
+ * Returns the HTTP realm.
*/
- function getRealm() {
-
+ public function getRealm(): string
+ {
return $this->realm;
-
}
-
}
diff --git a/vendor/sabre/http/lib/Auth/Basic.php b/vendor/sabre/http/lib/Auth/Basic.php
index c263e3f9b..d04b4a811 100644
--- a/vendor/sabre/http/lib/Auth/Basic.php
+++ b/vendor/sabre/http/lib/Auth/Basic.php
@@ -1,5 +1,7 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP\Auth;
/**
@@ -15,25 +17,25 @@ namespace Sabre\HTTP\Auth;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-class Basic extends AbstractAuth {
-
+class Basic extends AbstractAuth
+{
/**
* This method returns a numeric array with a username and password as the
* only elements.
*
* If no credentials were found, this method returns null.
*
- * @return null|array
+ * @return array|null
*/
- function getCredentials() {
-
+ public function getCredentials()
+ {
$auth = $this->request->getHeader('Authorization');
if (!$auth) {
return null;
}
- if (strtolower(substr($auth, 0, 6)) !== 'basic ') {
+ if ('basic ' !== strtolower(substr($auth, 0, 6))) {
return null;
}
@@ -44,20 +46,15 @@ class Basic extends AbstractAuth {
}
return $credentials;
-
}
/**
* This method sends the needed HTTP header and statuscode (401) to force
* the user to login.
- *
- * @return void
*/
- function requireLogin() {
-
- $this->response->addHeader('WWW-Authenticate', 'Basic realm="' . $this->realm . '", charset="UTF-8"');
+ public function requireLogin()
+ {
+ $this->response->addHeader('WWW-Authenticate', 'Basic realm="'.$this->realm.'", charset="UTF-8"');
$this->response->setStatus(401);
-
}
-
}
diff --git a/vendor/sabre/http/lib/Auth/Bearer.php b/vendor/sabre/http/lib/Auth/Bearer.php
index eefdf11ee..988bb29d2 100644
--- a/vendor/sabre/http/lib/Auth/Bearer.php
+++ b/vendor/sabre/http/lib/Auth/Bearer.php
@@ -1,5 +1,7 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP\Auth;
/**
@@ -15,42 +17,37 @@ namespace Sabre\HTTP\Auth;
* @author François Kooman (fkooman@tuxed.net)
* @license http://sabre.io/license/ Modified BSD License
*/
-class Bearer extends AbstractAuth {
-
+class Bearer extends AbstractAuth
+{
/**
* This method returns a string with an access token.
*
* If no token was found, this method returns null.
*
- * @return null|string
+ * @return string|null
*/
- function getToken() {
-
+ public function getToken()
+ {
$auth = $this->request->getHeader('Authorization');
if (!$auth) {
return null;
}
- if (strtolower(substr($auth, 0, 7)) !== 'bearer ') {
+ if ('bearer ' !== strtolower(substr($auth, 0, 7))) {
return null;
}
return substr($auth, 7);
-
}
/**
* This method sends the needed HTTP header and statuscode (401) to force
* authentication.
- *
- * @return void
*/
- function requireLogin() {
-
- $this->response->addHeader('WWW-Authenticate', 'Bearer realm="' . $this->realm . '"');
+ public function requireLogin()
+ {
+ $this->response->addHeader('WWW-Authenticate', 'Bearer realm="'.$this->realm.'"');
$this->response->setStatus(401);
-
}
-
}
diff --git a/vendor/sabre/http/lib/Auth/Digest.php b/vendor/sabre/http/lib/Auth/Digest.php
index 4b3f0746f..dd35a0b74 100644
--- a/vendor/sabre/http/lib/Auth/Digest.php
+++ b/vendor/sabre/http/lib/Auth/Digest.php
@@ -1,12 +1,14 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP\Auth;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
/**
- * HTTP Digest Authentication handler
+ * HTTP Digest Authentication handler.
*
* Use this class for easy http digest authentication.
* Instructions:
@@ -27,10 +29,10 @@ use Sabre\HTTP\ResponseInterface;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-class Digest extends AbstractAuth {
-
+class Digest extends AbstractAuth
+{
/**
- * These constants are used in setQOP();
+ * These constants are used in setQOP();.
*/
const QOP_AUTH = 1;
const QOP_AUTHINT = 2;
@@ -42,28 +44,24 @@ class Digest extends AbstractAuth {
protected $qop = self::QOP_AUTH;
/**
- * Initializes the object
+ * Initializes the object.
*/
- function __construct($realm = 'SabreTooth', RequestInterface $request, ResponseInterface $response) {
-
+ public function __construct(string $realm = 'SabreTooth', RequestInterface $request, ResponseInterface $response)
+ {
$this->nonce = uniqid();
$this->opaque = md5($realm);
parent::__construct($realm, $request, $response);
-
}
/**
- * Gathers all information from the headers
+ * Gathers all information from the headers.
*
* This method needs to be called prior to anything else.
- *
- * @return void
*/
- function init() {
-
+ public function init()
+ {
$digest = $this->getDigest();
- $this->digestParts = $this->parseDigest($digest);
-
+ $this->digestParts = $this->parseDigest((string) $digest);
}
/**
@@ -78,115 +76,101 @@ class Digest extends AbstractAuth {
* QOP_AUTHINT ensures integrity of the request body, but this is not
* supported by most HTTP clients. QOP_AUTHINT also requires the entire
* request body to be md5'ed, which can put strains on CPU and memory.
- *
- * @param int $qop
- * @return void
*/
- function setQOP($qop) {
-
+ public function setQOP(int $qop)
+ {
$this->qop = $qop;
-
}
/**
* Validates the user.
*
* The A1 parameter should be md5($username . ':' . $realm . ':' . $password);
- *
- * @param string $A1
- * @return bool
*/
- function validateA1($A1) {
-
+ public function validateA1(string $A1): bool
+ {
$this->A1 = $A1;
- return $this->validate();
+ return $this->validate();
}
/**
* Validates authentication through a password. The actual password must be provided here.
* It is strongly recommended not store the password in plain-text and use validateA1 instead.
- *
- * @param string $password
- * @return bool
*/
- function validatePassword($password) {
+ public function validatePassword(string $password): bool
+ {
+ $this->A1 = md5($this->digestParts['username'].':'.$this->realm.':'.$password);
- $this->A1 = md5($this->digestParts['username'] . ':' . $this->realm . ':' . $password);
return $this->validate();
-
}
/**
- * Returns the username for the request
+ * Returns the username for the request.
+ * Returns null if there were none.
*
- * @return string
+ * @return string|null
*/
- function getUsername() {
-
- return $this->digestParts['username'];
-
+ public function getUsername()
+ {
+ return $this->digestParts['username'] ?? null;
}
/**
- * Validates the digest challenge
- *
- * @return bool
+ * Validates the digest challenge.
*/
- protected function validate() {
+ protected function validate(): bool
+ {
+ if (!is_array($this->digestParts)) {
+ return false;
+ }
- $A2 = $this->request->getMethod() . ':' . $this->digestParts['uri'];
+ $A2 = $this->request->getMethod().':'.$this->digestParts['uri'];
- if ($this->digestParts['qop'] == 'auth-int') {
+ if ('auth-int' === $this->digestParts['qop']) {
// Making sure we support this qop value
- if (!($this->qop & self::QOP_AUTHINT)) return false;
+ if (!($this->qop & self::QOP_AUTHINT)) {
+ return false;
+ }
// We need to add an md5 of the entire request body to the A2 part of the hash
$body = $this->request->getBody($asString = true);
$this->request->setBody($body);
- $A2 .= ':' . md5($body);
- } else {
-
- // We need to make sure we support this qop value
- if (!($this->qop & self::QOP_AUTH)) return false;
+ $A2 .= ':'.md5($body);
+ } elseif (!($this->qop & self::QOP_AUTH)) {
+ return false;
}
$A2 = md5($A2);
$validResponse = md5("{$this->A1}:{$this->digestParts['nonce']}:{$this->digestParts['nc']}:{$this->digestParts['cnonce']}:{$this->digestParts['qop']}:{$A2}");
- return $this->digestParts['response'] == $validResponse;
-
-
+ return $this->digestParts['response'] === $validResponse;
}
/**
- * Returns an HTTP 401 header, forcing login
+ * Returns an HTTP 401 header, forcing login.
*
* This should be called when username and password are incorrect, or not supplied at all
- *
- * @return void
*/
- function requireLogin() {
-
+ public function requireLogin()
+ {
$qop = '';
switch ($this->qop) {
- case self::QOP_AUTH :
+ case self::QOP_AUTH:
$qop = 'auth';
break;
- case self::QOP_AUTHINT :
+ case self::QOP_AUTHINT:
$qop = 'auth-int';
break;
- case self::QOP_AUTH | self::QOP_AUTHINT :
+ case self::QOP_AUTH | self::QOP_AUTHINT:
$qop = 'auth,auth-int';
break;
}
- $this->response->addHeader('WWW-Authenticate', 'Digest realm="' . $this->realm . '",qop="' . $qop . '",nonce="' . $this->nonce . '",opaque="' . $this->opaque . '"');
+ $this->response->addHeader('WWW-Authenticate', 'Digest realm="'.$this->realm.'",qop="'.$qop.'",nonce="'.$this->nonce.'",opaque="'.$this->opaque.'"');
$this->response->setStatus(401);
-
}
-
/**
* This method returns the full digest string.
*
@@ -196,23 +180,20 @@ class Digest extends AbstractAuth {
*
* @return mixed
*/
- function getDigest() {
-
+ public function getDigest()
+ {
return $this->request->getHeader('Authorization');
-
}
-
/**
* Parses the different pieces of the digest string into an array.
*
* This method returns false if an incomplete digest was supplied
*
- * @param string $digest
- * @return mixed
+ * @return bool|array
*/
- protected function parseDigest($digest) {
-
+ protected function parseDigest(string $digest)
+ {
// protect against missing data
$needed_parts = ['nonce' => 1, 'nc' => 1, 'cnonce' => 1, 'qop' => 1, 'username' => 1, 'uri' => 1, 'response' => 1];
$data = [];
@@ -220,12 +201,10 @@ class Digest extends AbstractAuth {
preg_match_all('@(\w+)=(?:(?:")([^"]+)"|([^\s,$]+))@', $digest, $matches, PREG_SET_ORDER);
foreach ($matches as $m) {
- $data[$m[1]] = $m[2] ? $m[2] : $m[3];
+ $data[$m[1]] = $m[2] ?: $m[3];
unset($needed_parts[$m[1]]);
}
return $needed_parts ? false : $data;
-
}
-
}
diff --git a/vendor/sabre/http/lib/Client.php b/vendor/sabre/http/lib/Client.php
index 0810c4a25..48862e7da 100644
--- a/vendor/sabre/http/lib/Client.php
+++ b/vendor/sabre/http/lib/Client.php
@@ -1,5 +1,7 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP;
use Sabre\Event\EventEmitter;
@@ -41,10 +43,10 @@ use Sabre\Uri;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-class Client extends EventEmitter {
-
+class Client extends EventEmitter
+{
/**
- * List of curl settings
+ * List of curl settings.
*
* @var array
*/
@@ -64,53 +66,61 @@ class Client extends EventEmitter {
*/
protected $maxRedirects = 5;
+ protected $headerLinesMap = [];
+
/**
* Initializes the client.
- *
- * @return void
*/
- function __construct() {
+ public function __construct()
+ {
+ // See https://github.com/sabre-io/http/pull/115#discussion_r241292068
+ // Preserve compatibility for sub-classes that implements their own method `parseCurlResult`
+ $separatedHeaders = __CLASS__ === get_class($this);
$this->curlSettings = [
CURLOPT_RETURNTRANSFER => true,
- CURLOPT_HEADER => true,
- CURLOPT_NOBODY => false,
- CURLOPT_USERAGENT => 'sabre-http/' . Version::VERSION . ' (http://sabre.io/)',
+ CURLOPT_NOBODY => false,
+ CURLOPT_USERAGENT => 'sabre-http/'.Version::VERSION.' (http://sabre.io/)',
];
+ if ($separatedHeaders) {
+ $this->curlSettings[CURLOPT_HEADERFUNCTION] = [$this, 'receiveCurlHeader'];
+ } else {
+ $this->curlSettings[CURLOPT_HEADER] = true;
+ }
+ }
+
+ protected function receiveCurlHeader($curlHandle, $headerLine)
+ {
+ $this->headerLinesMap[(int) $curlHandle][] = $headerLine;
+ return strlen($headerLine);
}
/**
* Sends a request to a HTTP server, and returns a response.
- *
- * @param RequestInterface $request
- * @return ResponseInterface
*/
- function send(RequestInterface $request) {
-
+ public function send(RequestInterface $request): ResponseInterface
+ {
$this->emit('beforeRequest', [$request]);
$retryCount = 0;
$redirects = 0;
do {
-
$doRedirect = false;
$retry = false;
try {
-
$response = $this->doRequest($request);
- $code = (int)$response->getStatus();
+ $code = $response->getStatus();
// We are doing in-PHP redirects, because curl's
// FOLLOW_LOCATION throws errors when PHP is configured with
// open_basedir.
//
// https://github.com/fruux/sabre-http/issues/12
- if (in_array($code, [301, 302, 307, 308]) && $redirects < $this->maxRedirects) {
-
+ if ($redirects < $this->maxRedirects && in_array($code, [301, 302, 307, 308])) {
$oldLocation = $request->getUrl();
// Creating a new instance of the request object.
@@ -123,20 +133,15 @@ class Client extends EventEmitter {
));
$doRedirect = true;
- $redirects++;
-
+ ++$redirects;
}
// This was a HTTP error
if ($code >= 400) {
-
$this->emit('error', [$request, $response, &$retry, $retryCount]);
- $this->emit('error:' . $code, [$request, $response, &$retry, $retryCount]);
-
+ $this->emit('error:'.$code, [$request, $response, &$retry, $retryCount]);
}
-
} catch (ClientException $e) {
-
$this->emit('exception', [$request, $e, &$retry, $retryCount]);
// If retry was still set to false, it means no event handler
@@ -145,13 +150,11 @@ class Client extends EventEmitter {
if (!$retry) {
throw $e;
}
-
}
if ($retry) {
- $retryCount++;
+ ++$retryCount;
}
-
} while ($retry || $doRedirect);
$this->emit('afterRequest', [$request, $response]);
@@ -161,7 +164,6 @@ class Client extends EventEmitter {
}
return $response;
-
}
/**
@@ -172,32 +174,23 @@ class Client extends EventEmitter {
*
* After calling sendAsync, you must therefore occasionally call the poll()
* method, or wait().
- *
- * @param RequestInterface $request
- * @param callable $success
- * @param callable $error
- * @return void
*/
- function sendAsync(RequestInterface $request, callable $success = null, callable $error = null) {
-
+ public function sendAsync(RequestInterface $request, callable $success = null, callable $error = null)
+ {
$this->emit('beforeRequest', [$request]);
$this->sendAsyncInternal($request, $success, $error);
$this->poll();
-
}
-
/**
* This method checks if any http requests have gotten results, and if so,
* call the appropriate success or error handlers.
*
* This method will return true if there are still requests waiting to
* return, and false if all the work is done.
- *
- * @return bool
*/
- function poll() {
-
+ public function poll(): bool
+ {
// nothing to do?
if (!$this->curlMultiMap) {
return false;
@@ -208,10 +201,10 @@ class Client extends EventEmitter {
$this->curlMultiHandle,
$stillRunning
);
- } while ($r === CURLM_CALL_MULTI_PERFORM);
+ } while (CURLM_CALL_MULTI_PERFORM === $r);
+ $messagesInQueue = 0;
do {
-
messageQueue:
$status = curl_multi_info_read(
@@ -219,26 +212,25 @@ class Client extends EventEmitter {
$messagesInQueue
);
- if ($status && $status['msg'] === CURLMSG_DONE) {
-
- $resourceId = intval($status['handle']);
+ if ($status && CURLMSG_DONE === $status['msg']) {
+ $resourceId = (int) $status['handle'];
list(
$request,
$successCallback,
$errorCallback,
- $retryCount,
- ) = $this->curlMultiMap[$resourceId];
+ $retryCount) = $this->curlMultiMap[$resourceId];
unset($this->curlMultiMap[$resourceId]);
- $curlResult = $this->parseCurlResult(curl_multi_getcontent($status['handle']), $status['handle']);
- $retry = false;
- if ($curlResult['status'] === self::STATUS_CURLERROR) {
+ $curlHandle = $status['handle'];
+ $curlResult = $this->parseResponse(curl_multi_getcontent($curlHandle), $curlHandle);
+ $retry = false;
+ if (self::STATUS_CURLERROR === $curlResult['status']) {
$e = new ClientException($curlResult['curl_errmsg'], $curlResult['curl_errno']);
$this->emit('exception', [$request, $e, &$retry, $retryCount]);
if ($retry) {
- $retryCount++;
+ ++$retryCount;
$this->sendAsyncInternal($request, $successCallback, $errorCallback, $retryCount);
goto messageQueue;
}
@@ -248,18 +240,14 @@ class Client extends EventEmitter {
if ($errorCallback) {
$errorCallback($curlResult);
}
-
- } elseif ($curlResult['status'] === self::STATUS_HTTPERROR) {
-
+ } elseif (self::STATUS_HTTPERROR === $curlResult['status']) {
$this->emit('error', [$request, $curlResult['response'], &$retry, $retryCount]);
- $this->emit('error:' . $curlResult['http_code'], [$request, $curlResult['response'], &$retry, $retryCount]);
+ $this->emit('error:'.$curlResult['http_code'], [$request, $curlResult['response'], &$retry, $retryCount]);
if ($retry) {
-
- $retryCount++;
+ ++$retryCount;
$this->sendAsyncInternal($request, $successCallback, $errorCallback, $retryCount);
goto messageQueue;
-
}
$curlResult['request'] = $request;
@@ -267,37 +255,29 @@ class Client extends EventEmitter {
if ($errorCallback) {
$errorCallback($curlResult);
}
-
} else {
-
$this->emit('afterRequest', [$request, $curlResult['response']]);
if ($successCallback) {
$successCallback($curlResult['response']);
}
-
}
}
-
} while ($messagesInQueue > 0);
return count($this->curlMultiMap) > 0;
-
}
/**
* Processes every HTTP request in the queue, and waits till they are all
* completed.
- *
- * @return void
*/
- function wait() {
-
+ public function wait()
+ {
do {
curl_multi_select($this->curlMultiHandle);
$stillRunning = $this->poll();
} while ($stillRunning);
-
}
/**
@@ -309,14 +289,10 @@ class Client extends EventEmitter {
*
* This only works for the send() method. Throwing exceptions for
* sendAsync() is not supported.
- *
- * @param bool $throwExceptions
- * @return void
*/
- function setThrowExceptions($throwExceptions) {
-
+ public function setThrowExceptions(bool $throwExceptions)
+ {
$this->throwExceptions = $throwExceptions;
-
}
/**
@@ -324,40 +300,34 @@ class Client extends EventEmitter {
*
* These settings will be included in every HTTP request.
*
- * @param int $name
* @param mixed $value
- * @return void
*/
- function addCurlSetting($name, $value) {
-
+ public function addCurlSetting(int $name, $value)
+ {
$this->curlSettings[$name] = $value;
-
}
/**
* This method is responsible for performing a single request.
- *
- * @param RequestInterface $request
- * @return ResponseInterface
*/
- protected function doRequest(RequestInterface $request) {
-
+ protected function doRequest(RequestInterface $request): ResponseInterface
+ {
$settings = $this->createCurlSettingsArray($request);
if (!$this->curlHandle) {
$this->curlHandle = curl_init();
+ } else {
+ curl_reset($this->curlHandle);
}
curl_setopt_array($this->curlHandle, $settings);
$response = $this->curlExec($this->curlHandle);
- $response = $this->parseCurlResult($response, $this->curlHandle);
-
- if ($response['status'] === self::STATUS_CURLERROR) {
+ $response = $this->parseResponse($response, $this->curlHandle);
+ if (self::STATUS_CURLERROR === $response['status']) {
throw new ClientException($response['curl_errmsg'], $response['curl_errno']);
}
return $response['response'];
-
}
/**
@@ -389,28 +359,21 @@ class Client extends EventEmitter {
/**
* Turns a RequestInterface object into an array with settings that can be
- * fed to curl_setopt
- *
- * @param RequestInterface $request
- * @return array
+ * fed to curl_setopt.
*/
- protected function createCurlSettingsArray(RequestInterface $request) {
-
+ protected function createCurlSettingsArray(RequestInterface $request): array
+ {
$settings = $this->curlSettings;
switch ($request->getMethod()) {
- case 'HEAD' :
+ case 'HEAD':
$settings[CURLOPT_NOBODY] = true;
$settings[CURLOPT_CUSTOMREQUEST] = 'HEAD';
- $settings[CURLOPT_POSTFIELDS] = '';
- $settings[CURLOPT_PUT] = false;
break;
- case 'GET' :
+ case 'GET':
$settings[CURLOPT_CUSTOMREQUEST] = 'GET';
- $settings[CURLOPT_POSTFIELDS] = '';
- $settings[CURLOPT_PUT] = false;
break;
- default :
+ default:
$body = $request->getBody();
if (is_resource($body)) {
// This needs to be set to PUT, regardless of the actual
@@ -422,20 +385,17 @@ class Client extends EventEmitter {
// For security we cast this to a string. If somehow an array could
// be passed here, it would be possible for an attacker to use @ to
// post local files.
- $settings[CURLOPT_POSTFIELDS] = (string)$body;
+ $settings[CURLOPT_POSTFIELDS] = (string) $body;
}
$settings[CURLOPT_CUSTOMREQUEST] = $request->getMethod();
break;
-
}
$nHeaders = [];
foreach ($request->getHeaders() as $key => $values) {
-
foreach ($values as $value) {
- $nHeaders[] = $key . ': ' . $value;
+ $nHeaders[] = $key.': '.$value;
}
-
}
$settings[CURLOPT_HTTPHEADER] = $nHeaders;
$settings[CURLOPT_URL] = $request->getUrl();
@@ -449,13 +409,32 @@ class Client extends EventEmitter {
}
return $settings;
-
}
const STATUS_SUCCESS = 0;
const STATUS_CURLERROR = 1;
const STATUS_HTTPERROR = 2;
+ private function parseResponse(string $response, $curlHandle): array
+ {
+ $settings = $this->curlSettings;
+ $separatedHeaders = isset($settings[CURLOPT_HEADERFUNCTION]) && (bool) $settings[CURLOPT_HEADERFUNCTION];
+
+ if ($separatedHeaders) {
+ $resourceId = (int) $curlHandle;
+ if (isset($this->headerLinesMap[$resourceId])) {
+ $headers = $this->headerLinesMap[$resourceId];
+ } else {
+ $headers = [];
+ }
+ $response = $this->parseCurlResponse($headers, $response, $curlHandle);
+ } else {
+ $response = $this->parseCurlResult($response, $curlHandle);
+ }
+
+ return $response;
+ }
+
/**
* Parses the result of a curl call in a format that's a bit more
* convenient to work with.
@@ -471,12 +450,67 @@ class Client extends EventEmitter {
* * http_code - HTTP status code, as an int. Only set if Only set if
* status is STATUS_SUCCESS, or STATUS_HTTPERROR
*
- * @param string $response
+ * @param array $headerLines
+ * @param string $body
* @param resource $curlHandle
- * @return Response
*/
- protected function parseCurlResult($response, $curlHandle) {
+ protected function parseCurlResponse(array $headerLines, string $body, $curlHandle): array
+ {
+ list(
+ $curlInfo,
+ $curlErrNo,
+ $curlErrMsg
+ ) = $this->curlStuff($curlHandle);
+ if ($curlErrNo) {
+ return [
+ 'status' => self::STATUS_CURLERROR,
+ 'curl_errno' => $curlErrNo,
+ 'curl_errmsg' => $curlErrMsg,
+ ];
+ }
+
+ $response = new Response();
+ $response->setStatus($curlInfo['http_code']);
+ $response->setBody($body);
+
+ foreach ($headerLines as $header) {
+ $parts = explode(':', $header, 2);
+ if (2 === count($parts)) {
+ $response->addHeader(trim($parts[0]), trim($parts[1]));
+ }
+ }
+
+ $httpCode = $response->getStatus();
+
+ return [
+ 'status' => $httpCode >= 400 ? self::STATUS_HTTPERROR : self::STATUS_SUCCESS,
+ 'response' => $response,
+ 'http_code' => $httpCode,
+ ];
+ }
+
+ /**
+ * Parses the result of a curl call in a format that's a bit more
+ * convenient to work with.
+ *
+ * The method returns an array with the following elements:
+ * * status - one of the 3 STATUS constants.
+ * * curl_errno - A curl error number. Only set if status is
+ * STATUS_CURLERROR.
+ * * curl_errmsg - A current error message. Only set if status is
+ * STATUS_CURLERROR.
+ * * response - Response object. Only set if status is STATUS_SUCCESS, or
+ * STATUS_HTTPERROR.
+ * * http_code - HTTP status code, as an int. Only set if Only set if
+ * status is STATUS_SUCCESS, or STATUS_HTTPERROR
+ *
+ * @deprecated Use parseCurlResponse instead
+ *
+ * @param resource $curlHandle
+ */
+ protected function parseCurlResult(string $response, $curlHandle): array
+ {
list(
$curlInfo,
$curlErrNo,
@@ -485,8 +519,8 @@ class Client extends EventEmitter {
if ($curlErrNo) {
return [
- 'status' => self::STATUS_CURLERROR,
- 'curl_errno' => $curlErrNo,
+ 'status' => self::STATUS_CURLERROR,
+ 'curl_errno' => $curlErrNo,
'curl_errmsg' => $curlErrMsg,
];
}
@@ -495,7 +529,7 @@ class Client extends EventEmitter {
// In the case of 204 No Content, strlen($response) == $curlInfo['header_size].
// This will cause substr($response, $curlInfo['header_size']) return FALSE instead of NULL
// An exception will be thrown when calling getBodyAsString then
- $responseBody = substr($response, $curlInfo['header_size']) ?: null;
+ $responseBody = substr($response, $curlInfo['header_size']) ?: '';
unset($response);
@@ -510,26 +544,7 @@ class Client extends EventEmitter {
// Splitting headers
$headerBlob = explode("\r\n", $headerBlob);
- $response = new Response();
- $response->setStatus($curlInfo['http_code']);
-
- foreach ($headerBlob as $header) {
- $parts = explode(':', $header, 2);
- if (count($parts) == 2) {
- $response->addHeader(trim($parts[0]), trim($parts[1]));
- }
- }
-
- $response->setBody($responseBody);
-
- $httpCode = intval($response->getStatus());
-
- return [
- 'status' => $httpCode >= 400 ? self::STATUS_HTTPERROR : self::STATUS_SUCCESS,
- 'response' => $response,
- 'http_code' => $httpCode,
- ];
-
+ return $this->parseCurlResponse($headerBlob, $responseBody, $curlHandle);
}
/**
@@ -537,14 +552,9 @@ class Client extends EventEmitter {
*
* We keep this in a separate method, so we can call it without triggering
* the beforeRequest event and don't do the poll().
- *
- * @param RequestInterface $request
- * @param callable $success
- * @param callable $error
- * @param int $retryCount
*/
- protected function sendAsyncInternal(RequestInterface $request, callable $success, callable $error, $retryCount = 0) {
-
+ protected function sendAsyncInternal(RequestInterface $request, callable $success, callable $error, int $retryCount = 0)
+ {
if (!$this->curlMultiHandle) {
$this->curlMultiHandle = curl_multi_init();
}
@@ -554,29 +564,36 @@ class Client extends EventEmitter {
$this->createCurlSettingsArray($request)
);
curl_multi_add_handle($this->curlMultiHandle, $curl);
- $this->curlMultiMap[intval($curl)] = [
+
+ $resourceId = (int) $curl;
+ $this->headerLinesMap[$resourceId] = [];
+ $this->curlMultiMap[$resourceId] = [
$request,
$success,
$error,
- $retryCount
+ $retryCount,
];
-
}
// @codeCoverageIgnoreStart
/**
- * Calls curl_exec
+ * Calls curl_exec.
*
* This method exists so it can easily be overridden and mocked.
*
* @param resource $curlHandle
- * @return string
*/
- protected function curlExec($curlHandle) {
+ protected function curlExec($curlHandle): string
+ {
+ $this->headerLinesMap[(int) $curlHandle] = [];
- return curl_exec($curlHandle);
+ $result = curl_exec($curlHandle);
+ if (false === $result) {
+ $result = '';
+ }
+ return $result;
}
/**
@@ -585,17 +602,15 @@ class Client extends EventEmitter {
* This method exists so it can easily be overridden and mocked.
*
* @param resource $curlHandle
- * @return array
*/
- protected function curlStuff($curlHandle) {
-
+ protected function curlStuff($curlHandle): array
+ {
return [
curl_getinfo($curlHandle),
curl_errno($curlHandle),
curl_error($curlHandle),
];
-
}
- // @codeCoverageIgnoreEnd
+ // @codeCoverageIgnoreEnd
}
diff --git a/vendor/sabre/http/lib/ClientException.php b/vendor/sabre/http/lib/ClientException.php
index 69631f44e..2ca4a28e0 100644
--- a/vendor/sabre/http/lib/ClientException.php
+++ b/vendor/sabre/http/lib/ClientException.php
@@ -1,5 +1,7 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP;
/**
@@ -10,6 +12,6 @@ namespace Sabre\HTTP;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-class ClientException extends \Exception {
-
+class ClientException extends \Exception
+{
}
diff --git a/vendor/sabre/http/lib/ClientHttpException.php b/vendor/sabre/http/lib/ClientHttpException.php
index 2923ef3b5..116ca1f79 100644
--- a/vendor/sabre/http/lib/ClientHttpException.php
+++ b/vendor/sabre/http/lib/ClientHttpException.php
@@ -1,5 +1,7 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP;
/**
@@ -12,47 +14,37 @@ namespace Sabre\HTTP;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-class ClientHttpException extends \Exception implements HttpException {
-
+class ClientHttpException extends \Exception implements HttpException
+{
/**
- * Response object
+ * Response object.
*
* @var ResponseInterface
*/
protected $response;
/**
- * Constructor
- *
- * @param ResponseInterface $response
+ * Constructor.
*/
- function __construct(ResponseInterface $response) {
-
+ public function __construct(ResponseInterface $response)
+ {
$this->response = $response;
parent::__construct($response->getStatusText(), $response->getStatus());
-
}
/**
* The http status code for the error.
- *
- * @return int
*/
- function getHttpStatus() {
-
+ public function getHttpStatus(): int
+ {
return $this->response->getStatus();
-
}
/**
* Returns the full response object.
- *
- * @return ResponseInterface
*/
- function getResponse() {
-
+ public function getResponse(): ResponseInterface
+ {
return $this->response;
-
}
-
}
diff --git a/vendor/sabre/http/lib/HttpException.php b/vendor/sabre/http/lib/HttpException.php
index 1303dec97..80b3ae665 100644
--- a/vendor/sabre/http/lib/HttpException.php
+++ b/vendor/sabre/http/lib/HttpException.php
@@ -1,5 +1,7 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP;
/**
@@ -15,8 +17,8 @@ namespace Sabre\HTTP;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-interface HttpException {
-
+interface HttpException
+{
/**
* The http status code for the error.
*
@@ -25,6 +27,5 @@ interface HttpException {
*
* @return string|null
*/
- function getHttpStatus();
-
+ public function getHttpStatus();
}
diff --git a/vendor/sabre/http/lib/Message.php b/vendor/sabre/http/lib/Message.php
index 45bd18398..fc34f8d7f 100644
--- a/vendor/sabre/http/lib/Message.php
+++ b/vendor/sabre/http/lib/Message.php
@@ -1,5 +1,7 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP;
/**
@@ -11,26 +13,26 @@ namespace Sabre\HTTP;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-abstract class Message implements MessageInterface {
-
+abstract class Message implements MessageInterface
+{
/**
- * Request body
+ * Request body.
*
- * This should be a stream resource
+ * This should be a stream resource, string or a callback writing the body to php://output
*
- * @var resource
+ * @var resource|string|callable
*/
protected $body;
/**
- * Contains the list of HTTP headers
+ * Contains the list of HTTP headers.
*
* @var array
*/
protected $headers = [];
/**
- * HTTP message version (1.0 or 1.1)
+ * HTTP message version (1.0, 1.1 or 2.0).
*
* @var string
*/
@@ -44,17 +46,21 @@ abstract class Message implements MessageInterface {
*
* @return resource
*/
- function getBodyAsStream() {
-
+ public function getBodyAsStream()
+ {
$body = $this->getBody();
- if (is_string($body) || is_null($body)) {
+ if (is_callable($this->body)) {
+ $body = $this->getBodyAsString();
+ }
+ if (is_string($body) || null === $body) {
$stream = fopen('php://temp', 'r+');
- fwrite($stream, $body);
+ fwrite($stream, (string) $body);
rewind($stream);
+
return $stream;
}
- return $body;
+ return $body;
}
/**
@@ -62,77 +68,76 @@ abstract class Message implements MessageInterface {
*
* Note that because the underlying data may be based on a stream, this
* method could only work correctly the first time.
- *
- * @return string
*/
- function getBodyAsString() {
-
+ public function getBodyAsString(): string
+ {
$body = $this->getBody();
if (is_string($body)) {
return $body;
}
- if (is_null($body)) {
+ if (null === $body) {
return '';
}
+ if (is_callable($body)) {
+ ob_start();
+ $body();
+
+ return ob_get_clean();
+ }
+ /**
+ * @var string|int|null
+ */
$contentLength = $this->getHeader('Content-Length');
if (is_int($contentLength) || ctype_digit($contentLength)) {
- return stream_get_contents($body, $contentLength);
- } else {
- return stream_get_contents($body);
+ return stream_get_contents($body, (int) $contentLength);
}
+
+ return stream_get_contents($body);
}
/**
* Returns the message body, as it's internal representation.
*
- * This could be either a string or a stream.
+ * This could be either a string, a stream or a callback writing the body to php://output.
*
- * @return resource|string
+ * @return resource|string|callable
*/
- function getBody() {
-
+ public function getBody()
+ {
return $this->body;
-
}
/**
- * Replaces the body resource with a new stream or string.
+ * Replaces the body resource with a new stream, string or a callback writing the body to php://output.
*
- * @param resource|string $body
+ * @param resource|string|callable $body
*/
- function setBody($body) {
-
+ public function setBody($body)
+ {
$this->body = $body;
-
}
/**
* Returns all the HTTP headers as an array.
*
* Every header is returned as an array, with one or more values.
- *
- * @return array
*/
- function getHeaders() {
-
+ public function getHeaders(): array
+ {
$result = [];
foreach ($this->headers as $headerInfo) {
$result[$headerInfo[0]] = $headerInfo[1];
}
- return $result;
+ return $result;
}
/**
* Will return true or false, depending on if a HTTP header exists.
- *
- * @param string $name
- * @return bool
*/
- function hasHeader($name) {
-
+ public function hasHeader(string $name): bool
+ {
return isset($this->headers[strtolower($name)]);
-
}
/**
@@ -148,18 +153,17 @@ abstract class Message implements MessageInterface {
* `Set-Cookie` cannot be logically combined with a comma. In those cases
* you *should* use getHeaderAsArray().
*
- * @param string $name
* @return string|null
*/
- function getHeader($name) {
-
+ public function getHeader(string $name)
+ {
$name = strtolower($name);
if (isset($this->headers[$name])) {
return implode(',', $this->headers[$name][1]);
}
- return null;
+ return null;
}
/**
@@ -170,11 +174,10 @@ abstract class Message implements MessageInterface {
*
* If the header did not exists, this method will return an empty array.
*
- * @param string $name
* @return string[]
*/
- function getHeaderAsArray($name) {
-
+ public function getHeaderAsArray(string $name): array
+ {
$name = strtolower($name);
if (isset($this->headers[$name])) {
@@ -182,7 +185,6 @@ abstract class Message implements MessageInterface {
}
return [];
-
}
/**
@@ -192,14 +194,11 @@ abstract class Message implements MessageInterface {
*
* If the header already existed, it will be overwritten.
*
- * @param string $name
* @param string|string[] $value
- * @return void
*/
- function setHeader($name, $value) {
-
- $this->headers[strtolower($name)] = [$name, (array)$value];
-
+ public function setHeader(string $name, $value)
+ {
+ $this->headers[strtolower($name)] = [$name, (array) $value];
}
/**
@@ -209,16 +208,12 @@ abstract class Message implements MessageInterface {
* should be specified as either a string or an array.
*
* Any header that already existed will be overwritten.
- *
- * @param array $headers
- * @return void
*/
- function setHeaders(array $headers) {
-
+ public function setHeaders(array $headers)
+ {
foreach ($headers as $name => $value) {
$this->setHeader($name, $value);
}
-
}
/**
@@ -228,77 +223,62 @@ abstract class Message implements MessageInterface {
* another value. Individual values can be retrieved with
* getHeadersAsArray.
*
- * @param string $name
- * @param string $value
- * @return void
+ * @param string|string[] $value
*/
- function addHeader($name, $value) {
-
+ public function addHeader(string $name, $value)
+ {
$lName = strtolower($name);
if (isset($this->headers[$lName])) {
$this->headers[$lName][1] = array_merge(
$this->headers[$lName][1],
- (array)$value
+ (array) $value
);
} else {
$this->headers[$lName] = [
$name,
- (array)$value
+ (array) $value,
];
}
-
}
/**
* Adds a new set of HTTP headers.
*
* Any existing headers will not be overwritten.
- *
- * @param array $headers
- * @return void
*/
- function addHeaders(array $headers) {
-
+ public function addHeaders(array $headers)
+ {
foreach ($headers as $name => $value) {
$this->addHeader($name, $value);
}
-
}
-
/**
* Removes a HTTP header.
*
* The specified header name must be treated as case-insensitive.
* This method should return true if the header was successfully deleted,
* and false if the header did not exist.
- *
- * @param string $name
- * @return bool
*/
- function removeHeader($name) {
-
+ public function removeHeader(string $name): bool
+ {
$name = strtolower($name);
if (!isset($this->headers[$name])) {
return false;
}
unset($this->headers[$name]);
- return true;
+ return true;
}
/**
* Sets the HTTP version.
*
- * Should be 1.0 or 1.1.
- *
- * @param string $version
- * @return void
+ * Should be 1.0, 1.1 or 2.0.
*/
- function setHttpVersion($version) {
-
+ public function setHttpVersion(string $version)
+ {
$this->httpVersion = $version;
-
}
/**
@@ -306,9 +286,8 @@ abstract class Message implements MessageInterface {
*
* @return string
*/
- function getHttpVersion() {
-
+ public function getHttpVersion(): string
+ {
return $this->httpVersion;
-
}
}
diff --git a/vendor/sabre/http/lib/MessageDecoratorTrait.php b/vendor/sabre/http/lib/MessageDecoratorTrait.php
index 1cb32da22..d5504ac78 100644
--- a/vendor/sabre/http/lib/MessageDecoratorTrait.php
+++ b/vendor/sabre/http/lib/MessageDecoratorTrait.php
@@ -1,5 +1,7 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP;
/**
@@ -13,8 +15,8 @@ namespace Sabre\HTTP;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-trait MessageDecoratorTrait {
-
+trait MessageDecoratorTrait
+{
/**
* The inner request object.
*
@@ -32,10 +34,9 @@ trait MessageDecoratorTrait {
*
* @return resource
*/
- function getBodyAsStream() {
-
+ public function getBodyAsStream()
+ {
return $this->inner->getBodyAsStream();
-
}
/**
@@ -43,13 +44,10 @@ trait MessageDecoratorTrait {
*
* Note that because the underlying data may be based on a stream, this
* method could only work correctly the first time.
- *
- * @return string
*/
- function getBodyAsString() {
-
+ public function getBodyAsString(): string
+ {
return $this->inner->getBodyAsString();
-
}
/**
@@ -59,47 +57,37 @@ trait MessageDecoratorTrait {
*
* @return resource|string
*/
- function getBody() {
-
+ public function getBody()
+ {
return $this->inner->getBody();
-
}
/**
* Updates the body resource with a new stream.
*
- * @param resource $body
- * @return void
+ * @param resource|string|callable $body
*/
- function setBody($body) {
-
+ public function setBody($body)
+ {
$this->inner->setBody($body);
-
}
/**
* Returns all the HTTP headers as an array.
*
* Every header is returned as an array, with one or more values.
- *
- * @return array
*/
- function getHeaders() {
-
+ public function getHeaders(): array
+ {
return $this->inner->getHeaders();
-
}
/**
* Will return true or false, depending on if a HTTP header exists.
- *
- * @param string $name
- * @return bool
*/
- function hasHeader($name) {
-
+ public function hasHeader(string $name): bool
+ {
return $this->inner->hasHeader($name);
-
}
/**
@@ -115,13 +103,11 @@ trait MessageDecoratorTrait {
* `Set-Cookie` cannot be logically combined with a comma. In those cases
* you *should* use getHeaderAsArray().
*
- * @param string $name
* @return string|null
*/
- function getHeader($name) {
-
+ public function getHeader(string $name)
+ {
return $this->inner->getHeader($name);
-
}
/**
@@ -131,14 +117,10 @@ trait MessageDecoratorTrait {
* item will appear in the array.
*
* If the header did not exists, this method will return an empty array.
- *
- * @param string $name
- * @return string[]
*/
- function getHeaderAsArray($name) {
-
+ public function getHeaderAsArray(string $name): array
+ {
return $this->inner->getHeaderAsArray($name);
-
}
/**
@@ -148,14 +130,11 @@ trait MessageDecoratorTrait {
*
* If the header already existed, it will be overwritten.
*
- * @param string $name
* @param string|string[] $value
- * @return void
*/
- function setHeader($name, $value) {
-
+ public function setHeader(string $name, $value)
+ {
$this->inner->setHeader($name, $value);
-
}
/**
@@ -165,14 +144,10 @@ trait MessageDecoratorTrait {
* should be specified as either a string or an array.
*
* Any header that already existed will be overwritten.
- *
- * @param array $headers
- * @return void
*/
- function setHeaders(array $headers) {
-
+ public function setHeaders(array $headers)
+ {
$this->inner->setHeaders($headers);
-
}
/**
@@ -182,31 +157,23 @@ trait MessageDecoratorTrait {
* another value. Individual values can be retrieved with
* getHeadersAsArray.
*
- * @param string $name
- * @param string $value
- * @return void
+ * @param string|string[] $value
*/
- function addHeader($name, $value) {
-
+ public function addHeader(string $name, $value)
+ {
$this->inner->addHeader($name, $value);
-
}
/**
* Adds a new set of HTTP headers.
*
* Any existing headers will not be overwritten.
- *
- * @param array $headers
- * @return void
*/
- function addHeaders(array $headers) {
-
+ public function addHeaders(array $headers)
+ {
$this->inner->addHeaders($headers);
-
}
-
/**
* Removes a HTTP header.
*
@@ -214,38 +181,28 @@ trait MessageDecoratorTrait {
* This method should return true if the header was successfully deleted,
* and false if the header did not exist.
*
- * @param string $name
* @return bool
*/
- function removeHeader($name) {
-
+ public function removeHeader(string $name): bool
+ {
return $this->inner->removeHeader($name);
-
}
/**
* Sets the HTTP version.
*
- * Should be 1.0 or 1.1.
- *
- * @param string $version
- * @return void
+ * Should be 1.0, 1.1 or 2.0.
*/
- function setHttpVersion($version) {
-
+ public function setHttpVersion(string $version)
+ {
$this->inner->setHttpVersion($version);
-
}
/**
* Returns the HTTP version.
- *
- * @return string
*/
- function getHttpVersion() {
-
+ public function getHttpVersion(): string
+ {
return $this->inner->getHttpVersion();
-
}
-
}
diff --git a/vendor/sabre/http/lib/MessageInterface.php b/vendor/sabre/http/lib/MessageInterface.php
index df55beb2f..8070845d9 100644
--- a/vendor/sabre/http/lib/MessageInterface.php
+++ b/vendor/sabre/http/lib/MessageInterface.php
@@ -1,5 +1,7 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP;
/**
@@ -10,8 +12,8 @@ namespace Sabre\HTTP;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-interface MessageInterface {
-
+interface MessageInterface
+{
/**
* Returns the body as a readable stream resource.
*
@@ -20,7 +22,7 @@ interface MessageInterface {
*
* @return resource
*/
- function getBodyAsStream();
+ public function getBodyAsStream();
/**
* Returns the body as a string.
@@ -30,41 +32,35 @@ interface MessageInterface {
*
* @return string
*/
- function getBodyAsString();
+ public function getBodyAsString(): string;
/**
* Returns the message body, as it's internal representation.
*
- * This could be either a string or a stream.
+ * This could be either a string, a stream or a callback writing the body to php://output
*
- * @return resource|string
+ * @return resource|string|callable
*/
- function getBody();
+ public function getBody();
/**
* Updates the body resource with a new stream.
*
- * @param resource|string $body
- * @return void
+ * @param resource|string|callable $body
*/
- function setBody($body);
+ public function setBody($body);
/**
* Returns all the HTTP headers as an array.
*
* Every header is returned as an array, with one or more values.
- *
- * @return array
*/
- function getHeaders();
+ public function getHeaders(): array;
/**
* Will return true or false, depending on if a HTTP header exists.
- *
- * @param string $name
- * @return bool
*/
- function hasHeader($name);
+ public function hasHeader(string $name): bool;
/**
* Returns a specific HTTP header, based on it's name.
@@ -79,10 +75,9 @@ interface MessageInterface {
* `Set-Cookie` cannot be logically combined with a comma. In those cases
* you *should* use getHeaderAsArray().
*
- * @param string $name
* @return string|null
*/
- function getHeader($name);
+ public function getHeader(string $name);
/**
* Returns a HTTP header as an array.
@@ -92,10 +87,9 @@ interface MessageInterface {
*
* If the header did not exists, this method will return an empty array.
*
- * @param string $name
* @return string[]
*/
- function getHeaderAsArray($name);
+ public function getHeaderAsArray(string $name): array;
/**
* Updates a HTTP header.
@@ -104,11 +98,9 @@ interface MessageInterface {
*
* If the header already existed, it will be overwritten.
*
- * @param string $name
* @param string|string[] $value
- * @return void
*/
- function setHeader($name, $value);
+ public function setHeader(string $name, $value);
/**
* Sets a new set of HTTP headers.
@@ -117,11 +109,8 @@ interface MessageInterface {
* should be specified as either a string or an array.
*
* Any header that already existed will be overwritten.
- *
- * @param array $headers
- * @return void
*/
- function setHeaders(array $headers);
+ public function setHeaders(array $headers);
/**
* Adds a HTTP header.
@@ -130,21 +119,16 @@ interface MessageInterface {
* another value. Individual values can be retrieved with
* getHeadersAsArray.
*
- * @param string $name
- * @param string $value
- * @return void
+ * @param string|string[] $value
*/
- function addHeader($name, $value);
+ public function addHeader(string $name, $value);
/**
* Adds a new set of HTTP headers.
*
* Any existing headers will not be overwritten.
- *
- * @param array $headers
- * @return void
*/
- function addHeaders(array $headers);
+ public function addHeaders(array $headers);
/**
* Removes a HTTP header.
@@ -152,27 +136,18 @@ interface MessageInterface {
* The specified header name must be treated as case-insenstive.
* This method should return true if the header was successfully deleted,
* and false if the header did not exist.
- *
- * @param string $name
- * @return bool
*/
- function removeHeader($name);
+ public function removeHeader(string $name): bool;
/**
* Sets the HTTP version.
*
- * Should be 1.0 or 1.1.
- *
- * @param string $version
- * @return void
+ * Should be 1.0, 1.1 or 2.0.
*/
- function setHttpVersion($version);
+ public function setHttpVersion(string $version);
/**
* Returns the HTTP version.
- *
- * @return string
*/
- function getHttpVersion();
-
+ public function getHttpVersion(): string;
}
diff --git a/vendor/sabre/http/lib/Request.php b/vendor/sabre/http/lib/Request.php
index dfa3d5b48..496629a5b 100644
--- a/vendor/sabre/http/lib/Request.php
+++ b/vendor/sabre/http/lib/Request.php
@@ -1,8 +1,10 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP;
-use InvalidArgumentException;
+use LogicException;
use Sabre\Uri;
/**
@@ -15,132 +17,111 @@ use Sabre\Uri;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-class Request extends Message implements RequestInterface {
-
+class Request extends Message implements RequestInterface
+{
/**
- * HTTP Method
+ * HTTP Method.
*
* @var string
*/
protected $method;
/**
- * Request Url
+ * Request Url.
*
* @var string
*/
protected $url;
/**
- * Creates the request object
+ * Creates the request object.
*
- * @param string $method
- * @param string $url
- * @param array $headers
- * @param resource $body
+ * @param resource|callable|string $body
*/
- function __construct($method = null, $url = null, array $headers = null, $body = null) {
-
- if (is_array($method)) {
- throw new InvalidArgumentException('The first argument for this constructor should be a string or null, not an array. Did you upgrade from sabre/http 1.0 to 2.0?');
- }
- if (!is_null($method)) $this->setMethod($method);
- if (!is_null($url)) $this->setUrl($url);
- if (!is_null($headers)) $this->setHeaders($headers);
- if (!is_null($body)) $this->setBody($body);
-
+ public function __construct(string $method, string $url, array $headers = [], $body = null)
+ {
+ $this->setMethod($method);
+ $this->setUrl($url);
+ $this->setHeaders($headers);
+ $this->setBody($body);
}
/**
- * Returns the current HTTP method
- *
- * @return string
+ * Returns the current HTTP method.
*/
- function getMethod() {
-
+ public function getMethod(): string
+ {
return $this->method;
-
}
/**
- * Sets the HTTP method
- *
- * @param string $method
- * @return void
+ * Sets the HTTP method.
*/
- function setMethod($method) {
-
+ public function setMethod(string $method)
+ {
$this->method = $method;
-
}
/**
* Returns the request url.
- *
- * @return string
*/
- function getUrl() {
-
+ public function getUrl(): string
+ {
return $this->url;
-
}
/**
* Sets the request url.
- *
- * @param string $url
- * @return void
*/
- function setUrl($url) {
-
+ public function setUrl(string $url)
+ {
$this->url = $url;
-
}
/**
* Returns the list of query parameters.
*
* This is equivalent to PHP's $_GET superglobal.
- *
- * @return array
*/
- function getQueryParameters() {
-
+ public function getQueryParameters(): array
+ {
$url = $this->getUrl();
- if (($index = strpos($url, '?')) === false) {
+ if (false === ($index = strpos($url, '?'))) {
return [];
- } else {
- parse_str(substr($url, $index + 1), $queryParams);
- return $queryParams;
}
+ parse_str(substr($url, $index + 1), $queryParams);
+
+ return $queryParams;
}
+ protected $absoluteUrl;
+
/**
* Sets the absolute url.
- *
- * @param string $url
- * @return void
*/
- function setAbsoluteUrl($url) {
-
+ public function setAbsoluteUrl(string $url)
+ {
$this->absoluteUrl = $url;
-
}
/**
* Returns the absolute url.
- *
- * @return string
*/
- function getAbsoluteUrl() {
+ public function getAbsoluteUrl(): string
+ {
+ if (!$this->absoluteUrl) {
+ // Guessing we're a http endpoint.
+ $this->absoluteUrl = 'http://'.
+ ($this->getHeader('Host') ?? 'localhost').
+ $this->getUrl();
+ }
return $this->absoluteUrl;
-
}
/**
- * Base url
+ * Base url.
*
* @var string
*/
@@ -150,25 +131,18 @@ class Request extends Message implements RequestInterface {
* Sets a base url.
*
* This url is used for relative path calculations.
- *
- * @param string $url
- * @return void
*/
- function setBaseUrl($url) {
-
+ public function setBaseUrl(string $url)
+ {
$this->baseUrl = $url;
-
}
/**
* Returns the current base url.
- *
- * @return string
*/
- function getBaseUrl() {
-
+ public function getBaseUrl(): string
+ {
return $this->baseUrl;
-
}
/**
@@ -185,33 +159,29 @@ class Request extends Message implements RequestInterface {
* ISO-8859-1, it will convert it to UTF-8.
*
* If the path is outside of the base url, a LogicException will be thrown.
- *
- * @return string
*/
- function getPath() {
-
+ public function getPath(): string
+ {
// Removing duplicated slashes.
$uri = str_replace('//', '/', $this->getUrl());
$uri = Uri\normalize($uri);
$baseUri = Uri\normalize($this->getBaseUrl());
- if (strpos($uri, $baseUri) === 0) {
-
+ if (0 === strpos($uri, $baseUri)) {
// We're not interested in the query part (everything after the ?).
list($uri) = explode('?', $uri);
- return trim(URLUtil::decodePath(substr($uri, strlen($baseUri))), '/');
+ return trim(decodePath(substr($uri, strlen($baseUri))), '/');
}
- // A special case, if the baseUri was accessed without a trailing
- // slash, we'll accept it as well.
- elseif ($uri . '/' === $baseUri) {
+ if ($uri.'/' === $baseUri) {
return '';
-
}
+ // A special case, if the baseUri was accessed without a trailing
+ // slash, we'll accept it as well.
- throw new \LogicException('Requested uri (' . $this->getUrl() . ') is out of base uri (' . $this->getBaseUrl() . ')');
+ throw new \LogicException('Requested uri ('.$this->getUrl().') is out of base uri ('.$this->getBaseUrl().')');
}
/**
@@ -228,27 +198,20 @@ class Request extends Message implements RequestInterface {
*
* This would not have been needed, if POST data was accessible as
* php://input, but unfortunately we need to special case it.
- *
- * @param array $postData
- * @return void
*/
- function setPostData(array $postData) {
-
+ public function setPostData(array $postData)
+ {
$this->postData = $postData;
-
}
/**
* Returns the POST data.
*
* This is equivalent to PHP's $_POST superglobal.
- *
- * @return array
*/
- function getPostData() {
-
+ public function getPostData(): array
+ {
return $this->postData;
-
}
/**
@@ -263,54 +226,42 @@ class Request extends Message implements RequestInterface {
*
* If the value does not exist in the array, null is returned.
*
- * @param string $valueName
* @return string|null
*/
- function getRawServerValue($valueName) {
-
- if (isset($this->rawServerData[$valueName])) {
- return $this->rawServerData[$valueName];
- }
-
+ public function getRawServerValue(string $valueName)
+ {
+ return $this->rawServerData[$valueName] ?? null;
}
/**
* Sets the _SERVER array.
- *
- * @param array $data
- * @return void
*/
- function setRawServerData(array $data) {
-
+ public function setRawServerData(array $data)
+ {
$this->rawServerData = $data;
-
}
/**
* Serializes the request object as a string.
*
* This is useful for debugging purposes.
- *
- * @return string
*/
- function __toString() {
-
- $out = $this->getMethod() . ' ' . $this->getUrl() . ' HTTP/' . $this->getHTTPVersion() . "\r\n";
+ public function __toString(): string
+ {
+ $out = $this->getMethod().' '.$this->getUrl().' HTTP/'.$this->getHttpVersion()."\r\n";
foreach ($this->getHeaders() as $key => $value) {
foreach ($value as $v) {
- if ($key === 'Authorization') {
+ if ('Authorization' === $key) {
list($v) = explode(' ', $v, 2);
$v .= ' REDACTED';
}
- $out .= $key . ": " . $v . "\r\n";
+ $out .= $key.': '.$v."\r\n";
}
}
$out .= "\r\n";
$out .= $this->getBodyAsString();
return $out;
-
}
-
}
diff --git a/vendor/sabre/http/lib/RequestDecorator.php b/vendor/sabre/http/lib/RequestDecorator.php
index 7ee3f6fc8..0ad24925f 100644
--- a/vendor/sabre/http/lib/RequestDecorator.php
+++ b/vendor/sabre/http/lib/RequestDecorator.php
@@ -1,9 +1,11 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP;
/**
- * Request Decorator
+ * Request Decorator.
*
* This helper class allows you to easily create decorators for the Request
* object.
@@ -12,99 +14,72 @@ namespace Sabre\HTTP;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-class RequestDecorator implements RequestInterface {
-
+class RequestDecorator implements RequestInterface
+{
use MessageDecoratorTrait;
/**
* Constructor.
- *
- * @param RequestInterface $inner
*/
- function __construct(RequestInterface $inner) {
-
+ public function __construct(RequestInterface $inner)
+ {
$this->inner = $inner;
-
}
/**
- * Returns the current HTTP method
- *
- * @return string
+ * Returns the current HTTP method.
*/
- function getMethod() {
-
+ public function getMethod(): string
+ {
return $this->inner->getMethod();
-
}
/**
- * Sets the HTTP method
- *
- * @param string $method
- * @return void
+ * Sets the HTTP method.
*/
- function setMethod($method) {
-
+ public function setMethod(string $method)
+ {
$this->inner->setMethod($method);
-
}
/**
* Returns the request url.
- *
- * @return string
*/
- function getUrl() {
-
+ public function getUrl(): string
+ {
return $this->inner->getUrl();
-
}
/**
* Sets the request url.
- *
- * @param string $url
- * @return void
*/
- function setUrl($url) {
-
+ public function setUrl(string $url)
+ {
$this->inner->setUrl($url);
-
}
/**
* Returns the absolute url.
- *
- * @return string
*/
- function getAbsoluteUrl() {
-
+ public function getAbsoluteUrl(): string
+ {
return $this->inner->getAbsoluteUrl();
-
}
/**
* Sets the absolute url.
- *
- * @param string $url
- * @return void
*/
- function setAbsoluteUrl($url) {
-
+ public function setAbsoluteUrl(string $url)
+ {
$this->inner->setAbsoluteUrl($url);
-
}
/**
* Returns the current base url.
- *
- * @return string
*/
- function getBaseUrl() {
-
+ public function getBaseUrl(): string
+ {
return $this->inner->getBaseUrl();
-
}
/**
@@ -113,14 +88,10 @@ class RequestDecorator implements RequestInterface {
* This url is used for relative path calculations.
*
* The base url should default to /
- *
- * @param string $url
- * @return void
*/
- function setBaseUrl($url) {
-
+ public function setBaseUrl(string $url)
+ {
$this->inner->setBaseUrl($url);
-
}
/**
@@ -137,39 +108,30 @@ class RequestDecorator implements RequestInterface {
* ISO-8859-1, it will convert it to UTF-8.
*
* If the path is outside of the base url, a LogicException will be thrown.
- *
- * @return string
*/
- function getPath() {
-
+ public function getPath(): string
+ {
return $this->inner->getPath();
-
}
/**
* Returns the list of query parameters.
*
* This is equivalent to PHP's $_GET superglobal.
- *
- * @return array
*/
- function getQueryParameters() {
-
+ public function getQueryParameters(): array
+ {
return $this->inner->getQueryParameters();
-
}
/**
* Returns the POST data.
*
* This is equivalent to PHP's $_POST superglobal.
- *
- * @return array
*/
- function getPostData() {
-
+ public function getPostData(): array
+ {
return $this->inner->getPostData();
-
}
/**
@@ -179,53 +141,39 @@ class RequestDecorator implements RequestInterface {
*
* This would not have been needed, if POST data was accessible as
* php://input, but unfortunately we need to special case it.
- *
- * @param array $postData
- * @return void
*/
- function setPostData(array $postData) {
-
+ public function setPostData(array $postData)
+ {
$this->inner->setPostData($postData);
-
}
-
/**
* Returns an item from the _SERVER array.
*
* If the value does not exist in the array, null is returned.
*
- * @param string $valueName
* @return string|null
*/
- function getRawServerValue($valueName) {
-
+ public function getRawServerValue(string $valueName)
+ {
return $this->inner->getRawServerValue($valueName);
-
}
/**
* Sets the _SERVER array.
- *
- * @param array $data
- * @return void
*/
- function setRawServerData(array $data) {
-
+ public function setRawServerData(array $data)
+ {
$this->inner->setRawServerData($data);
-
}
/**
* Serializes the request object as a string.
*
* This is useful for debugging purposes.
- *
- * @return string
*/
- function __toString() {
-
+ public function __toString(): string
+ {
return $this->inner->__toString();
-
}
}
diff --git a/vendor/sabre/http/lib/RequestInterface.php b/vendor/sabre/http/lib/RequestInterface.php
index 63d9cbb51..83fa85bdc 100644
--- a/vendor/sabre/http/lib/RequestInterface.php
+++ b/vendor/sabre/http/lib/RequestInterface.php
@@ -1,5 +1,7 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP;
/**
@@ -9,59 +11,42 @@ namespace Sabre\HTTP;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-interface RequestInterface extends MessageInterface {
-
+interface RequestInterface extends MessageInterface
+{
/**
- * Returns the current HTTP method
- *
- * @return string
+ * Returns the current HTTP method.
*/
- function getMethod();
+ public function getMethod(): string;
/**
- * Sets the HTTP method
- *
- * @param string $method
- * @return void
+ * Sets the HTTP method.
*/
- function setMethod($method);
+ public function setMethod(string $method);
/**
* Returns the request url.
- *
- * @return string
*/
- function getUrl();
+ public function getUrl(): string;
/**
* Sets the request url.
- *
- * @param string $url
- * @return void
*/
- function setUrl($url);
+ public function setUrl(string $url);
/**
* Returns the absolute url.
- *
- * @return string
*/
- function getAbsoluteUrl();
+ public function getAbsoluteUrl(): string;
/**
* Sets the absolute url.
- *
- * @param string $url
- * @return void
*/
- function setAbsoluteUrl($url);
+ public function setAbsoluteUrl(string $url);
/**
* Returns the current base url.
- *
- * @return string
*/
- function getBaseUrl();
+ public function getBaseUrl(): string;
/**
* Sets a base url.
@@ -69,11 +54,8 @@ interface RequestInterface extends MessageInterface {
* This url is used for relative path calculations.
*
* The base url should default to /
- *
- * @param string $url
- * @return void
*/
- function setBaseUrl($url);
+ public function setBaseUrl(string $url);
/**
* Returns the relative path.
@@ -89,28 +71,22 @@ interface RequestInterface extends MessageInterface {
* ISO-8859-1, it will convert it to UTF-8.
*
* If the path is outside of the base url, a LogicException will be thrown.
- *
- * @return string
*/
- function getPath();
+ public function getPath(): string;
/**
* Returns the list of query parameters.
*
* This is equivalent to PHP's $_GET superglobal.
- *
- * @return array
*/
- function getQueryParameters();
+ public function getQueryParameters(): array;
/**
* Returns the POST data.
*
* This is equivalent to PHP's $_POST superglobal.
- *
- * @return array
*/
- function getPostData();
+ public function getPostData(): array;
/**
* Sets the post data.
@@ -119,29 +95,20 @@ interface RequestInterface extends MessageInterface {
*
* This would not have been needed, if POST data was accessible as
* php://input, but unfortunately we need to special case it.
- *
- * @param array $postData
- * @return void
*/
- function setPostData(array $postData);
+ public function setPostData(array $postData);
/**
* Returns an item from the _SERVER array.
*
* If the value does not exist in the array, null is returned.
*
- * @param string $valueName
* @return string|null
*/
- function getRawServerValue($valueName);
+ public function getRawServerValue(string $valueName);
/**
* Sets the _SERVER array.
- *
- * @param array $data
- * @return void
*/
- function setRawServerData(array $data);
-
-
+ public function setRawServerData(array $data);
}
diff --git a/vendor/sabre/http/lib/Response.php b/vendor/sabre/http/lib/Response.php
index 01920d8d9..64dfbc0b2 100644
--- a/vendor/sabre/http/lib/Response.php
+++ b/vendor/sabre/http/lib/Response.php
@@ -1,5 +1,7 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP;
/**
@@ -9,14 +11,14 @@ namespace Sabre\HTTP;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-class Response extends Message implements ResponseInterface {
-
+class Response extends Message implements ResponseInterface
+{
/**
* This is the list of currently registered HTTP status codes.
*
* @var array
*/
- static $statusCodes = [
+ public static $statusCodes = [
100 => 'Continue',
101 => 'Switching Protocols',
102 => 'Processing',
@@ -81,57 +83,55 @@ class Response extends Message implements ResponseInterface {
];
/**
- * HTTP status code
+ * HTTP status code.
*
* @var int
*/
protected $status;
/**
- * HTTP status text
+ * HTTP status text.
*
* @var string
*/
protected $statusText;
/**
- * Creates the response object
+ * Creates the response object.
*
* @param string|int $status
- * @param array $headers
- * @param resource $body
+ * @param array $headers
+ * @param resource $body
*/
- function __construct($status = null, array $headers = null, $body = null) {
-
- if (!is_null($status)) $this->setStatus($status);
- if (!is_null($headers)) $this->setHeaders($headers);
- if (!is_null($body)) $this->setBody($body);
-
+ public function __construct($status = 500, array $headers = null, $body = null)
+ {
+ if (null !== $status) {
+ $this->setStatus($status);
+ }
+ if (null !== $headers) {
+ $this->setHeaders($headers);
+ }
+ if (null !== $body) {
+ $this->setBody($body);
+ }
}
-
/**
* Returns the current HTTP status code.
- *
- * @return int
*/
- function getStatus() {
-
+ public function getStatus(): int
+ {
return $this->status;
-
}
/**
* Returns the human-readable status string.
*
* In the case of a 200, this may for example be 'OK'.
- *
- * @return string
*/
- function getStatusText() {
-
+ public function getStatusText(): string
+ {
return $this->statusText;
-
}
/**
@@ -144,21 +144,20 @@ class Response extends Message implements ResponseInterface {
* added.
*
* @param string|int $status
+ *
* @throws \InvalidArgumentException
- * @return void
*/
- function setStatus($status) {
-
+ public function setStatus($status)
+ {
if (ctype_digit($status) || is_int($status)) {
-
$statusCode = $status;
- $statusText = isset(self::$statusCodes[$status]) ? self::$statusCodes[$status] : 'Unknown';
-
+ $statusText = self::$statusCodes[$status] ?? 'Unknown';
} else {
list(
$statusCode,
$statusText
) = explode(' ', $status, 2);
+ $statusCode = (int) $statusCode;
}
if ($statusCode < 100 || $statusCode > 999) {
throw new \InvalidArgumentException('The HTTP status code must be exactly 3 digits');
@@ -166,28 +165,24 @@ class Response extends Message implements ResponseInterface {
$this->status = $statusCode;
$this->statusText = $statusText;
-
}
/**
* Serializes the response object as a string.
*
* This is useful for debugging purposes.
- *
- * @return string
*/
- function __toString() {
-
- $str = 'HTTP/' . $this->httpVersion . ' ' . $this->getStatus() . ' ' . $this->getStatusText() . "\r\n";
+ public function __toString(): string
+ {
+ $str = 'HTTP/'.$this->httpVersion.' '.$this->getStatus().' '.$this->getStatusText()."\r\n";
foreach ($this->getHeaders() as $key => $value) {
foreach ($value as $v) {
- $str .= $key . ": " . $v . "\r\n";
+ $str .= $key.': '.$v."\r\n";
}
}
$str .= "\r\n";
$str .= $this->getBodyAsString();
- return $str;
+ return $str;
}
-
}
diff --git a/vendor/sabre/http/lib/ResponseDecorator.php b/vendor/sabre/http/lib/ResponseDecorator.php
index db3a67507..289dba5cc 100644
--- a/vendor/sabre/http/lib/ResponseDecorator.php
+++ b/vendor/sabre/http/lib/ResponseDecorator.php
@@ -1,9 +1,11 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP;
/**
- * Response Decorator
+ * Response Decorator.
*
* This helper class allows you to easily create decorators for the Response
* object.
@@ -12,45 +14,36 @@ namespace Sabre\HTTP;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-class ResponseDecorator implements ResponseInterface {
-
+class ResponseDecorator implements ResponseInterface
+{
use MessageDecoratorTrait;
/**
* Constructor.
- *
- * @param ResponseInterface $inner
*/
- function __construct(ResponseInterface $inner) {
-
+ public function __construct(ResponseInterface $inner)
+ {
$this->inner = $inner;
-
}
/**
* Returns the current HTTP status code.
- *
- * @return int
*/
- function getStatus() {
-
+ public function getStatus(): int
+ {
return $this->inner->getStatus();
-
}
-
/**
* Returns the human-readable status string.
*
* In the case of a 200, this may for example be 'OK'.
- *
- * @return string
*/
- function getStatusText() {
-
+ public function getStatusText(): string
+ {
return $this->inner->getStatusText();
-
}
+
/**
* Sets the HTTP status code.
*
@@ -61,12 +54,10 @@ class ResponseDecorator implements ResponseInterface {
* added.
*
* @param string|int $status
- * @return void
*/
- function setStatus($status) {
-
+ public function setStatus($status)
+ {
$this->inner->setStatus($status);
-
}
/**
@@ -76,9 +67,8 @@ class ResponseDecorator implements ResponseInterface {
*
* @return string
*/
- function __toString() {
-
+ public function __toString(): string
+ {
return $this->inner->__toString();
-
}
}
diff --git a/vendor/sabre/http/lib/ResponseInterface.php b/vendor/sabre/http/lib/ResponseInterface.php
index 411cdc06c..9bd93f179 100644
--- a/vendor/sabre/http/lib/ResponseInterface.php
+++ b/vendor/sabre/http/lib/ResponseInterface.php
@@ -1,5 +1,7 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP;
/**
@@ -9,23 +11,19 @@ namespace Sabre\HTTP;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-interface ResponseInterface extends MessageInterface {
-
+interface ResponseInterface extends MessageInterface
+{
/**
* Returns the current HTTP status code.
- *
- * @return int
*/
- function getStatus();
+ public function getStatus(): int;
/**
* Returns the human-readable status string.
*
* In the case of a 200, this may for example be 'OK'.
- *
- * @return string
*/
- function getStatusText();
+ public function getStatusText(): string;
/**
* Sets the HTTP status code.
@@ -37,9 +35,8 @@ interface ResponseInterface extends MessageInterface {
* added.
*
* @param string|int $status
+ *
* @throws \InvalidArgumentException
- * @return void
*/
- function setStatus($status);
-
+ public function setStatus($status);
}
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;
}
-
}
diff --git a/vendor/sabre/http/lib/URLUtil.php b/vendor/sabre/http/lib/URLUtil.php
deleted file mode 100644
index 85c0e1150..000000000
--- a/vendor/sabre/http/lib/URLUtil.php
+++ /dev/null
@@ -1,103 +0,0 @@
-<?php
-
-namespace Sabre\HTTP;
-
-use Sabre\URI;
-
-/**
- * URL utility class
- *
- * Note: this class is deprecated. All its functionality moved to functions.php
- * or sabre\uri.
- *
- * @deprecated
- * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class URLUtil {
-
- /**
- * Encodes the path of a url.
- *
- * slashes (/) are treated as path-separators.
- *
- * @deprecated use \Sabre\HTTP\encodePath()
- * @param string $path
- * @return string
- */
- static function encodePath($path) {
-
- return encodePath($path);
-
- }
-
- /**
- * Encodes a 1 segment of a path
- *
- * Slashes are considered part of the name, and are encoded as %2f
- *
- * @deprecated use \Sabre\HTTP\encodePathSegment()
- * @param string $pathSegment
- * @return string
- */
- static function encodePathSegment($pathSegment) {
-
- return encodePathSegment($pathSegment);
-
- }
-
- /**
- * Decodes a url-encoded path
- *
- * @deprecated use \Sabre\HTTP\decodePath
- * @param string $path
- * @return string
- */
- static function decodePath($path) {
-
- return decodePath($path);
-
- }
-
- /**
- * Decodes a url-encoded path segment
- *
- * @deprecated use \Sabre\HTTP\decodePathSegment()
- * @param string $path
- * @return string
- */
- static function decodePathSegment($path) {
-
- return decodePathSegment($path);
-
- }
-
- /**
- * Returns the 'dirname' and 'basename' for a path.
- *
- * @deprecated Use Sabre\Uri\split().
- * @param string $path
- * @return array
- */
- static function splitPath($path) {
-
- return Uri\split($path);
-
- }
-
- /**
- * Resolves relative urls, like a browser would.
- *
- * @deprecated Use Sabre\Uri\resolve().
- * @param string $basePath
- * @param string $newPath
- * @return string
- */
- static function resolve($basePath, $newPath) {
-
- return Uri\resolve($basePath, $newPath);
-
- }
-
-}
diff --git a/vendor/sabre/http/lib/Util.php b/vendor/sabre/http/lib/Util.php
deleted file mode 100644
index e3f13a645..000000000
--- a/vendor/sabre/http/lib/Util.php
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-
-namespace Sabre\HTTP;
-
-/**
- * HTTP utility methods
- *
- * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
- * @author Evert Pot (http://evertpot.com/)
- * @author Paul Voegler
- * @deprecated All these functions moved to functions.php
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Util {
-
- /**
- * Content negotiation
- *
- * @deprecated Use \Sabre\HTTP\negotiateContentType
- * @param string|null $acceptHeaderValue
- * @param array $availableOptions
- * @return string|null
- */
- static function negotiateContentType($acceptHeaderValue, array $availableOptions) {
-
- return negotiateContentType($acceptHeaderValue, $availableOptions);
-
- }
-
- /**
- * Deprecated! Use negotiateContentType.
- *
- * @deprecated Use \Sabre\HTTP\NegotiateContentType
- * @param string|null $acceptHeaderValue
- * @param array $availableOptions
- * @return string|null
- */
- static function negotiate($acceptHeaderValue, array $availableOptions) {
-
- return negotiateContentType($acceptHeaderValue, $availableOptions);
-
- }
-
- /**
- * Parses a RFC2616-compatible date string
- *
- * This method returns false if the date is invalid
- *
- * @deprecated Use parseDate
- * @param string $dateHeader
- * @return bool|DateTime
- */
- static function parseHTTPDate($dateHeader) {
-
- return parseDate($dateHeader);
-
- }
-
- /**
- * Transforms a DateTime object to HTTP's most common date format.
- *
- * We're serializing it as the RFC 1123 date, which, for HTTP must be
- * specified as GMT.
- *
- * @deprecated Use toDate
- * @param \DateTime $dateTime
- * @return string
- */
- static function toHTTPDate(\DateTime $dateTime) {
-
- return toDate($dateTime);
-
- }
-}
diff --git a/vendor/sabre/http/lib/Version.php b/vendor/sabre/http/lib/Version.php
index c40532ae8..20a401773 100644
--- a/vendor/sabre/http/lib/Version.php
+++ b/vendor/sabre/http/lib/Version.php
@@ -1,19 +1,20 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP;
/**
- * This class contains the version number for the HTTP package
+ * This class contains the version number for the HTTP package.
*
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-class Version {
-
+class Version
+{
/**
- * Full version number
+ * Full version number.
*/
- const VERSION = '4.2.4';
-
+ const VERSION = '5.0.4';
}
diff --git a/vendor/sabre/http/lib/functions.php b/vendor/sabre/http/lib/functions.php
index d94119623..197a9e661 100644
--- a/vendor/sabre/http/lib/functions.php
+++ b/vendor/sabre/http/lib/functions.php
@@ -1,8 +1,11 @@
<?php
+declare(strict_types=1);
+
namespace Sabre\HTTP;
use DateTime;
+use InvalidArgumentException;
/**
* A collection of useful helpers for parsing or generating various HTTP
@@ -27,61 +30,64 @@ use DateTime;
* http://tools.ietf.org/html/rfc7231#section-7.1.1.1
*
* @param string $dateString
+ *
* @return bool|DateTime
*/
-function parseDate($dateString) {
-
+function parseDate(string $dateString)
+{
// Only the format is checked, valid ranges are checked by strtotime below
$month = '(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)';
$weekday = '(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)';
$wkday = '(Mon|Tue|Wed|Thu|Fri|Sat|Sun)';
$time = '([0-1]\d|2[0-3])(\:[0-5]\d){2}';
- $date3 = $month . ' ([12]\d|3[01]| [1-9])';
- $date2 = '(0[1-9]|[12]\d|3[01])\-' . $month . '\-\d{2}';
+ $date3 = $month.' ([12]\d|3[01]| [1-9])';
+ $date2 = '(0[1-9]|[12]\d|3[01])\-'.$month.'\-\d{2}';
// 4-digit year cannot begin with 0 - unix timestamp begins in 1970
- $date1 = '(0[1-9]|[12]\d|3[01]) ' . $month . ' [1-9]\d{3}';
+ $date1 = '(0[1-9]|[12]\d|3[01]) '.$month.' [1-9]\d{3}';
// ANSI C's asctime() format
// 4-digit year cannot begin with 0 - unix timestamp begins in 1970
- $asctime_date = $wkday . ' ' . $date3 . ' ' . $time . ' [1-9]\d{3}';
+ $asctime_date = $wkday.' '.$date3.' '.$time.' [1-9]\d{3}';
// RFC 850, obsoleted by RFC 1036
- $rfc850_date = $weekday . ', ' . $date2 . ' ' . $time . ' GMT';
+ $rfc850_date = $weekday.', '.$date2.' '.$time.' GMT';
// RFC 822, updated by RFC 1123
- $rfc1123_date = $wkday . ', ' . $date1 . ' ' . $time . ' GMT';
+ $rfc1123_date = $wkday.', '.$date1.' '.$time.' GMT';
// allowed date formats by RFC 2616
$HTTP_date = "($rfc1123_date|$rfc850_date|$asctime_date)";
// allow for space around the string and strip it
$dateString = trim($dateString, ' ');
- if (!preg_match('/^' . $HTTP_date . '$/', $dateString))
+ if (!preg_match('/^'.$HTTP_date.'$/', $dateString)) {
return false;
+ }
// append implicit GMT timezone to ANSI C time format
- if (strpos($dateString, ' GMT') === false)
+ if (false === strpos($dateString, ' GMT')) {
$dateString .= ' GMT';
+ }
try {
return new DateTime($dateString, new \DateTimeZone('UTC'));
} catch (\Exception $e) {
return false;
}
-
}
/**
- * Transforms a DateTime object to a valid HTTP/1.1 Date header value
+ * Transforms a DateTime object to a valid HTTP/1.1 Date header value.
*
* @param DateTime $dateTime
+ *
* @return string
*/
-function toDate(DateTime $dateTime) {
-
+function toDate(DateTime $dateTime): string
+{
// We need to clone it, as we don't want to affect the existing
// DateTime.
$dateTime = clone $dateTime;
$dateTime->setTimezone(new \DateTimeZone('GMT'));
- return $dateTime->format('D, d M Y H:i:s \G\M\T');
+ return $dateTime->format('D, d M Y H:i:s \G\M\T');
}
/**
@@ -101,11 +107,12 @@ function toDate(DateTime $dateTime) {
* implying that no accept header was sent.
*
* @param string|null $acceptHeaderValue
- * @param array $availableOptions
+ * @param array $availableOptions
+ *
* @return string|null
*/
-function negotiateContentType($acceptHeaderValue, array $availableOptions) {
-
+function negotiateContentType($acceptHeaderValue, array $availableOptions)
+{
if (!$acceptHeaderValue) {
// Grabbing the first in the list.
return reset($availableOptions);
@@ -130,9 +137,10 @@ function negotiateContentType($acceptHeaderValue, array $availableOptions) {
$lastChoice = null;
foreach ($proposals as $proposal) {
-
// Ignoring broken values.
- if (is_null($proposal)) continue;
+ if (null === $proposal) {
+ continue;
+ }
// If the quality is lower we don't have to bother comparing.
if ($proposal['quality'] < $lastQuality) {
@@ -140,12 +148,11 @@ function negotiateContentType($acceptHeaderValue, array $availableOptions) {
}
foreach ($options as $optionIndex => $option) {
-
- if ($proposal['type'] !== '*' && $proposal['type'] !== $option['type']) {
+ if ('*' !== $proposal['type'] && $proposal['type'] !== $option['type']) {
// no match on type.
continue;
}
- if ($proposal['subType'] !== '*' && $proposal['subType'] !== $option['subType']) {
+ if ('*' !== $proposal['subType'] && $proposal['subType'] !== $option['subType']) {
// no match on subtype.
continue;
}
@@ -165,31 +172,25 @@ function negotiateContentType($acceptHeaderValue, array $availableOptions) {
// subtype. We need to calculate a score for how specific the
// match was.
$specificity =
- ($proposal['type'] !== '*' ? 20 : 0) +
- ($proposal['subType'] !== '*' ? 10 : 0) +
+ ('*' !== $proposal['type'] ? 20 : 0) +
+ ('*' !== $proposal['subType'] ? 10 : 0) +
count($option['parameters']);
-
// Does this entry win?
if (
($proposal['quality'] > $lastQuality) ||
($proposal['quality'] === $lastQuality && $specificity > $lastSpecificity) ||
($proposal['quality'] === $lastQuality && $specificity === $lastSpecificity && $optionIndex < $lastOptionIndex)
) {
-
$lastQuality = $proposal['quality'];
$lastSpecificity = $specificity;
$lastOptionIndex = $optionIndex;
$lastChoice = $availableOptions[$optionIndex];
-
}
-
}
-
}
return $lastChoice;
-
}
/**
@@ -217,10 +218,11 @@ function negotiateContentType($acceptHeaderValue, array $availableOptions) {
* uses them.
*
* @param string|string[] $input
+ *
* @return array
*/
-function parsePrefer($input) {
-
+function parsePrefer($input): array
+{
$token = '[!#$%&\'*+\-.^_`~A-Za-z0-9]+';
// Work in progress
@@ -241,7 +243,6 @@ REGEX;
$output = [];
foreach (getHeaderValues($input) as $value) {
-
if (!preg_match($regex, $value, $matches)) {
// Ignore
continue;
@@ -249,22 +250,22 @@ REGEX;
// Mapping old values to their new counterparts
switch ($matches['name']) {
- case 'return-asynch' :
+ case 'return-asynch':
$output['respond-async'] = true;
break;
- case 'return-representation' :
+ case 'return-representation':
$output['return'] = 'representation';
break;
- case 'return-minimal' :
+ case 'return-minimal':
$output['return'] = 'minimal';
break;
- case 'strict' :
+ case 'strict':
$output['handling'] = 'strict';
break;
- case 'lenient' :
+ case 'lenient':
$output['handling'] = 'lenient';
break;
- default :
+ default:
if (isset($matches['value'])) {
$value = trim($matches['value'], '"');
} else {
@@ -273,11 +274,9 @@ REGEX;
$output[strtolower($matches['name'])] = empty($value) ? true : $value;
break;
}
-
}
return $output;
-
}
/**
@@ -296,25 +295,26 @@ REGEX;
*
* @param string|string[] $values
* @param string|string[] $values2
- * @return string[]
*/
-function getHeaderValues($values, $values2 = null) {
-
- $values = (array)$values;
+function getHeaderValues($values, $values2 = null): array
+{
+ $values = (array) $values;
if ($values2) {
- $values = array_merge($values, (array)$values2);
+ $values = array_merge($values, (array) $values2);
}
+
+ $result = array();
foreach ($values as $l1) {
foreach (explode(',', $l1) as $l2) {
$result[] = trim($l2);
}
}
- return $result;
+ return $result;
}
/**
- * Parses a mime-type and splits it into:
+ * Parses a mime-type and splits it into:.
*
* 1. type
* 2. subtype
@@ -322,10 +322,11 @@ function getHeaderValues($values, $values2 = null) {
* 4. parameters
*
* @param string $str
+ *
* @return array
*/
-function parseMimeType($str) {
-
+function parseMimeType(string $str): array
+{
$parameters = [];
// If no q= parameter appears, then quality = 1.
$quality = 1;
@@ -333,17 +334,22 @@ function parseMimeType($str) {
$parts = explode(';', $str);
// The first part is the mime-type.
- $mimeType = array_shift($parts);
+ $mimeType = trim(array_shift($parts));
+
+ if ('*' === $mimeType) {
+ $mimeType = '*/*';
+ }
- $mimeType = explode('/', trim($mimeType));
- if (count($mimeType) !== 2) {
+ $mimeType = explode('/', $mimeType);
+ if (2 !== count($mimeType)) {
// Illegal value
- return null;
+ var_dump($mimeType);
+ die();
+ throw new InvalidArgumentException('Not a valid mime-type: '.$str);
}
list($type, $subType) = $mimeType;
foreach ($parts as $part) {
-
$part = trim($part);
if (strpos($part, '=')) {
list($partName, $partValue) =
@@ -357,89 +363,66 @@ function parseMimeType($str) {
// the parameter list. Anything after the q= counts as an
// 'accept extension' and could introduce new semantics in
// content-negotation.
- if ($partName !== 'q') {
+ if ('q' !== $partName) {
$parameters[$partName] = $part;
} else {
- $quality = (float)$partValue;
+ $quality = (float) $partValue;
break; // Stop parsing parts
}
-
}
return [
- 'type' => $type,
- 'subType' => $subType,
- 'quality' => $quality,
+ 'type' => $type,
+ 'subType' => $subType,
+ 'quality' => $quality,
'parameters' => $parameters,
];
-
}
/**
* Encodes the path of a url.
*
* slashes (/) are treated as path-separators.
- *
- * @param string $path
- * @return string
*/
-function encodePath($path) {
-
- return preg_replace_callback('/([^A-Za-z0-9_\-\.~\(\)\/:@])/', function($match) {
-
- return '%' . sprintf('%02x', ord($match[0]));
-
+function encodePath(string $path): string
+{
+ return preg_replace_callback('/([^A-Za-z0-9_\-\.~\(\)\/:@])/', function ($match) {
+ return '%'.sprintf('%02x', ord($match[0]));
}, $path);
-
}
/**
- * Encodes a 1 segment of a path
+ * Encodes a 1 segment of a path.
*
* Slashes are considered part of the name, and are encoded as %2f
- *
- * @param string $pathSegment
- * @return string
*/
-function encodePathSegment($pathSegment) {
-
- return preg_replace_callback('/([^A-Za-z0-9_\-\.~\(\):@])/', function($match) {
-
- return '%' . sprintf('%02x', ord($match[0]));
-
+function encodePathSegment(string $pathSegment): string
+{
+ return preg_replace_callback('/([^A-Za-z0-9_\-\.~\(\):@])/', function ($match) {
+ return '%'.sprintf('%02x', ord($match[0]));
}, $pathSegment);
}
/**
- * Decodes a url-encoded path
- *
- * @param string $path
- * @return string
+ * Decodes a url-encoded path.
*/
-function decodePath($path) {
-
+function decodePath(string $path): string
+{
return decodePathSegment($path);
-
}
/**
- * Decodes a url-encoded path segment
- *
- * @param string $path
- * @return string
+ * Decodes a url-encoded path segment.
*/
-function decodePathSegment($path) {
-
+function decodePathSegment(string $path): string
+{
$path = rawurldecode($path);
$encoding = mb_detect_encoding($path, ['UTF-8', 'ISO-8859-1']);
switch ($encoding) {
-
- case 'ISO-8859-1' :
+ case 'ISO-8859-1':
$path = utf8_encode($path);
-
}
return $path;
-
}