first commit
This commit is contained in:
85
vendor/nyholm/psr7/CHANGELOG.md
vendored
Normal file
85
vendor/nyholm/psr7/CHANGELOG.md
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file, in reverse chronological order by release.
|
||||
|
||||
## 1.2.1
|
||||
|
||||
### Changed
|
||||
|
||||
- Added `.github` and `phpstan.neon.dist` to `.gitattributes`.
|
||||
|
||||
## 1.2.0
|
||||
|
||||
### Changed
|
||||
|
||||
- Change minimal port number to 0 (unix socket)
|
||||
- Updated `Psr17Factory::createResponse` to respect the specification. If second
|
||||
argument is not used, a standard reason phrase. If an empty string is passed,
|
||||
then the reason phrase will be empty.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Check for seekable on the stream resource.
|
||||
- Fixed the `Response::$reason` should never be null.
|
||||
|
||||
## 1.1.0
|
||||
|
||||
### Added
|
||||
|
||||
- Improved performance
|
||||
- More tests for `UploadedFile` and `HttplugFactory`
|
||||
|
||||
### Removed
|
||||
|
||||
- Dead code
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Fixed
|
||||
|
||||
- Handle `fopen` failing in createStreamFromFile according to PSR-7.
|
||||
- Reduce execution path to speed up performance.
|
||||
- Fixed typos.
|
||||
- Code style.
|
||||
|
||||
## 1.0.0
|
||||
|
||||
### Added
|
||||
|
||||
- Support for final PSR-17 (HTTP factories). (`Psr17Factory`)
|
||||
- Support for numeric header values.
|
||||
- Support for empty header values.
|
||||
- All classes are final
|
||||
- `HttplugFactory` that implements factory interfaces from HTTPlug.
|
||||
|
||||
### Changed
|
||||
|
||||
- `ServerRequest` does not extend `Request`.
|
||||
|
||||
### Removed
|
||||
|
||||
- The HTTPlug discovery strategy was removed since it is included in php-http/discovery 1.4.
|
||||
- `UploadedFileFactory()` was removed in favor for `Psr17Factory`.
|
||||
- `ServerRequestFactory()` was removed in favor for `Psr17Factory`.
|
||||
- `StreamFactory`, `UriFactory`, abd `MessageFactory`. Use `HttplugFactory` instead.
|
||||
- `ServerRequestFactory::createServerRequestFromArray`, `ServerRequestFactory::createServerRequestFromArrays` and
|
||||
`ServerRequestFactory::createServerRequestFromGlobals`. Please use the new `nyholm/psr7-server` instead.
|
||||
|
||||
## 0.3.0
|
||||
|
||||
### Added
|
||||
|
||||
- Return types.
|
||||
- Many `InvalidArgumentException`s are thrown when you use invalid arguments.
|
||||
- Integration tests for `UploadedFile` and `ServerRequest`.
|
||||
|
||||
### Changed
|
||||
|
||||
- We dropped PHP7.0 support.
|
||||
- PSR-17 factories have been marked as internal. They do not fall under our BC promise until PSR-17 is accepted.
|
||||
- `UploadedFileFactory::createUploadedFile` does not accept a string file path.
|
||||
|
||||
## 0.2.3
|
||||
|
||||
No changelog before this release
|
||||
|
21
vendor/nyholm/psr7/LICENSE
vendored
Normal file
21
vendor/nyholm/psr7/LICENSE
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016 Tobias Nyholm
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
111
vendor/nyholm/psr7/README.md
vendored
Normal file
111
vendor/nyholm/psr7/README.md
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
# PSR-7 implementation
|
||||
|
||||
[](https://github.com/Nyholm/psr7/releases)
|
||||
[](https://travis-ci.org/Nyholm/psr7)
|
||||
[](https://scrutinizer-ci.com/g/Nyholm/psr7)
|
||||
[](https://scrutinizer-ci.com/g/Nyholm/psr7)
|
||||
[](https://packagist.org/packages/nyholm/psr7)
|
||||
[](https://packagist.org/packages/nyholm/psr7)
|
||||
[](LICENSE)
|
||||
|
||||
|
||||
A super lightweight PSR-7 implementation. Very strict and very fast.
|
||||
|
||||
| Description | Guzzle | Zend | Slim | Nyholm |
|
||||
| ---- | ------ | ---- | ---- | ------ |
|
||||
| Lines of code | 3 000 | 3 000 | 1 700 | 1 000 |
|
||||
| PHP7 | No | Yes | No | Yes |
|
||||
| PSR-7* | 66% | 100% | 75% | 100% |
|
||||
| PSR-17 | No | Yes | Yes | Yes |
|
||||
| HTTPlug | No | No | No | Yes |
|
||||
| Performance** | 1.34x | 1x | 1.16x | 1.75x |
|
||||
|
||||
\* Percent of completed tests in https://github.com/php-http/psr7-integration-tests
|
||||
|
||||
\** See benchmark at https://github.com/Nyholm/http-client-benchmark (higher is better)
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
composer require nyholm/psr7
|
||||
```
|
||||
|
||||
If you are using Symfony Flex then you get all message factories registered as services.
|
||||
|
||||
## Usage
|
||||
|
||||
The PSR-7 objects do not contain any other public methods than those defined in
|
||||
the [PSR-7 specification](https://www.php-fig.org/psr/psr-7/).
|
||||
|
||||
### Create objects
|
||||
|
||||
Use the PSR-17 factory to create requests, streams, URIs etc.
|
||||
|
||||
```php
|
||||
$psr17Factory = new \Nyholm\Psr7\Factory\Psr17Factory();
|
||||
$request = $psr17Factory->createRequest('GET', 'http://tnyholm.se');
|
||||
$stream = $psr17Factory->createStream('foobar');
|
||||
```
|
||||
|
||||
### Sending a request
|
||||
|
||||
With [HTTPlug](http://httplug.io/) or any other PSR-18 (HTTP client) you may send
|
||||
requests like:
|
||||
|
||||
```bash
|
||||
composer require kriswallsmith/buzz
|
||||
```
|
||||
|
||||
```php
|
||||
$psr17Factory = new \Nyholm\Psr7\Factory\Psr17Factory();
|
||||
$psr18Client = new \Buzz\Client\Curl($psr17Factory);
|
||||
|
||||
$request = $psr17Factory->createRequest('GET', 'http://tnyholm.se');
|
||||
$response = $psr18Client->sendRequest($request);
|
||||
```
|
||||
|
||||
### Create server requests
|
||||
|
||||
The [`nyholm/psr7-server`](https://github.com/Nyholm/psr7-server) package can be used
|
||||
to create server requests from PHP superglobals.
|
||||
|
||||
```bash
|
||||
composer require nyholm/psr7-server
|
||||
```
|
||||
|
||||
```php
|
||||
$psr17Factory = new \Nyholm\Psr7\Factory\Psr17Factory();
|
||||
|
||||
$creator = new \Nyholm\Psr7Server\ServerRequestCreator(
|
||||
$psr17Factory, // ServerRequestFactory
|
||||
$psr17Factory, // UriFactory
|
||||
$psr17Factory, // UploadedFileFactory
|
||||
$psr17Factory // StreamFactory
|
||||
);
|
||||
|
||||
$serverRequest = $creator->fromGlobals();
|
||||
```
|
||||
|
||||
### Emitting a response
|
||||
|
||||
```bash
|
||||
composer require zendframework/zend-httphandlerrunner
|
||||
```
|
||||
|
||||
```php
|
||||
$psr17Factory = new \Nyholm\Psr7\Factory\Psr17Factory();
|
||||
|
||||
$responseBody = $psr17Factory->createStream('Hello world');
|
||||
$response = $psr17Factory->createResponse(200)->withBody($responseBody);
|
||||
(new \Zend\HttpHandlerRunner\Emitter\SapiEmitter())->emit($response);
|
||||
```
|
||||
|
||||
## Our goal
|
||||
|
||||
This package is currently maintained by [Tobias Nyholm](http://nyholm.se) and
|
||||
[Martijn van der Ven](https://vanderven.se/martijn/). They have decided that the
|
||||
goal of this library should be to provide a super strict implementation of
|
||||
[PSR-7](https://www.php-fig.org/psr/psr-7/) that is blazing fast.
|
||||
|
||||
The package will never include any extra features nor helper methods. All our classes
|
||||
and functions exist because they are required to fulfill the PSR-7 specification.
|
40
vendor/nyholm/psr7/src/Factory/HttplugFactory.php
vendored
Normal file
40
vendor/nyholm/psr7/src/Factory/HttplugFactory.php
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Nyholm\Psr7\Factory;
|
||||
|
||||
use Http\Message\{MessageFactory, StreamFactory, UriFactory};
|
||||
use Nyholm\Psr7\{Request, Response, Stream, Uri};
|
||||
use Psr\Http\Message\UriInterface;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
* @author Martijn van der Ven <martijn@vanderven.se>
|
||||
*/
|
||||
final class HttplugFactory implements MessageFactory, StreamFactory, UriFactory
|
||||
{
|
||||
public function createRequest($method, $uri, array $headers = [], $body = null, $protocolVersion = '1.1')
|
||||
{
|
||||
return new Request($method, $uri, $headers, $body, $protocolVersion);
|
||||
}
|
||||
|
||||
public function createResponse($statusCode = 200, $reasonPhrase = null, array $headers = [], $body = null, $version = '1.1')
|
||||
{
|
||||
return new Response((int) $statusCode, $headers, $body, $version, $reasonPhrase);
|
||||
}
|
||||
|
||||
public function createStream($body = null)
|
||||
{
|
||||
return Stream::create($body ?? '');
|
||||
}
|
||||
|
||||
public function createUri($uri = ''): UriInterface
|
||||
{
|
||||
if ($uri instanceof UriInterface) {
|
||||
return $uri;
|
||||
}
|
||||
|
||||
return new Uri($uri);
|
||||
}
|
||||
}
|
73
vendor/nyholm/psr7/src/Factory/Psr17Factory.php
vendored
Normal file
73
vendor/nyholm/psr7/src/Factory/Psr17Factory.php
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Nyholm\Psr7\Factory;
|
||||
|
||||
use Nyholm\Psr7\{Request, Response, ServerRequest, Stream, UploadedFile, Uri};
|
||||
use Psr\Http\Message\{RequestFactoryInterface, RequestInterface, ResponseFactoryInterface, ResponseInterface, ServerRequestFactoryInterface, ServerRequestInterface, StreamFactoryInterface, StreamInterface, UploadedFileFactoryInterface, UploadedFileInterface, UriFactoryInterface, UriInterface};
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
* @author Martijn van der Ven <martijn@vanderven.se>
|
||||
*/
|
||||
final class Psr17Factory implements RequestFactoryInterface, ResponseFactoryInterface, ServerRequestFactoryInterface, StreamFactoryInterface, UploadedFileFactoryInterface, UriFactoryInterface
|
||||
{
|
||||
public function createRequest(string $method, $uri): RequestInterface
|
||||
{
|
||||
return new Request($method, $uri);
|
||||
}
|
||||
|
||||
public function createResponse(int $code = 200, string $reasonPhrase = ''): ResponseInterface
|
||||
{
|
||||
if (2 > \func_num_args()) {
|
||||
// This will make the Response class to use a custom reasonPhrase
|
||||
$reasonPhrase = null;
|
||||
}
|
||||
|
||||
return new Response($code, [], null, '1.1', $reasonPhrase);
|
||||
}
|
||||
|
||||
public function createStream(string $content = ''): StreamInterface
|
||||
{
|
||||
return Stream::create($content);
|
||||
}
|
||||
|
||||
public function createStreamFromFile(string $filename, string $mode = 'r'): StreamInterface
|
||||
{
|
||||
$resource = @\fopen($filename, $mode);
|
||||
if (false === $resource) {
|
||||
if ('' === $mode || false === \in_array($mode[0], ['r', 'w', 'a', 'x', 'c'])) {
|
||||
throw new \InvalidArgumentException('The mode ' . $mode . ' is invalid.');
|
||||
}
|
||||
|
||||
throw new \RuntimeException('The file ' . $filename . ' cannot be opened.');
|
||||
}
|
||||
|
||||
return Stream::create($resource);
|
||||
}
|
||||
|
||||
public function createStreamFromResource($resource): StreamInterface
|
||||
{
|
||||
return Stream::create($resource);
|
||||
}
|
||||
|
||||
public function createUploadedFile(StreamInterface $stream, int $size = null, int $error = \UPLOAD_ERR_OK, string $clientFilename = null, string $clientMediaType = null): UploadedFileInterface
|
||||
{
|
||||
if (null === $size) {
|
||||
$size = $stream->getSize();
|
||||
}
|
||||
|
||||
return new UploadedFile($stream, $size, $error, $clientFilename, $clientMediaType);
|
||||
}
|
||||
|
||||
public function createUri(string $uri = ''): UriInterface
|
||||
{
|
||||
return new Uri($uri);
|
||||
}
|
||||
|
||||
public function createServerRequest(string $method, $uri, array $serverParams = []): ServerRequestInterface
|
||||
{
|
||||
return new ServerRequest($method, $uri, [], null, '1.1', $serverParams);
|
||||
}
|
||||
}
|
202
vendor/nyholm/psr7/src/MessageTrait.php
vendored
Normal file
202
vendor/nyholm/psr7/src/MessageTrait.php
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Nyholm\Psr7;
|
||||
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
/**
|
||||
* Trait implementing functionality common to requests and responses.
|
||||
*
|
||||
* @author Michael Dowling and contributors to guzzlehttp/psr7
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
* @author Martijn van der Ven <martijn@vanderven.se>
|
||||
*
|
||||
* @internal should not be used outside of Nyholm/Psr7 as it does not fall under our BC promise
|
||||
*/
|
||||
trait MessageTrait
|
||||
{
|
||||
/** @var array Map of all registered headers, as original name => array of values */
|
||||
private $headers = [];
|
||||
|
||||
/** @var array Map of lowercase header name => original name at registration */
|
||||
private $headerNames = [];
|
||||
|
||||
/** @var string */
|
||||
private $protocol = '1.1';
|
||||
|
||||
/** @var StreamInterface|null */
|
||||
private $stream;
|
||||
|
||||
public function getProtocolVersion(): string
|
||||
{
|
||||
return $this->protocol;
|
||||
}
|
||||
|
||||
public function withProtocolVersion($version): self
|
||||
{
|
||||
if ($this->protocol === $version) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$new = clone $this;
|
||||
$new->protocol = $version;
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function getHeaders(): array
|
||||
{
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
public function hasHeader($header): bool
|
||||
{
|
||||
return isset($this->headerNames[\strtolower($header)]);
|
||||
}
|
||||
|
||||
public function getHeader($header): array
|
||||
{
|
||||
$header = \strtolower($header);
|
||||
if (!isset($this->headerNames[$header])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$header = $this->headerNames[$header];
|
||||
|
||||
return $this->headers[$header];
|
||||
}
|
||||
|
||||
public function getHeaderLine($header): string
|
||||
{
|
||||
return \implode(', ', $this->getHeader($header));
|
||||
}
|
||||
|
||||
public function withHeader($header, $value): self
|
||||
{
|
||||
$value = $this->validateAndTrimHeader($header, $value);
|
||||
$normalized = \strtolower($header);
|
||||
|
||||
$new = clone $this;
|
||||
if (isset($new->headerNames[$normalized])) {
|
||||
unset($new->headers[$new->headerNames[$normalized]]);
|
||||
}
|
||||
$new->headerNames[$normalized] = $header;
|
||||
$new->headers[$header] = $value;
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function withAddedHeader($header, $value): self
|
||||
{
|
||||
if (!\is_string($header) || '' === $header) {
|
||||
throw new \InvalidArgumentException('Header name must be an RFC 7230 compatible string.');
|
||||
}
|
||||
|
||||
$new = clone $this;
|
||||
$new->setHeaders([$header => $value]);
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function withoutHeader($header): self
|
||||
{
|
||||
$normalized = \strtolower($header);
|
||||
if (!isset($this->headerNames[$normalized])) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$header = $this->headerNames[$normalized];
|
||||
$new = clone $this;
|
||||
unset($new->headers[$header], $new->headerNames[$normalized]);
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function getBody(): StreamInterface
|
||||
{
|
||||
if (null === $this->stream) {
|
||||
$this->stream = Stream::create('');
|
||||
}
|
||||
|
||||
return $this->stream;
|
||||
}
|
||||
|
||||
public function withBody(StreamInterface $body): self
|
||||
{
|
||||
if ($body === $this->stream) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$new = clone $this;
|
||||
$new->stream = $body;
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
private function setHeaders(array $headers): void
|
||||
{
|
||||
foreach ($headers as $header => $value) {
|
||||
$value = $this->validateAndTrimHeader($header, $value);
|
||||
$normalized = \strtolower($header);
|
||||
if (isset($this->headerNames[$normalized])) {
|
||||
$header = $this->headerNames[$normalized];
|
||||
$this->headers[$header] = \array_merge($this->headers[$header], $value);
|
||||
} else {
|
||||
$this->headerNames[$normalized] = $header;
|
||||
$this->headers[$header] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure the header complies with RFC 7230.
|
||||
*
|
||||
* Header names must be a non-empty string consisting of token characters.
|
||||
*
|
||||
* Header values must be strings consisting of visible characters with all optional
|
||||
* leading and trailing whitespace stripped. This method will always strip such
|
||||
* optional whitespace. Note that the method does not allow folding whitespace within
|
||||
* the values as this was deprecated for almost all instances by the RFC.
|
||||
*
|
||||
* header-field = field-name ":" OWS field-value OWS
|
||||
* field-name = 1*( "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / "^"
|
||||
* / "_" / "`" / "|" / "~" / %x30-39 / ( %x41-5A / %x61-7A ) )
|
||||
* OWS = *( SP / HTAB )
|
||||
* field-value = *( ( %x21-7E / %x80-FF ) [ 1*( SP / HTAB ) ( %x21-7E / %x80-FF ) ] )
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc7230#section-3.2.4
|
||||
*/
|
||||
private function validateAndTrimHeader($header, $values): array
|
||||
{
|
||||
if (!\is_string($header) || 1 !== \preg_match("@^[!#$%&'*+.^_`|~0-9A-Za-z-]+$@", $header)) {
|
||||
throw new \InvalidArgumentException('Header name must be an RFC 7230 compatible string.');
|
||||
}
|
||||
|
||||
if (!\is_array($values)) {
|
||||
// This is simple, just one value.
|
||||
if ((!\is_numeric($values) && !\is_string($values)) || 1 !== \preg_match("@^[ \t\x21-\x7E\x80-\xFF]*$@", (string) $values)) {
|
||||
throw new \InvalidArgumentException('Header values must be RFC 7230 compatible strings.');
|
||||
}
|
||||
|
||||
return [\trim((string) $values, " \t")];
|
||||
}
|
||||
|
||||
if (empty($values)) {
|
||||
throw new \InvalidArgumentException('Header values must be a string or an array of strings, empty array given.');
|
||||
}
|
||||
|
||||
// Assert Non empty array
|
||||
$returnValues = [];
|
||||
foreach ($values as $v) {
|
||||
if ((!\is_numeric($v) && !\is_string($v)) || 1 !== \preg_match("@^[ \t\x21-\x7E\x80-\xFF]*$@", (string) $v)) {
|
||||
throw new \InvalidArgumentException('Header values must be RFC 7230 compatible strings.');
|
||||
}
|
||||
|
||||
$returnValues[] = \trim((string) $v, " \t");
|
||||
}
|
||||
|
||||
return $returnValues;
|
||||
}
|
||||
}
|
45
vendor/nyholm/psr7/src/Request.php
vendored
Normal file
45
vendor/nyholm/psr7/src/Request.php
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Nyholm\Psr7;
|
||||
|
||||
use Psr\Http\Message\{RequestInterface, StreamInterface, UriInterface};
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
* @author Martijn van der Ven <martijn@vanderven.se>
|
||||
*/
|
||||
final class Request implements RequestInterface
|
||||
{
|
||||
use MessageTrait;
|
||||
use RequestTrait;
|
||||
|
||||
/**
|
||||
* @param string $method HTTP method
|
||||
* @param string|UriInterface $uri URI
|
||||
* @param array $headers Request headers
|
||||
* @param string|resource|StreamInterface|null $body Request body
|
||||
* @param string $version Protocol version
|
||||
*/
|
||||
public function __construct(string $method, $uri, array $headers = [], $body = null, string $version = '1.1')
|
||||
{
|
||||
if (!($uri instanceof UriInterface)) {
|
||||
$uri = new Uri($uri);
|
||||
}
|
||||
|
||||
$this->method = $method;
|
||||
$this->uri = $uri;
|
||||
$this->setHeaders($headers);
|
||||
$this->protocol = $version;
|
||||
|
||||
if (!$this->hasHeader('Host')) {
|
||||
$this->updateHostFromUri();
|
||||
}
|
||||
|
||||
// If we got no body, defer initialization of the stream until Request::getBody()
|
||||
if ('' !== $body && null !== $body) {
|
||||
$this->stream = Stream::create($body);
|
||||
}
|
||||
}
|
||||
}
|
113
vendor/nyholm/psr7/src/RequestTrait.php
vendored
Normal file
113
vendor/nyholm/psr7/src/RequestTrait.php
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Nyholm\Psr7;
|
||||
|
||||
use Psr\Http\Message\UriInterface;
|
||||
|
||||
/**
|
||||
* @author Michael Dowling and contributors to guzzlehttp/psr7
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
* @author Martijn van der Ven <martijn@vanderven.se>
|
||||
*
|
||||
* @internal should not be used outside of Nyholm/Psr7 as it does not fall under our BC promise
|
||||
*/
|
||||
trait RequestTrait
|
||||
{
|
||||
/** @var string */
|
||||
private $method;
|
||||
|
||||
/** @var string|null */
|
||||
private $requestTarget;
|
||||
|
||||
/** @var UriInterface|null */
|
||||
private $uri;
|
||||
|
||||
public function getRequestTarget(): string
|
||||
{
|
||||
if (null !== $this->requestTarget) {
|
||||
return $this->requestTarget;
|
||||
}
|
||||
|
||||
if ('' === $target = $this->uri->getPath()) {
|
||||
$target = '/';
|
||||
}
|
||||
if ('' !== $this->uri->getQuery()) {
|
||||
$target .= '?' . $this->uri->getQuery();
|
||||
}
|
||||
|
||||
return $target;
|
||||
}
|
||||
|
||||
public function withRequestTarget($requestTarget): self
|
||||
{
|
||||
if (\preg_match('#\s#', $requestTarget)) {
|
||||
throw new \InvalidArgumentException('Invalid request target provided; cannot contain whitespace');
|
||||
}
|
||||
|
||||
$new = clone $this;
|
||||
$new->requestTarget = $requestTarget;
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function getMethod(): string
|
||||
{
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
public function withMethod($method): self
|
||||
{
|
||||
if (!\is_string($method)) {
|
||||
throw new \InvalidArgumentException('Method must be a string');
|
||||
}
|
||||
|
||||
$new = clone $this;
|
||||
$new->method = $method;
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function getUri(): UriInterface
|
||||
{
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
public function withUri(UriInterface $uri, $preserveHost = false): self
|
||||
{
|
||||
if ($uri === $this->uri) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$new = clone $this;
|
||||
$new->uri = $uri;
|
||||
|
||||
if (!$preserveHost || !$this->hasHeader('Host')) {
|
||||
$new->updateHostFromUri();
|
||||
}
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
private function updateHostFromUri(): void
|
||||
{
|
||||
if ('' === $host = $this->uri->getHost()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (null !== ($port = $this->uri->getPort())) {
|
||||
$host .= ':' . $port;
|
||||
}
|
||||
|
||||
if (isset($this->headerNames['host'])) {
|
||||
$header = $this->headerNames['host'];
|
||||
} else {
|
||||
$this->headerNames['host'] = $header = 'Host';
|
||||
}
|
||||
|
||||
// Ensure Host is the first header.
|
||||
// See: http://tools.ietf.org/html/rfc7230#section-5.4
|
||||
$this->headers = [$header => [$host]] + $this->headers;
|
||||
}
|
||||
}
|
88
vendor/nyholm/psr7/src/Response.php
vendored
Normal file
88
vendor/nyholm/psr7/src/Response.php
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Nyholm\Psr7;
|
||||
|
||||
use Psr\Http\Message\{ResponseInterface, StreamInterface};
|
||||
|
||||
/**
|
||||
* @author Michael Dowling and contributors to guzzlehttp/psr7
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
* @author Martijn van der Ven <martijn@vanderven.se>
|
||||
*/
|
||||
final class Response implements ResponseInterface
|
||||
{
|
||||
use MessageTrait;
|
||||
|
||||
/** @var array Map of standard HTTP status code/reason phrases */
|
||||
private const PHRASES = [
|
||||
100 => 'Continue', 101 => 'Switching Protocols', 102 => 'Processing',
|
||||
200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authoritative Information', 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content', 207 => 'Multi-status', 208 => 'Already Reported',
|
||||
300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 306 => 'Switch Proxy', 307 => 'Temporary Redirect',
|
||||
400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Time-out', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Request Entity Too Large', 414 => 'Request-URI Too Large', 415 => 'Unsupported Media Type', 416 => 'Requested range not satisfiable', 417 => 'Expectation Failed', 418 => 'I\'m a teapot', 422 => 'Unprocessable Entity', 423 => 'Locked', 424 => 'Failed Dependency', 425 => 'Unordered Collection', 426 => 'Upgrade Required', 428 => 'Precondition Required', 429 => 'Too Many Requests', 431 => 'Request Header Fields Too Large', 451 => 'Unavailable For Legal Reasons',
|
||||
500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Time-out', 505 => 'HTTP Version not supported', 506 => 'Variant Also Negotiates', 507 => 'Insufficient Storage', 508 => 'Loop Detected', 511 => 'Network Authentication Required',
|
||||
];
|
||||
|
||||
/** @var string */
|
||||
private $reasonPhrase = '';
|
||||
|
||||
/** @var int */
|
||||
private $statusCode;
|
||||
|
||||
/**
|
||||
* @param int $status Status code
|
||||
* @param array $headers Response headers
|
||||
* @param string|resource|StreamInterface|null $body Response body
|
||||
* @param string $version Protocol version
|
||||
* @param string|null $reason Reason phrase (when empty a default will be used based on the status code)
|
||||
*/
|
||||
public function __construct(int $status = 200, array $headers = [], $body = null, string $version = '1.1', string $reason = null)
|
||||
{
|
||||
// If we got no body, defer initialization of the stream until Response::getBody()
|
||||
if ('' !== $body && null !== $body) {
|
||||
$this->stream = Stream::create($body);
|
||||
}
|
||||
|
||||
$this->statusCode = $status;
|
||||
$this->setHeaders($headers);
|
||||
if (null === $reason && isset(self::PHRASES[$this->statusCode])) {
|
||||
$this->reasonPhrase = self::PHRASES[$status];
|
||||
} else {
|
||||
$this->reasonPhrase = $reason ?? '';
|
||||
}
|
||||
|
||||
$this->protocol = $version;
|
||||
}
|
||||
|
||||
public function getStatusCode(): int
|
||||
{
|
||||
return $this->statusCode;
|
||||
}
|
||||
|
||||
public function getReasonPhrase(): string
|
||||
{
|
||||
return $this->reasonPhrase;
|
||||
}
|
||||
|
||||
public function withStatus($code, $reasonPhrase = ''): self
|
||||
{
|
||||
if (!\is_int($code) && !\is_string($code)) {
|
||||
throw new \InvalidArgumentException('Status code has to be an integer');
|
||||
}
|
||||
|
||||
$code = (int) $code;
|
||||
if ($code < 100 || $code > 599) {
|
||||
throw new \InvalidArgumentException('Status code has to be an integer between 100 and 599');
|
||||
}
|
||||
|
||||
$new = clone $this;
|
||||
$new->statusCode = $code;
|
||||
if ((null === $reasonPhrase || '' === $reasonPhrase) && isset(self::PHRASES[$new->statusCode])) {
|
||||
$reasonPhrase = self::PHRASES[$new->statusCode];
|
||||
}
|
||||
$new->reasonPhrase = $reasonPhrase;
|
||||
|
||||
return $new;
|
||||
}
|
||||
}
|
162
vendor/nyholm/psr7/src/ServerRequest.php
vendored
Normal file
162
vendor/nyholm/psr7/src/ServerRequest.php
vendored
Normal file
@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Nyholm\Psr7;
|
||||
|
||||
use Psr\Http\Message\{ServerRequestInterface, StreamInterface, UploadedFileInterface, UriInterface};
|
||||
|
||||
/**
|
||||
* @author Michael Dowling and contributors to guzzlehttp/psr7
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
* @author Martijn van der Ven <martijn@vanderven.se>
|
||||
*/
|
||||
final class ServerRequest implements ServerRequestInterface
|
||||
{
|
||||
use MessageTrait;
|
||||
use RequestTrait;
|
||||
|
||||
/** @var array */
|
||||
private $attributes = [];
|
||||
|
||||
/** @var array */
|
||||
private $cookieParams = [];
|
||||
|
||||
/** @var array|object|null */
|
||||
private $parsedBody;
|
||||
|
||||
/** @var array */
|
||||
private $queryParams = [];
|
||||
|
||||
/** @var array */
|
||||
private $serverParams;
|
||||
|
||||
/** @var UploadedFileInterface[] */
|
||||
private $uploadedFiles = [];
|
||||
|
||||
/**
|
||||
* @param string $method HTTP method
|
||||
* @param string|UriInterface $uri URI
|
||||
* @param array $headers Request headers
|
||||
* @param string|resource|StreamInterface|null $body Request body
|
||||
* @param string $version Protocol version
|
||||
* @param array $serverParams Typically the $_SERVER superglobal
|
||||
*/
|
||||
public function __construct(string $method, $uri, array $headers = [], $body = null, string $version = '1.1', array $serverParams = [])
|
||||
{
|
||||
$this->serverParams = $serverParams;
|
||||
|
||||
if (!($uri instanceof UriInterface)) {
|
||||
$uri = new Uri($uri);
|
||||
}
|
||||
|
||||
$this->method = $method;
|
||||
$this->uri = $uri;
|
||||
$this->setHeaders($headers);
|
||||
$this->protocol = $version;
|
||||
|
||||
if (!$this->hasHeader('Host')) {
|
||||
$this->updateHostFromUri();
|
||||
}
|
||||
|
||||
// If we got no body, defer initialization of the stream until ServerRequest::getBody()
|
||||
if ('' !== $body && null !== $body) {
|
||||
$this->stream = Stream::create($body);
|
||||
}
|
||||
}
|
||||
|
||||
public function getServerParams(): array
|
||||
{
|
||||
return $this->serverParams;
|
||||
}
|
||||
|
||||
public function getUploadedFiles(): array
|
||||
{
|
||||
return $this->uploadedFiles;
|
||||
}
|
||||
|
||||
public function withUploadedFiles(array $uploadedFiles)
|
||||
{
|
||||
$new = clone $this;
|
||||
$new->uploadedFiles = $uploadedFiles;
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function getCookieParams(): array
|
||||
{
|
||||
return $this->cookieParams;
|
||||
}
|
||||
|
||||
public function withCookieParams(array $cookies)
|
||||
{
|
||||
$new = clone $this;
|
||||
$new->cookieParams = $cookies;
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function getQueryParams(): array
|
||||
{
|
||||
return $this->queryParams;
|
||||
}
|
||||
|
||||
public function withQueryParams(array $query)
|
||||
{
|
||||
$new = clone $this;
|
||||
$new->queryParams = $query;
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function getParsedBody()
|
||||
{
|
||||
return $this->parsedBody;
|
||||
}
|
||||
|
||||
public function withParsedBody($data)
|
||||
{
|
||||
if (!\is_array($data) && !\is_object($data) && null !== $data) {
|
||||
throw new \InvalidArgumentException('First parameter to withParsedBody MUST be object, array or null');
|
||||
}
|
||||
|
||||
$new = clone $this;
|
||||
$new->parsedBody = $data;
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function getAttributes(): array
|
||||
{
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
public function getAttribute($attribute, $default = null)
|
||||
{
|
||||
if (false === \array_key_exists($attribute, $this->attributes)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $this->attributes[$attribute];
|
||||
}
|
||||
|
||||
public function withAttribute($attribute, $value): self
|
||||
{
|
||||
$new = clone $this;
|
||||
$new->attributes[$attribute] = $value;
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function withoutAttribute($attribute): self
|
||||
{
|
||||
if (false === \array_key_exists($attribute, $this->attributes)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$new = clone $this;
|
||||
unset($new->attributes[$attribute]);
|
||||
|
||||
return $new;
|
||||
}
|
||||
}
|
257
vendor/nyholm/psr7/src/Stream.php
vendored
Normal file
257
vendor/nyholm/psr7/src/Stream.php
vendored
Normal file
@ -0,0 +1,257 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Nyholm\Psr7;
|
||||
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
/**
|
||||
* @author Michael Dowling and contributors to guzzlehttp/psr7
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
* @author Martijn van der Ven <martijn@vanderven.se>
|
||||
*/
|
||||
final class Stream implements StreamInterface
|
||||
{
|
||||
/** @var resource|null A resource reference */
|
||||
private $stream;
|
||||
|
||||
/** @var bool */
|
||||
private $seekable;
|
||||
|
||||
/** @var bool */
|
||||
private $readable;
|
||||
|
||||
/** @var bool */
|
||||
private $writable;
|
||||
|
||||
/** @var array|mixed|void|null */
|
||||
private $uri;
|
||||
|
||||
/** @var int|null */
|
||||
private $size;
|
||||
|
||||
/** @var array Hash of readable and writable stream types */
|
||||
private const READ_WRITE_HASH = [
|
||||
'read' => [
|
||||
'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true,
|
||||
'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true,
|
||||
'c+b' => true, 'rt' => true, 'w+t' => true, 'r+t' => true,
|
||||
'x+t' => true, 'c+t' => true, 'a+' => true,
|
||||
],
|
||||
'write' => [
|
||||
'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true,
|
||||
'c+' => true, 'wb' => true, 'w+b' => true, 'r+b' => true,
|
||||
'x+b' => true, 'c+b' => true, 'w+t' => true, 'r+t' => true,
|
||||
'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true,
|
||||
],
|
||||
];
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new PSR-7 stream.
|
||||
*
|
||||
* @param string|resource|StreamInterface $body
|
||||
*
|
||||
* @return StreamInterface
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function create($body = ''): StreamInterface
|
||||
{
|
||||
if ($body instanceof StreamInterface) {
|
||||
return $body;
|
||||
}
|
||||
|
||||
if (\is_string($body)) {
|
||||
$resource = \fopen('php://temp', 'rw+');
|
||||
\fwrite($resource, $body);
|
||||
$body = $resource;
|
||||
}
|
||||
|
||||
if (\is_resource($body)) {
|
||||
$new = new self();
|
||||
$new->stream = $body;
|
||||
$meta = \stream_get_meta_data($new->stream);
|
||||
$new->seekable = $meta['seekable'] && 0 === \fseek($new->stream, 0, \SEEK_CUR);
|
||||
$new->readable = isset(self::READ_WRITE_HASH['read'][$meta['mode']]);
|
||||
$new->writable = isset(self::READ_WRITE_HASH['write'][$meta['mode']]);
|
||||
$new->uri = $new->getMetadata('uri');
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException('First argument to Stream::create() must be a string, resource or StreamInterface.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the stream when the destructed.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
try {
|
||||
if ($this->isSeekable()) {
|
||||
$this->seek(0);
|
||||
}
|
||||
|
||||
return $this->getContents();
|
||||
} catch (\Exception $e) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
public function close(): void
|
||||
{
|
||||
if (isset($this->stream)) {
|
||||
if (\is_resource($this->stream)) {
|
||||
\fclose($this->stream);
|
||||
}
|
||||
$this->detach();
|
||||
}
|
||||
}
|
||||
|
||||
public function detach()
|
||||
{
|
||||
if (!isset($this->stream)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$result = $this->stream;
|
||||
unset($this->stream);
|
||||
$this->size = $this->uri = null;
|
||||
$this->readable = $this->writable = $this->seekable = false;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getSize(): ?int
|
||||
{
|
||||
if (null !== $this->size) {
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
if (!isset($this->stream)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Clear the stat cache if the stream has a URI
|
||||
if ($this->uri) {
|
||||
\clearstatcache(true, $this->uri);
|
||||
}
|
||||
|
||||
$stats = \fstat($this->stream);
|
||||
if (isset($stats['size'])) {
|
||||
$this->size = $stats['size'];
|
||||
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function tell(): int
|
||||
{
|
||||
if (false === $result = \ftell($this->stream)) {
|
||||
throw new \RuntimeException('Unable to determine stream position');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function eof(): bool
|
||||
{
|
||||
return !$this->stream || \feof($this->stream);
|
||||
}
|
||||
|
||||
public function isSeekable(): bool
|
||||
{
|
||||
return $this->seekable;
|
||||
}
|
||||
|
||||
public function seek($offset, $whence = \SEEK_SET): void
|
||||
{
|
||||
if (!$this->seekable) {
|
||||
throw new \RuntimeException('Stream is not seekable');
|
||||
}
|
||||
|
||||
if (-1 === \fseek($this->stream, $offset, $whence)) {
|
||||
throw new \RuntimeException('Unable to seek to stream position ' . $offset . ' with whence ' . \var_export($whence, true));
|
||||
}
|
||||
}
|
||||
|
||||
public function rewind(): void
|
||||
{
|
||||
$this->seek(0);
|
||||
}
|
||||
|
||||
public function isWritable(): bool
|
||||
{
|
||||
return $this->writable;
|
||||
}
|
||||
|
||||
public function write($string): int
|
||||
{
|
||||
if (!$this->writable) {
|
||||
throw new \RuntimeException('Cannot write to a non-writable stream');
|
||||
}
|
||||
|
||||
// We can't know the size after writing anything
|
||||
$this->size = null;
|
||||
|
||||
if (false === $result = \fwrite($this->stream, $string)) {
|
||||
throw new \RuntimeException('Unable to write to stream');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function isReadable(): bool
|
||||
{
|
||||
return $this->readable;
|
||||
}
|
||||
|
||||
public function read($length): string
|
||||
{
|
||||
if (!$this->readable) {
|
||||
throw new \RuntimeException('Cannot read from non-readable stream');
|
||||
}
|
||||
|
||||
return \fread($this->stream, $length);
|
||||
}
|
||||
|
||||
public function getContents(): string
|
||||
{
|
||||
if (!isset($this->stream)) {
|
||||
throw new \RuntimeException('Unable to read stream contents');
|
||||
}
|
||||
|
||||
if (false === $contents = \stream_get_contents($this->stream)) {
|
||||
throw new \RuntimeException('Unable to read stream contents');
|
||||
}
|
||||
|
||||
return $contents;
|
||||
}
|
||||
|
||||
public function getMetadata($key = null)
|
||||
{
|
||||
if (!isset($this->stream)) {
|
||||
return $key ? null : [];
|
||||
}
|
||||
|
||||
$meta = \stream_get_meta_data($this->stream);
|
||||
|
||||
if (null === $key) {
|
||||
return $meta;
|
||||
}
|
||||
|
||||
return $meta[$key] ?? null;
|
||||
}
|
||||
}
|
171
vendor/nyholm/psr7/src/UploadedFile.php
vendored
Normal file
171
vendor/nyholm/psr7/src/UploadedFile.php
vendored
Normal file
@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Nyholm\Psr7;
|
||||
|
||||
use Psr\Http\Message\{StreamInterface, UploadedFileInterface};
|
||||
|
||||
/**
|
||||
* @author Michael Dowling and contributors to guzzlehttp/psr7
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
* @author Martijn van der Ven <martijn@vanderven.se>
|
||||
*/
|
||||
final class UploadedFile implements UploadedFileInterface
|
||||
{
|
||||
/** @var array */
|
||||
private const ERRORS = [
|
||||
\UPLOAD_ERR_OK => 1,
|
||||
\UPLOAD_ERR_INI_SIZE => 1,
|
||||
\UPLOAD_ERR_FORM_SIZE => 1,
|
||||
\UPLOAD_ERR_PARTIAL => 1,
|
||||
\UPLOAD_ERR_NO_FILE => 1,
|
||||
\UPLOAD_ERR_NO_TMP_DIR => 1,
|
||||
\UPLOAD_ERR_CANT_WRITE => 1,
|
||||
\UPLOAD_ERR_EXTENSION => 1,
|
||||
];
|
||||
|
||||
/** @var string */
|
||||
private $clientFilename;
|
||||
|
||||
/** @var string */
|
||||
private $clientMediaType;
|
||||
|
||||
/** @var int */
|
||||
private $error;
|
||||
|
||||
/** @var string|null */
|
||||
private $file;
|
||||
|
||||
/** @var bool */
|
||||
private $moved = false;
|
||||
|
||||
/** @var int */
|
||||
private $size;
|
||||
|
||||
/** @var StreamInterface|null */
|
||||
private $stream;
|
||||
|
||||
/**
|
||||
* @param StreamInterface|string|resource $streamOrFile
|
||||
* @param int $size
|
||||
* @param int $errorStatus
|
||||
* @param string|null $clientFilename
|
||||
* @param string|null $clientMediaType
|
||||
*/
|
||||
public function __construct($streamOrFile, $size, $errorStatus, $clientFilename = null, $clientMediaType = null)
|
||||
{
|
||||
if (false === \is_int($errorStatus) || !isset(self::ERRORS[$errorStatus])) {
|
||||
throw new \InvalidArgumentException('Upload file error status must be an integer value and one of the "UPLOAD_ERR_*" constants.');
|
||||
}
|
||||
|
||||
if (false === \is_int($size)) {
|
||||
throw new \InvalidArgumentException('Upload file size must be an integer');
|
||||
}
|
||||
|
||||
if (null !== $clientFilename && !\is_string($clientFilename)) {
|
||||
throw new \InvalidArgumentException('Upload file client filename must be a string or null');
|
||||
}
|
||||
|
||||
if (null !== $clientMediaType && !\is_string($clientMediaType)) {
|
||||
throw new \InvalidArgumentException('Upload file client media type must be a string or null');
|
||||
}
|
||||
|
||||
$this->error = $errorStatus;
|
||||
$this->size = $size;
|
||||
$this->clientFilename = $clientFilename;
|
||||
$this->clientMediaType = $clientMediaType;
|
||||
|
||||
if (\UPLOAD_ERR_OK === $this->error) {
|
||||
// Depending on the value set file or stream variable.
|
||||
if (\is_string($streamOrFile)) {
|
||||
$this->file = $streamOrFile;
|
||||
} elseif (\is_resource($streamOrFile)) {
|
||||
$this->stream = Stream::create($streamOrFile);
|
||||
} elseif ($streamOrFile instanceof StreamInterface) {
|
||||
$this->stream = $streamOrFile;
|
||||
} else {
|
||||
throw new \InvalidArgumentException('Invalid stream or file provided for UploadedFile');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \RuntimeException if is moved or not ok
|
||||
*/
|
||||
private function validateActive(): void
|
||||
{
|
||||
if (\UPLOAD_ERR_OK !== $this->error) {
|
||||
throw new \RuntimeException('Cannot retrieve stream due to upload error');
|
||||
}
|
||||
|
||||
if ($this->moved) {
|
||||
throw new \RuntimeException('Cannot retrieve stream after it has already been moved');
|
||||
}
|
||||
}
|
||||
|
||||
public function getStream(): StreamInterface
|
||||
{
|
||||
$this->validateActive();
|
||||
|
||||
if ($this->stream instanceof StreamInterface) {
|
||||
return $this->stream;
|
||||
}
|
||||
|
||||
$resource = \fopen($this->file, 'r');
|
||||
|
||||
return Stream::create($resource);
|
||||
}
|
||||
|
||||
public function moveTo($targetPath): void
|
||||
{
|
||||
$this->validateActive();
|
||||
|
||||
if (!\is_string($targetPath) || '' === $targetPath) {
|
||||
throw new \InvalidArgumentException('Invalid path provided for move operation; must be a non-empty string');
|
||||
}
|
||||
|
||||
if (null !== $this->file) {
|
||||
$this->moved = 'cli' === \PHP_SAPI ? \rename($this->file, $targetPath) : \move_uploaded_file($this->file, $targetPath);
|
||||
} else {
|
||||
$stream = $this->getStream();
|
||||
if ($stream->isSeekable()) {
|
||||
$stream->rewind();
|
||||
}
|
||||
|
||||
// Copy the contents of a stream into another stream until end-of-file.
|
||||
$dest = Stream::create(\fopen($targetPath, 'w'));
|
||||
while (!$stream->eof()) {
|
||||
if (!$dest->write($stream->read(1048576))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->moved = true;
|
||||
}
|
||||
|
||||
if (false === $this->moved) {
|
||||
throw new \RuntimeException(\sprintf('Uploaded file could not be moved to %s', $targetPath));
|
||||
}
|
||||
}
|
||||
|
||||
public function getSize(): int
|
||||
{
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
public function getError(): int
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
public function getClientFilename(): ?string
|
||||
{
|
||||
return $this->clientFilename;
|
||||
}
|
||||
|
||||
public function getClientMediaType(): ?string
|
||||
{
|
||||
return $this->clientMediaType;
|
||||
}
|
||||
}
|
310
vendor/nyholm/psr7/src/Uri.php
vendored
Normal file
310
vendor/nyholm/psr7/src/Uri.php
vendored
Normal file
@ -0,0 +1,310 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Nyholm\Psr7;
|
||||
|
||||
use Psr\Http\Message\UriInterface;
|
||||
|
||||
/**
|
||||
* PSR-7 URI implementation.
|
||||
*
|
||||
* @author Michael Dowling
|
||||
* @author Tobias Schultze
|
||||
* @author Matthew Weier O'Phinney
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
* @author Martijn van der Ven <martijn@vanderven.se>
|
||||
*/
|
||||
final class Uri implements UriInterface
|
||||
{
|
||||
private const SCHEMES = ['http' => 80, 'https' => 443];
|
||||
|
||||
private const CHAR_UNRESERVED = 'a-zA-Z0-9_\-\.~';
|
||||
|
||||
private const CHAR_SUB_DELIMS = '!\$&\'\(\)\*\+,;=';
|
||||
|
||||
/** @var string Uri scheme. */
|
||||
private $scheme = '';
|
||||
|
||||
/** @var string Uri user info. */
|
||||
private $userInfo = '';
|
||||
|
||||
/** @var string Uri host. */
|
||||
private $host = '';
|
||||
|
||||
/** @var int|null Uri port. */
|
||||
private $port;
|
||||
|
||||
/** @var string Uri path. */
|
||||
private $path = '';
|
||||
|
||||
/** @var string Uri query string. */
|
||||
private $query = '';
|
||||
|
||||
/** @var string Uri fragment. */
|
||||
private $fragment = '';
|
||||
|
||||
public function __construct(string $uri = '')
|
||||
{
|
||||
if ('' !== $uri) {
|
||||
if (false === $parts = \parse_url($uri)) {
|
||||
throw new \InvalidArgumentException("Unable to parse URI: $uri");
|
||||
}
|
||||
|
||||
// Apply parse_url parts to a URI.
|
||||
$this->scheme = isset($parts['scheme']) ? \strtolower($parts['scheme']) : '';
|
||||
$this->userInfo = $parts['user'] ?? '';
|
||||
$this->host = isset($parts['host']) ? \strtolower($parts['host']) : '';
|
||||
$this->port = isset($parts['port']) ? $this->filterPort($parts['port']) : null;
|
||||
$this->path = isset($parts['path']) ? $this->filterPath($parts['path']) : '';
|
||||
$this->query = isset($parts['query']) ? $this->filterQueryAndFragment($parts['query']) : '';
|
||||
$this->fragment = isset($parts['fragment']) ? $this->filterQueryAndFragment($parts['fragment']) : '';
|
||||
if (isset($parts['pass'])) {
|
||||
$this->userInfo .= ':' . $parts['pass'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return self::createUriString($this->scheme, $this->getAuthority(), $this->path, $this->query, $this->fragment);
|
||||
}
|
||||
|
||||
public function getScheme(): string
|
||||
{
|
||||
return $this->scheme;
|
||||
}
|
||||
|
||||
public function getAuthority(): string
|
||||
{
|
||||
if ('' === $this->host) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$authority = $this->host;
|
||||
if ('' !== $this->userInfo) {
|
||||
$authority = $this->userInfo . '@' . $authority;
|
||||
}
|
||||
|
||||
if (null !== $this->port) {
|
||||
$authority .= ':' . $this->port;
|
||||
}
|
||||
|
||||
return $authority;
|
||||
}
|
||||
|
||||
public function getUserInfo(): string
|
||||
{
|
||||
return $this->userInfo;
|
||||
}
|
||||
|
||||
public function getHost(): string
|
||||
{
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
public function getPort(): ?int
|
||||
{
|
||||
return $this->port;
|
||||
}
|
||||
|
||||
public function getPath(): string
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function getQuery(): string
|
||||
{
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
public function getFragment(): string
|
||||
{
|
||||
return $this->fragment;
|
||||
}
|
||||
|
||||
public function withScheme($scheme): self
|
||||
{
|
||||
if (!\is_string($scheme)) {
|
||||
throw new \InvalidArgumentException('Scheme must be a string');
|
||||
}
|
||||
|
||||
if ($this->scheme === $scheme = \strtolower($scheme)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$new = clone $this;
|
||||
$new->scheme = $scheme;
|
||||
$new->port = $new->filterPort($new->port);
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function withUserInfo($user, $password = null): self
|
||||
{
|
||||
$info = $user;
|
||||
if (null !== $password && '' !== $password) {
|
||||
$info .= ':' . $password;
|
||||
}
|
||||
|
||||
if ($this->userInfo === $info) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$new = clone $this;
|
||||
$new->userInfo = $info;
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function withHost($host): self
|
||||
{
|
||||
if (!\is_string($host)) {
|
||||
throw new \InvalidArgumentException('Host must be a string');
|
||||
}
|
||||
|
||||
if ($this->host === $host = \strtolower($host)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$new = clone $this;
|
||||
$new->host = $host;
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function withPort($port): self
|
||||
{
|
||||
if ($this->port === $port = $this->filterPort($port)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$new = clone $this;
|
||||
$new->port = $port;
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function withPath($path): self
|
||||
{
|
||||
if ($this->path === $path = $this->filterPath($path)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$new = clone $this;
|
||||
$new->path = $path;
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function withQuery($query): self
|
||||
{
|
||||
if ($this->query === $query = $this->filterQueryAndFragment($query)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$new = clone $this;
|
||||
$new->query = $query;
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function withFragment($fragment): self
|
||||
{
|
||||
if ($this->fragment === $fragment = $this->filterQueryAndFragment($fragment)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$new = clone $this;
|
||||
$new->fragment = $fragment;
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a URI string from its various parts.
|
||||
*/
|
||||
private static function createUriString(string $scheme, string $authority, string $path, string $query, string $fragment): string
|
||||
{
|
||||
$uri = '';
|
||||
if ('' !== $scheme) {
|
||||
$uri .= $scheme . ':';
|
||||
}
|
||||
|
||||
if ('' !== $authority) {
|
||||
$uri .= '//' . $authority;
|
||||
}
|
||||
|
||||
if ('' !== $path) {
|
||||
if ('/' !== $path[0]) {
|
||||
if ('' !== $authority) {
|
||||
// If the path is rootless and an authority is present, the path MUST be prefixed by "/"
|
||||
$path = '/' . $path;
|
||||
}
|
||||
} elseif (isset($path[1]) && '/' === $path[1]) {
|
||||
if ('' === $authority) {
|
||||
// If the path is starting with more than one "/" and no authority is present, the
|
||||
// starting slashes MUST be reduced to one.
|
||||
$path = '/' . \ltrim($path, '/');
|
||||
}
|
||||
}
|
||||
|
||||
$uri .= $path;
|
||||
}
|
||||
|
||||
if ('' !== $query) {
|
||||
$uri .= '?' . $query;
|
||||
}
|
||||
|
||||
if ('' !== $fragment) {
|
||||
$uri .= '#' . $fragment;
|
||||
}
|
||||
|
||||
return $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is a given port non-standard for the current scheme?
|
||||
*/
|
||||
private static function isNonStandardPort(string $scheme, int $port): bool
|
||||
{
|
||||
return !isset(self::SCHEMES[$scheme]) || $port !== self::SCHEMES[$scheme];
|
||||
}
|
||||
|
||||
private function filterPort($port): ?int
|
||||
{
|
||||
if (null === $port) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$port = (int) $port;
|
||||
if (0 > $port || 0xffff < $port) {
|
||||
throw new \InvalidArgumentException(\sprintf('Invalid port: %d. Must be between 0 and 65535', $port));
|
||||
}
|
||||
|
||||
return self::isNonStandardPort($this->scheme, $port) ? $port : null;
|
||||
}
|
||||
|
||||
private function filterPath($path): string
|
||||
{
|
||||
if (!\is_string($path)) {
|
||||
throw new \InvalidArgumentException('Path must be a string');
|
||||
}
|
||||
|
||||
return \preg_replace_callback('/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\/]++|%(?![A-Fa-f0-9]{2}))/', [__CLASS__, 'rawurlencodeMatchZero'], $path);
|
||||
}
|
||||
|
||||
private function filterQueryAndFragment($str): string
|
||||
{
|
||||
if (!\is_string($str)) {
|
||||
throw new \InvalidArgumentException('Query and fragment must be a string');
|
||||
}
|
||||
|
||||
return \preg_replace_callback('/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/', [__CLASS__, 'rawurlencodeMatchZero'], $str);
|
||||
}
|
||||
|
||||
private static function rawurlencodeMatchZero(array $match): string
|
||||
{
|
||||
return \rawurlencode($match[0]);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user