Add laminas/laminas-diactoros
This commit is contained in:
parent
a0394b2361
commit
8a6a0c7382
74 changed files with 11384 additions and 2 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,5 +1,8 @@
|
||||||
/vendor/*
|
/vendor/*
|
||||||
!/vendor/embed
|
!/vendor/embed
|
||||||
|
!/vendor/embed/embed
|
||||||
|
!/vendor/laminas
|
||||||
|
!/vendor/laminas/laminas-diactoros
|
||||||
|
|
||||||
/.vscode
|
/.vscode
|
||||||
/includes/config/config.php
|
/includes/config/config.php
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.1"
|
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.1"
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"embed/embed": "^4.3"
|
"embed/embed": "^4.3",
|
||||||
|
"laminas/laminas-diactoros": "^2.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
101
composer.lock
generated
101
composer.lock
generated
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "ccddc20719e54ec597c104abcbd1ab07",
|
"content-hash": "72ca4d25f90c6bffc18b886e1ef67acb",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "composer/ca-bundle",
|
"name": "composer/ca-bundle",
|
||||||
|
@ -157,6 +157,105 @@
|
||||||
},
|
},
|
||||||
"time": "2021-10-10T17:10:44+00:00"
|
"time": "2021-10-10T17:10:44+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "laminas/laminas-diactoros",
|
||||||
|
"version": "2.8.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/laminas/laminas-diactoros.git",
|
||||||
|
"reference": "0c26ef1d95b6d7e6e3943a243ba3dc0797227199"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/0c26ef1d95b6d7e6e3943a243ba3dc0797227199",
|
||||||
|
"reference": "0c26ef1d95b6d7e6e3943a243ba3dc0797227199",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.3 || ~8.0.0 || ~8.1.0",
|
||||||
|
"psr/http-factory": "^1.0",
|
||||||
|
"psr/http-message": "^1.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"phpspec/prophecy": "<1.9.0",
|
||||||
|
"zendframework/zend-diactoros": "*"
|
||||||
|
},
|
||||||
|
"provide": {
|
||||||
|
"psr/http-factory-implementation": "1.0",
|
||||||
|
"psr/http-message-implementation": "1.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"ext-curl": "*",
|
||||||
|
"ext-dom": "*",
|
||||||
|
"ext-gd": "*",
|
||||||
|
"ext-libxml": "*",
|
||||||
|
"http-interop/http-factory-tests": "^0.8.0",
|
||||||
|
"laminas/laminas-coding-standard": "~1.0.0",
|
||||||
|
"php-http/psr7-integration-tests": "^1.1",
|
||||||
|
"phpspec/prophecy-phpunit": "^2.0",
|
||||||
|
"phpunit/phpunit": "^9.1",
|
||||||
|
"psalm/plugin-phpunit": "^0.14.0",
|
||||||
|
"vimeo/psalm": "^4.3"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laminas": {
|
||||||
|
"config-provider": "Laminas\\Diactoros\\ConfigProvider",
|
||||||
|
"module": "Laminas\\Diactoros"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"src/functions/create_uploaded_file.php",
|
||||||
|
"src/functions/marshal_headers_from_sapi.php",
|
||||||
|
"src/functions/marshal_method_from_sapi.php",
|
||||||
|
"src/functions/marshal_protocol_version_from_sapi.php",
|
||||||
|
"src/functions/marshal_uri_from_sapi.php",
|
||||||
|
"src/functions/normalize_server.php",
|
||||||
|
"src/functions/normalize_uploaded_files.php",
|
||||||
|
"src/functions/parse_cookie_header.php",
|
||||||
|
"src/functions/create_uploaded_file.legacy.php",
|
||||||
|
"src/functions/marshal_headers_from_sapi.legacy.php",
|
||||||
|
"src/functions/marshal_method_from_sapi.legacy.php",
|
||||||
|
"src/functions/marshal_protocol_version_from_sapi.legacy.php",
|
||||||
|
"src/functions/marshal_uri_from_sapi.legacy.php",
|
||||||
|
"src/functions/normalize_server.legacy.php",
|
||||||
|
"src/functions/normalize_uploaded_files.legacy.php",
|
||||||
|
"src/functions/parse_cookie_header.legacy.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Laminas\\Diactoros\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"BSD-3-Clause"
|
||||||
|
],
|
||||||
|
"description": "PSR HTTP Message implementations",
|
||||||
|
"homepage": "https://laminas.dev",
|
||||||
|
"keywords": [
|
||||||
|
"http",
|
||||||
|
"laminas",
|
||||||
|
"psr",
|
||||||
|
"psr-17",
|
||||||
|
"psr-7"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"chat": "https://laminas.dev/chat",
|
||||||
|
"docs": "https://docs.laminas.dev/laminas-diactoros/",
|
||||||
|
"forum": "https://discourse.laminas.dev",
|
||||||
|
"issues": "https://github.com/laminas/laminas-diactoros/issues",
|
||||||
|
"rss": "https://github.com/laminas/laminas-diactoros/releases.atom",
|
||||||
|
"source": "https://github.com/laminas/laminas-diactoros"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://funding.communitybridge.org/projects/laminas-project",
|
||||||
|
"type": "community_bridge"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2021-09-22T03:54:36+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "ml/iri",
|
"name": "ml/iri",
|
||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
/**
|
/**
|
||||||
* Include
|
* Include
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
require 'vendor/autoload.php';
|
||||||
require 'includes/functions/auto-include.php';
|
require 'includes/functions/auto-include.php';
|
||||||
|
|
||||||
autoInclude(__DIR__ . '/includes/classes');
|
autoInclude(__DIR__ . '/includes/classes');
|
||||||
|
|
8
vendor/laminas/laminas-diactoros/.laminas-ci.json
vendored
Normal file
8
vendor/laminas/laminas-diactoros/.laminas-ci.json
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"extensions": [
|
||||||
|
"gd"
|
||||||
|
],
|
||||||
|
"ignore_php_platform_requirements": {
|
||||||
|
"8.1": true
|
||||||
|
}
|
||||||
|
}
|
1
vendor/laminas/laminas-diactoros/COPYRIGHT.md
vendored
Normal file
1
vendor/laminas/laminas-diactoros/COPYRIGHT.md
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/)
|
26
vendor/laminas/laminas-diactoros/LICENSE.md
vendored
Normal file
26
vendor/laminas/laminas-diactoros/LICENSE.md
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
- Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
- Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
- Neither the name of Laminas Foundation nor the names of its contributors may
|
||||||
|
be used to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
vendor/laminas/laminas-diactoros/README.md
vendored
Normal file
30
vendor/laminas/laminas-diactoros/README.md
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# laminas-diactoros
|
||||||
|
|
||||||
|
[![Build Status](https://github.com/laminas/laminas-diactoros/workflows/Continuous%20Integration/badge.svg)](https://github.com/laminas/laminas-diactoros/actions/workflows/continuous-integration.yml)
|
||||||
|
|
||||||
|
> Diactoros (pronunciation: `/dɪʌktɒrɒs/`): an epithet for Hermes, meaning literally, "the messenger."
|
||||||
|
|
||||||
|
This package supercedes and replaces [phly/http](https://github.com/phly/http).
|
||||||
|
|
||||||
|
`laminas-diactoros` is a PHP package containing implementations of the
|
||||||
|
[PSR-7 HTTP message interfaces](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-7-http-message.md)
|
||||||
|
and [PSR-17 HTTP message factory interfaces](https://www.php-fig.org/psr/psr-17).
|
||||||
|
|
||||||
|
- File issues at https://github.com/laminas/laminas-diactoros/issues
|
||||||
|
- Issue patches to https://github.com/laminas/laminas-diactoros/pulls
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
Documentation is available at:
|
||||||
|
|
||||||
|
- https://docs.laminas.dev/laminas-diactoros/
|
||||||
|
|
||||||
|
Source files for documentation are [in the docs/ tree](docs/).
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
## Contributing and Support
|
||||||
|
|
||||||
|
- If you need support with the project, read [the support documentation](https://github.com/laminas/.github/blob/main/SUPPORT.md).
|
||||||
|
- If you wish to contribute to the project, read the [contributing guidelines](https://github.com/laminas/.github/blob/main/CONTRIBUTING.md) as well as the [Code of Conduct](https://github.com/laminas/.github/blob/main/CODE_OF_CONDUCT.md).
|
||||||
|
- For reporting security issues, please review our [security policy](https://github.com/laminas/.github/blob/main/SECURITY.md).
|
95
vendor/laminas/laminas-diactoros/composer.json
vendored
Normal file
95
vendor/laminas/laminas-diactoros/composer.json
vendored
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
{
|
||||||
|
"name": "laminas/laminas-diactoros",
|
||||||
|
"description": "PSR HTTP Message implementations",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"keywords": [
|
||||||
|
"laminas",
|
||||||
|
"http",
|
||||||
|
"psr",
|
||||||
|
"psr-7",
|
||||||
|
"psr-17"
|
||||||
|
],
|
||||||
|
"homepage": "https://laminas.dev",
|
||||||
|
"support": {
|
||||||
|
"docs": "https://docs.laminas.dev/laminas-diactoros/",
|
||||||
|
"issues": "https://github.com/laminas/laminas-diactoros/issues",
|
||||||
|
"source": "https://github.com/laminas/laminas-diactoros",
|
||||||
|
"rss": "https://github.com/laminas/laminas-diactoros/releases.atom",
|
||||||
|
"chat": "https://laminas.dev/chat",
|
||||||
|
"forum": "https://discourse.laminas.dev"
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"sort-packages": true
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"laminas": {
|
||||||
|
"config-provider": "Laminas\\Diactoros\\ConfigProvider",
|
||||||
|
"module": "Laminas\\Diactoros"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.3 || ~8.0.0 || ~8.1.0",
|
||||||
|
"psr/http-factory": "^1.0",
|
||||||
|
"psr/http-message": "^1.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"ext-curl": "*",
|
||||||
|
"ext-dom": "*",
|
||||||
|
"ext-gd": "*",
|
||||||
|
"ext-libxml": "*",
|
||||||
|
"http-interop/http-factory-tests": "^0.8.0",
|
||||||
|
"laminas/laminas-coding-standard": "~1.0.0",
|
||||||
|
"php-http/psr7-integration-tests": "^1.1",
|
||||||
|
"phpspec/prophecy-phpunit": "^2.0",
|
||||||
|
"phpunit/phpunit": "^9.1",
|
||||||
|
"psalm/plugin-phpunit": "^0.14.0",
|
||||||
|
"vimeo/psalm": "^4.3"
|
||||||
|
},
|
||||||
|
"provide": {
|
||||||
|
"psr/http-factory-implementation": "1.0",
|
||||||
|
"psr/http-message-implementation": "1.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"phpspec/prophecy": "<1.9.0",
|
||||||
|
"zendframework/zend-diactoros": "*"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"src/functions/create_uploaded_file.php",
|
||||||
|
"src/functions/marshal_headers_from_sapi.php",
|
||||||
|
"src/functions/marshal_method_from_sapi.php",
|
||||||
|
"src/functions/marshal_protocol_version_from_sapi.php",
|
||||||
|
"src/functions/marshal_uri_from_sapi.php",
|
||||||
|
"src/functions/normalize_server.php",
|
||||||
|
"src/functions/normalize_uploaded_files.php",
|
||||||
|
"src/functions/parse_cookie_header.php",
|
||||||
|
"src/functions/create_uploaded_file.legacy.php",
|
||||||
|
"src/functions/marshal_headers_from_sapi.legacy.php",
|
||||||
|
"src/functions/marshal_method_from_sapi.legacy.php",
|
||||||
|
"src/functions/marshal_protocol_version_from_sapi.legacy.php",
|
||||||
|
"src/functions/marshal_uri_from_sapi.legacy.php",
|
||||||
|
"src/functions/normalize_server.legacy.php",
|
||||||
|
"src/functions/normalize_uploaded_files.legacy.php",
|
||||||
|
"src/functions/parse_cookie_header.legacy.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Laminas\\Diactoros\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload-dev": {
|
||||||
|
"psr-4": {
|
||||||
|
"LaminasTest\\Diactoros\\": "test/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"check": [
|
||||||
|
"@cs-check",
|
||||||
|
"@test"
|
||||||
|
],
|
||||||
|
"cs-check": "phpcs",
|
||||||
|
"cs-fix": "phpcbf",
|
||||||
|
"test": "phpunit --colors=always",
|
||||||
|
"test-coverage": "phpunit --colors=always --coverage-clover clover.xml",
|
||||||
|
"static-analysis": "psalm --shepherd --stats"
|
||||||
|
}
|
||||||
|
}
|
4179
vendor/laminas/laminas-diactoros/composer.lock
generated
vendored
Normal file
4179
vendor/laminas/laminas-diactoros/composer.lock
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
1362
vendor/laminas/laminas-diactoros/psalm-baseline.xml
vendored
Normal file
1362
vendor/laminas/laminas-diactoros/psalm-baseline.xml
vendored
Normal file
File diff suppressed because it is too large
Load diff
29
vendor/laminas/laminas-diactoros/psalm.xml.dist
vendored
Normal file
29
vendor/laminas/laminas-diactoros/psalm.xml.dist
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<psalm
|
||||||
|
totallyTyped="true"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="https://getpsalm.org/schema/config"
|
||||||
|
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
||||||
|
errorBaseline="psalm-baseline.xml"
|
||||||
|
>
|
||||||
|
<projectFiles>
|
||||||
|
<directory name="src"/>
|
||||||
|
<directory name="test"/>
|
||||||
|
<ignoreFiles>
|
||||||
|
<directory name="vendor"/>
|
||||||
|
</ignoreFiles>
|
||||||
|
</projectFiles>
|
||||||
|
|
||||||
|
<issueHandlers>
|
||||||
|
<InternalMethod>
|
||||||
|
<errorLevel type="suppress">
|
||||||
|
<referencedMethod name="PHPUnit\Framework\MockObject\Builder\InvocationMocker::method"/>
|
||||||
|
<referencedMethod name="PHPUnit\Framework\MockObject\Builder\InvocationMocker::willReturn"/>
|
||||||
|
<referencedMethod name="PHPUnit\Framework\MockObject\Builder\InvocationMocker::with"/>
|
||||||
|
</errorLevel>
|
||||||
|
</InternalMethod>
|
||||||
|
</issueHandlers>
|
||||||
|
<plugins>
|
||||||
|
<pluginClass class="Psalm\PhpUnitPlugin\Plugin"/>
|
||||||
|
</plugins>
|
||||||
|
</psalm>
|
148
vendor/laminas/laminas-diactoros/src/AbstractSerializer.php
vendored
Normal file
148
vendor/laminas/laminas-diactoros/src/AbstractSerializer.php
vendored
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
|
||||||
|
use function array_pop;
|
||||||
|
use function implode;
|
||||||
|
use function ltrim;
|
||||||
|
use function preg_match;
|
||||||
|
use function sprintf;
|
||||||
|
use function str_replace;
|
||||||
|
use function ucwords;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides base functionality for request and response de/serialization
|
||||||
|
* strategies, including functionality for retrieving a line at a time from
|
||||||
|
* the message, splitting headers from the body, and serializing headers.
|
||||||
|
*/
|
||||||
|
abstract class AbstractSerializer
|
||||||
|
{
|
||||||
|
const CR = "\r";
|
||||||
|
const EOL = "\r\n";
|
||||||
|
const LF = "\n";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a single line from the stream.
|
||||||
|
*
|
||||||
|
* Retrieves a line from the stream; a line is defined as a sequence of
|
||||||
|
* characters ending in a CRLF sequence.
|
||||||
|
*
|
||||||
|
* @throws Exception\DeserializationException if the sequence contains a CR
|
||||||
|
* or LF in isolation, or ends in a CR.
|
||||||
|
*/
|
||||||
|
protected static function getLine(StreamInterface $stream) : string
|
||||||
|
{
|
||||||
|
$line = '';
|
||||||
|
$crFound = false;
|
||||||
|
while (! $stream->eof()) {
|
||||||
|
$char = $stream->read(1);
|
||||||
|
|
||||||
|
if ($crFound && $char === self::LF) {
|
||||||
|
$crFound = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CR NOT followed by LF
|
||||||
|
if ($crFound && $char !== self::LF) {
|
||||||
|
throw Exception\DeserializationException::forUnexpectedCarriageReturn();
|
||||||
|
}
|
||||||
|
|
||||||
|
// LF in isolation
|
||||||
|
if (! $crFound && $char === self::LF) {
|
||||||
|
throw Exception\DeserializationException::forUnexpectedLineFeed();
|
||||||
|
}
|
||||||
|
|
||||||
|
// CR found; do not append
|
||||||
|
if ($char === self::CR) {
|
||||||
|
$crFound = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any other character: append
|
||||||
|
$line .= $char;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CR found at end of stream
|
||||||
|
if ($crFound) {
|
||||||
|
throw Exception\DeserializationException::forUnexpectedEndOfHeaders();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $line;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Split the stream into headers and body content.
|
||||||
|
*
|
||||||
|
* Returns an array containing two elements
|
||||||
|
*
|
||||||
|
* - The first is an array of headers
|
||||||
|
* - The second is a StreamInterface containing the body content
|
||||||
|
*
|
||||||
|
* @throws Exception\DeserializationException For invalid headers.
|
||||||
|
*/
|
||||||
|
protected static function splitStream(StreamInterface $stream) : array
|
||||||
|
{
|
||||||
|
$headers = [];
|
||||||
|
$currentHeader = false;
|
||||||
|
|
||||||
|
while ($line = self::getLine($stream)) {
|
||||||
|
if (preg_match(';^(?P<name>[!#$%&\'*+.^_`\|~0-9a-zA-Z-]+):(?P<value>.*)$;', $line, $matches)) {
|
||||||
|
$currentHeader = $matches['name'];
|
||||||
|
if (! isset($headers[$currentHeader])) {
|
||||||
|
$headers[$currentHeader] = [];
|
||||||
|
}
|
||||||
|
$headers[$currentHeader][] = ltrim($matches['value']);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $currentHeader) {
|
||||||
|
throw Exception\DeserializationException::forInvalidHeader();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! preg_match('#^[ \t]#', $line)) {
|
||||||
|
throw Exception\DeserializationException::forInvalidHeaderContinuation();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append continuation to last header value found
|
||||||
|
$value = array_pop($headers[$currentHeader]);
|
||||||
|
$headers[$currentHeader][] = $value . ltrim($line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// use RelativeStream to avoid copying initial stream into memory
|
||||||
|
return [$headers, new RelativeStream($stream, $stream->tell())];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize headers to string values.
|
||||||
|
*
|
||||||
|
* @psalm-param array<string, string[]> $headers
|
||||||
|
*/
|
||||||
|
protected static function serializeHeaders(array $headers) : string
|
||||||
|
{
|
||||||
|
$lines = [];
|
||||||
|
foreach ($headers as $header => $values) {
|
||||||
|
$normalized = self::filterHeader($header);
|
||||||
|
foreach ($values as $value) {
|
||||||
|
$lines[] = sprintf('%s: %s', $normalized, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode("\r\n", $lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter a header name to wordcase
|
||||||
|
*
|
||||||
|
* @param string $header
|
||||||
|
*/
|
||||||
|
protected static function filterHeader($header) : string
|
||||||
|
{
|
||||||
|
$filtered = str_replace('-', ' ', $header);
|
||||||
|
$filtered = ucwords($filtered);
|
||||||
|
return str_replace(' ', '-', $filtered);
|
||||||
|
}
|
||||||
|
}
|
180
vendor/laminas/laminas-diactoros/src/CallbackStream.php
vendored
Normal file
180
vendor/laminas/laminas-diactoros/src/CallbackStream.php
vendored
Normal file
|
@ -0,0 +1,180 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
|
||||||
|
use function array_key_exists;
|
||||||
|
|
||||||
|
use const SEEK_SET;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of PSR HTTP streams
|
||||||
|
*/
|
||||||
|
class CallbackStream implements StreamInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var callable|null
|
||||||
|
*/
|
||||||
|
protected $callback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param callable $callback
|
||||||
|
* @throws Exception\InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function __construct(callable $callback)
|
||||||
|
{
|
||||||
|
$this->attach($callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function __toString() : string
|
||||||
|
{
|
||||||
|
return $this->getContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function close() : void
|
||||||
|
{
|
||||||
|
$this->callback = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function detach() : ?callable
|
||||||
|
{
|
||||||
|
$callback = $this->callback;
|
||||||
|
$this->callback = null;
|
||||||
|
return $callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attach a new callback to the instance.
|
||||||
|
*/
|
||||||
|
public function attach(callable $callback) : void
|
||||||
|
{
|
||||||
|
$this->callback = $callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getSize() : ?int
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function tell() : int
|
||||||
|
{
|
||||||
|
throw Exception\UntellableStreamException::forCallbackStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function eof() : bool
|
||||||
|
{
|
||||||
|
return empty($this->callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function isSeekable() : bool
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
* @param int $offset
|
||||||
|
* @param int $whence
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function seek($offset, $whence = SEEK_SET)
|
||||||
|
{
|
||||||
|
throw Exception\UnseekableStreamException::forCallbackStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function rewind() : void
|
||||||
|
{
|
||||||
|
throw Exception\UnrewindableStreamException::forCallbackStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function isWritable() : bool
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function write($string) : void
|
||||||
|
{
|
||||||
|
throw Exception\UnwritableStreamException::forCallbackStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function isReadable() : bool
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function read($length) : string
|
||||||
|
{
|
||||||
|
throw Exception\UnreadableStreamException::forCallbackStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getContents() : string
|
||||||
|
{
|
||||||
|
$callback = $this->detach();
|
||||||
|
$contents = $callback ? $callback() : '';
|
||||||
|
return (string) $contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getMetadata($key = null)
|
||||||
|
{
|
||||||
|
$metadata = [
|
||||||
|
'eof' => $this->eof(),
|
||||||
|
'stream_type' => 'callback',
|
||||||
|
'seekable' => false
|
||||||
|
];
|
||||||
|
|
||||||
|
if (null === $key) {
|
||||||
|
return $metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! array_key_exists($key, $metadata)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $metadata[$key];
|
||||||
|
}
|
||||||
|
}
|
45
vendor/laminas/laminas-diactoros/src/ConfigProvider.php
vendored
Normal file
45
vendor/laminas/laminas-diactoros/src/ConfigProvider.php
vendored
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\ServerRequestFactoryInterface;
|
||||||
|
use Psr\Http\Message\RequestFactoryInterface;
|
||||||
|
use Psr\Http\Message\ResponseFactoryInterface;
|
||||||
|
use Psr\Http\Message\StreamFactoryInterface;
|
||||||
|
use Psr\Http\Message\UploadedFileFactoryInterface;
|
||||||
|
use Psr\Http\Message\UriFactoryInterface;
|
||||||
|
|
||||||
|
class ConfigProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Retrieve configuration for laminas-diactoros.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function __invoke() : array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'dependencies' => $this->getDependencies(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the container dependencies.
|
||||||
|
* Maps factory interfaces to factories.
|
||||||
|
*/
|
||||||
|
public function getDependencies() : array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'invokables' => [
|
||||||
|
RequestFactoryInterface::class => RequestFactory::class,
|
||||||
|
ResponseFactoryInterface::class => ResponseFactory::class,
|
||||||
|
StreamFactoryInterface::class => StreamFactory::class,
|
||||||
|
ServerRequestFactoryInterface::class => ServerRequestFactory::class,
|
||||||
|
UploadedFileFactoryInterface::class => UploadedFileFactory::class,
|
||||||
|
UriFactoryInterface::class => UriFactory::class
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
46
vendor/laminas/laminas-diactoros/src/Exception/DeserializationException.php
vendored
Normal file
46
vendor/laminas/laminas-diactoros/src/Exception/DeserializationException.php
vendored
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Exception;
|
||||||
|
|
||||||
|
use Throwable;
|
||||||
|
use UnexpectedValueException;
|
||||||
|
|
||||||
|
class DeserializationException extends UnexpectedValueException implements ExceptionInterface
|
||||||
|
{
|
||||||
|
public static function forInvalidHeader() : self
|
||||||
|
{
|
||||||
|
throw new self('Invalid header detected');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function forInvalidHeaderContinuation() : self
|
||||||
|
{
|
||||||
|
throw new self('Invalid header continuation');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function forRequestFromArray(Throwable $previous) : self
|
||||||
|
{
|
||||||
|
return new self('Cannot deserialize request', $previous->getCode(), $previous);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function forResponseFromArray(Throwable $previous) : self
|
||||||
|
{
|
||||||
|
return new self('Cannot deserialize response', $previous->getCode(), $previous);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function forUnexpectedCarriageReturn() : self
|
||||||
|
{
|
||||||
|
throw new self('Unexpected carriage return detected');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function forUnexpectedEndOfHeaders() : self
|
||||||
|
{
|
||||||
|
throw new self('Unexpected end of headers');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function forUnexpectedLineFeed() : self
|
||||||
|
{
|
||||||
|
throw new self('Unexpected line feed detected');
|
||||||
|
}
|
||||||
|
}
|
14
vendor/laminas/laminas-diactoros/src/Exception/ExceptionInterface.php
vendored
Normal file
14
vendor/laminas/laminas-diactoros/src/Exception/ExceptionInterface.php
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Exception;
|
||||||
|
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marker interface for package-specific exceptions.
|
||||||
|
*/
|
||||||
|
interface ExceptionInterface extends Throwable
|
||||||
|
{
|
||||||
|
}
|
9
vendor/laminas/laminas-diactoros/src/Exception/InvalidArgumentException.php
vendored
Normal file
9
vendor/laminas/laminas-diactoros/src/Exception/InvalidArgumentException.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Exception;
|
||||||
|
|
||||||
|
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
|
||||||
|
{
|
||||||
|
}
|
19
vendor/laminas/laminas-diactoros/src/Exception/InvalidStreamPointerPositionException.php
vendored
Normal file
19
vendor/laminas/laminas-diactoros/src/Exception/InvalidStreamPointerPositionException.php
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Exception;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
class InvalidStreamPointerPositionException extends RuntimeException implements ExceptionInterface
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
string $message = 'Invalid pointer position',
|
||||||
|
$code = 0,
|
||||||
|
Throwable $previous = null
|
||||||
|
) {
|
||||||
|
parent::__construct($message, $code, $previous);
|
||||||
|
}
|
||||||
|
}
|
9
vendor/laminas/laminas-diactoros/src/Exception/RuntimeException.php
vendored
Normal file
9
vendor/laminas/laminas-diactoros/src/Exception/RuntimeException.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Exception;
|
||||||
|
|
||||||
|
class RuntimeException extends \RuntimeException implements ExceptionInterface
|
||||||
|
{
|
||||||
|
}
|
20
vendor/laminas/laminas-diactoros/src/Exception/SerializationException.php
vendored
Normal file
20
vendor/laminas/laminas-diactoros/src/Exception/SerializationException.php
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Exception;
|
||||||
|
|
||||||
|
use UnexpectedValueException;
|
||||||
|
|
||||||
|
class SerializationException extends UnexpectedValueException implements ExceptionInterface
|
||||||
|
{
|
||||||
|
public static function forInvalidRequestLine() : self
|
||||||
|
{
|
||||||
|
return new self('Invalid request line detected');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function forInvalidStatusLine() : self
|
||||||
|
{
|
||||||
|
return new self('No status line detected');
|
||||||
|
}
|
||||||
|
}
|
30
vendor/laminas/laminas-diactoros/src/Exception/UnreadableStreamException.php
vendored
Normal file
30
vendor/laminas/laminas-diactoros/src/Exception/UnreadableStreamException.php
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Exception;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
class UnreadableStreamException extends RuntimeException implements ExceptionInterface
|
||||||
|
{
|
||||||
|
public static function dueToConfiguration() : self
|
||||||
|
{
|
||||||
|
return new self('Stream is not readable');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function dueToMissingResource() : self
|
||||||
|
{
|
||||||
|
return new self('No resource available; cannot read');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function dueToPhpError() : self
|
||||||
|
{
|
||||||
|
return new self('Error reading stream');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function forCallbackStream() : self
|
||||||
|
{
|
||||||
|
return new self('Callback streams cannot read');
|
||||||
|
}
|
||||||
|
}
|
17
vendor/laminas/laminas-diactoros/src/Exception/UnrecognizedProtocolVersionException.php
vendored
Normal file
17
vendor/laminas/laminas-diactoros/src/Exception/UnrecognizedProtocolVersionException.php
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Exception;
|
||||||
|
|
||||||
|
use UnexpectedValueException;
|
||||||
|
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
|
class UnrecognizedProtocolVersionException extends UnexpectedValueException implements ExceptionInterface
|
||||||
|
{
|
||||||
|
public static function forVersion(string $version) : self
|
||||||
|
{
|
||||||
|
return new self(sprintf('Unrecognized protocol version (%s)', $version));
|
||||||
|
}
|
||||||
|
}
|
15
vendor/laminas/laminas-diactoros/src/Exception/UnrewindableStreamException.php
vendored
Normal file
15
vendor/laminas/laminas-diactoros/src/Exception/UnrewindableStreamException.php
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Exception;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
class UnrewindableStreamException extends RuntimeException implements ExceptionInterface
|
||||||
|
{
|
||||||
|
public static function forCallbackStream() : self
|
||||||
|
{
|
||||||
|
return new self('Callback streams cannot rewind position');
|
||||||
|
}
|
||||||
|
}
|
30
vendor/laminas/laminas-diactoros/src/Exception/UnseekableStreamException.php
vendored
Normal file
30
vendor/laminas/laminas-diactoros/src/Exception/UnseekableStreamException.php
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Exception;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
class UnseekableStreamException extends RuntimeException implements ExceptionInterface
|
||||||
|
{
|
||||||
|
public static function dueToConfiguration() : self
|
||||||
|
{
|
||||||
|
return new self('Stream is not seekable');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function dueToMissingResource() : self
|
||||||
|
{
|
||||||
|
return new self('No resource available; cannot seek position');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function dueToPhpError() : self
|
||||||
|
{
|
||||||
|
return new self('Error seeking within stream');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function forCallbackStream() : self
|
||||||
|
{
|
||||||
|
return new self('Callback streams cannot seek position');
|
||||||
|
}
|
||||||
|
}
|
25
vendor/laminas/laminas-diactoros/src/Exception/UntellableStreamException.php
vendored
Normal file
25
vendor/laminas/laminas-diactoros/src/Exception/UntellableStreamException.php
vendored
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Exception;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
class UntellableStreamException extends RuntimeException implements ExceptionInterface
|
||||||
|
{
|
||||||
|
public static function dueToMissingResource() : self
|
||||||
|
{
|
||||||
|
return new self('No resource available; cannot tell position');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function dueToPhpError() : self
|
||||||
|
{
|
||||||
|
return new self('Error occurred during tell operation');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function forCallbackStream() : self
|
||||||
|
{
|
||||||
|
return new self('Callback streams cannot tell position');
|
||||||
|
}
|
||||||
|
}
|
30
vendor/laminas/laminas-diactoros/src/Exception/UnwritableStreamException.php
vendored
Normal file
30
vendor/laminas/laminas-diactoros/src/Exception/UnwritableStreamException.php
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Exception;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
class UnwritableStreamException extends RuntimeException implements ExceptionInterface
|
||||||
|
{
|
||||||
|
public static function dueToConfiguration() : self
|
||||||
|
{
|
||||||
|
return new self('Stream is not writable');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function dueToMissingResource() : self
|
||||||
|
{
|
||||||
|
return new self('No resource available; cannot write');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function dueToPhpError() : self
|
||||||
|
{
|
||||||
|
return new self('Error writing to stream');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function forCallbackStream() : self
|
||||||
|
{
|
||||||
|
return new self('Callback streams cannot write');
|
||||||
|
}
|
||||||
|
}
|
19
vendor/laminas/laminas-diactoros/src/Exception/UploadedFileAlreadyMovedException.php
vendored
Normal file
19
vendor/laminas/laminas-diactoros/src/Exception/UploadedFileAlreadyMovedException.php
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Exception;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
class UploadedFileAlreadyMovedException extends RuntimeException implements ExceptionInterface
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
string $message = 'Cannot retrieve stream after it has already moved',
|
||||||
|
$code = 0,
|
||||||
|
Throwable $previous = null
|
||||||
|
) {
|
||||||
|
parent::__construct($message, $code, $previous);
|
||||||
|
}
|
||||||
|
}
|
38
vendor/laminas/laminas-diactoros/src/Exception/UploadedFileErrorException.php
vendored
Normal file
38
vendor/laminas/laminas-diactoros/src/Exception/UploadedFileErrorException.php
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Exception;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
|
class UploadedFileErrorException extends RuntimeException implements ExceptionInterface
|
||||||
|
{
|
||||||
|
public static function forUnmovableFile() : self
|
||||||
|
{
|
||||||
|
return new self('Error occurred while moving uploaded file');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function dueToStreamUploadError(string $error) : self
|
||||||
|
{
|
||||||
|
return new self(sprintf(
|
||||||
|
'Cannot retrieve stream due to upload error: %s',
|
||||||
|
$error
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function dueToUnwritablePath() : self
|
||||||
|
{
|
||||||
|
return new self('Unable to write to designated path');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function dueToUnwritableTarget(string $targetDirectory) : self
|
||||||
|
{
|
||||||
|
return new self(sprintf(
|
||||||
|
'The target directory `%s` does not exists or is not writable',
|
||||||
|
$targetDirectory
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
168
vendor/laminas/laminas-diactoros/src/HeaderSecurity.php
vendored
Normal file
168
vendor/laminas/laminas-diactoros/src/HeaderSecurity.php
vendored
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use function get_class;
|
||||||
|
use function gettype;
|
||||||
|
use function in_array;
|
||||||
|
use function is_numeric;
|
||||||
|
use function is_object;
|
||||||
|
use function is_string;
|
||||||
|
use function ord;
|
||||||
|
use function preg_match;
|
||||||
|
use function sprintf;
|
||||||
|
use function strlen;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide security tools around HTTP headers to prevent common injection vectors.
|
||||||
|
*
|
||||||
|
* Code is largely lifted from the Laminas\Http\Header\HeaderValue implementation in
|
||||||
|
* Laminas, released with the copyright and license below.
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2005-2015 Laminas (https://www.zend.com)
|
||||||
|
* @license https://getlaminas.org/license/new-bsd New BSD License
|
||||||
|
*/
|
||||||
|
final class HeaderSecurity
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Private constructor; non-instantiable.
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
private function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter a header value
|
||||||
|
*
|
||||||
|
* Ensures CRLF header injection vectors are filtered.
|
||||||
|
*
|
||||||
|
* Per RFC 7230, only VISIBLE ASCII characters, spaces, and horizontal
|
||||||
|
* tabs are allowed in values; header continuations MUST consist of
|
||||||
|
* a single CRLF sequence followed by a space or horizontal tab.
|
||||||
|
*
|
||||||
|
* This method filters any values not allowed from the string, and is
|
||||||
|
* lossy.
|
||||||
|
*
|
||||||
|
* @see http://en.wikipedia.org/wiki/HTTP_response_splitting
|
||||||
|
*/
|
||||||
|
public static function filter(string $value) : string
|
||||||
|
{
|
||||||
|
$length = strlen($value);
|
||||||
|
$string = '';
|
||||||
|
for ($i = 0; $i < $length; $i += 1) {
|
||||||
|
$ascii = ord($value[$i]);
|
||||||
|
|
||||||
|
// Detect continuation sequences
|
||||||
|
if ($ascii === 13) {
|
||||||
|
$lf = ord($value[$i + 1]);
|
||||||
|
$ws = ord($value[$i + 2]);
|
||||||
|
if ($lf === 10 && in_array($ws, [9, 32], true)) {
|
||||||
|
$string .= $value[$i] . $value[$i + 1];
|
||||||
|
$i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-visible, non-whitespace characters
|
||||||
|
// 9 === horizontal tab
|
||||||
|
// 32-126, 128-254 === visible
|
||||||
|
// 127 === DEL
|
||||||
|
// 255 === null byte
|
||||||
|
if (($ascii < 32 && $ascii !== 9)
|
||||||
|
|| $ascii === 127
|
||||||
|
|| $ascii > 254
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$string .= $value[$i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a header value.
|
||||||
|
*
|
||||||
|
* Per RFC 7230, only VISIBLE ASCII characters, spaces, and horizontal
|
||||||
|
* tabs are allowed in values; header continuations MUST consist of
|
||||||
|
* a single CRLF sequence followed by a space or horizontal tab.
|
||||||
|
*
|
||||||
|
* @param string|int|float $value
|
||||||
|
* @see http://en.wikipedia.org/wiki/HTTP_response_splitting
|
||||||
|
*/
|
||||||
|
public static function isValid($value) : bool
|
||||||
|
{
|
||||||
|
$value = (string) $value;
|
||||||
|
|
||||||
|
// Look for:
|
||||||
|
// \n not preceded by \r, OR
|
||||||
|
// \r not followed by \n, OR
|
||||||
|
// \r\n not followed by space or horizontal tab; these are all CRLF attacks
|
||||||
|
if (preg_match("#(?:(?:(?<!\r)\n)|(?:\r(?!\n))|(?:\r\n(?![ \t])))#", $value)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-visible, non-whitespace characters
|
||||||
|
// 9 === horizontal tab
|
||||||
|
// 10 === line feed
|
||||||
|
// 13 === carriage return
|
||||||
|
// 32-126, 128-254 === visible
|
||||||
|
// 127 === DEL (disallowed)
|
||||||
|
// 255 === null byte (disallowed)
|
||||||
|
if (preg_match('/[^\x09\x0a\x0d\x20-\x7E\x80-\xFE]/', $value)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assert a header value is valid.
|
||||||
|
*
|
||||||
|
* @param mixed $value Value to be tested. This method asserts it is a string or number.
|
||||||
|
* @throws Exception\InvalidArgumentException for invalid values
|
||||||
|
*/
|
||||||
|
public static function assertValid($value) : void
|
||||||
|
{
|
||||||
|
if (! is_string($value) && ! is_numeric($value)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'Invalid header value type; must be a string or numeric; received %s',
|
||||||
|
(is_object($value) ? get_class($value) : gettype($value))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if (! self::isValid($value)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'"%s" is not valid header value',
|
||||||
|
$value
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assert whether or not a header name is valid.
|
||||||
|
*
|
||||||
|
* @see http://tools.ietf.org/html/rfc7230#section-3.2
|
||||||
|
* @param mixed $name
|
||||||
|
* @throws Exception\InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public static function assertValidName($name) : void
|
||||||
|
{
|
||||||
|
if (! is_string($name)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'Invalid header name type; expected string; received %s',
|
||||||
|
(is_object($name) ? get_class($name) : gettype($name))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if (! preg_match('/^[a-zA-Z0-9\'`#$%&*+.^_|~!-]+$/', $name)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'"%s" is not valid header name',
|
||||||
|
$name
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
416
vendor/laminas/laminas-diactoros/src/MessageTrait.php
vendored
Normal file
416
vendor/laminas/laminas-diactoros/src/MessageTrait.php
vendored
Normal file
|
@ -0,0 +1,416 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\MessageInterface;
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
|
||||||
|
use function array_map;
|
||||||
|
use function array_merge;
|
||||||
|
use function get_class;
|
||||||
|
use function gettype;
|
||||||
|
use function implode;
|
||||||
|
use function is_array;
|
||||||
|
use function is_object;
|
||||||
|
use function is_resource;
|
||||||
|
use function is_string;
|
||||||
|
use function preg_match;
|
||||||
|
use function sprintf;
|
||||||
|
use function strtolower;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trait implementing the various methods defined in MessageInterface.
|
||||||
|
*
|
||||||
|
* @see https://github.com/php-fig/http-message/tree/master/src/MessageInterface.php
|
||||||
|
*/
|
||||||
|
trait MessageTrait
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* List of all registered headers, as key => array of values.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* @psalm-var array<non-empty-string, list<string>>
|
||||||
|
*/
|
||||||
|
protected $headers = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of normalized header name to original name used to register header.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* @psalm-var array<non-empty-string, non-empty-string>
|
||||||
|
*/
|
||||||
|
protected $headerNames = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $protocol = '1.1';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var StreamInterface
|
||||||
|
*/
|
||||||
|
private $stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the HTTP protocol version as a string.
|
||||||
|
*
|
||||||
|
* The string MUST contain only the HTTP version number (e.g., "1.1", "1.0").
|
||||||
|
*
|
||||||
|
* @return string HTTP protocol version.
|
||||||
|
*/
|
||||||
|
public function getProtocolVersion() : string
|
||||||
|
{
|
||||||
|
return $this->protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an instance with the specified HTTP protocol version.
|
||||||
|
*
|
||||||
|
* The version string MUST contain only the HTTP version number (e.g.,
|
||||||
|
* "1.1", "1.0").
|
||||||
|
*
|
||||||
|
* This method MUST be implemented in such a way as to retain the
|
||||||
|
* immutability of the message, and MUST return an instance that has the
|
||||||
|
* new protocol version.
|
||||||
|
*
|
||||||
|
* @param string $version HTTP protocol version
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function withProtocolVersion($version) : MessageInterface
|
||||||
|
{
|
||||||
|
$this->validateProtocolVersion($version);
|
||||||
|
$new = clone $this;
|
||||||
|
$new->protocol = $version;
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all message headers.
|
||||||
|
*
|
||||||
|
* The keys represent the header name as it will be sent over the wire, and
|
||||||
|
* each value is an array of strings associated with the header.
|
||||||
|
*
|
||||||
|
* // Represent the headers as a string
|
||||||
|
* foreach ($message->getHeaders() as $name => $values) {
|
||||||
|
* echo $name . ": " . implode(", ", $values);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Emit headers iteratively:
|
||||||
|
* foreach ($message->getHeaders() as $name => $values) {
|
||||||
|
* foreach ($values as $value) {
|
||||||
|
* header(sprintf('%s: %s', $name, $value), false);
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @return array Returns an associative array of the message's headers. Each
|
||||||
|
* key MUST be a header name, and each value MUST be an array of strings.
|
||||||
|
*
|
||||||
|
* @psalm-return array<non-empty-string, list<string>>
|
||||||
|
*/
|
||||||
|
public function getHeaders() : array
|
||||||
|
{
|
||||||
|
return $this->headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a header exists by the given case-insensitive name.
|
||||||
|
*
|
||||||
|
* @param string $header Case-insensitive header name.
|
||||||
|
* @return bool Returns true if any header names match the given header
|
||||||
|
* name using a case-insensitive string comparison. Returns false if
|
||||||
|
* no matching header name is found in the message.
|
||||||
|
*/
|
||||||
|
public function hasHeader($header) : bool
|
||||||
|
{
|
||||||
|
return isset($this->headerNames[strtolower($header)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a message header value by the given case-insensitive name.
|
||||||
|
*
|
||||||
|
* This method returns an array of all the header values of the given
|
||||||
|
* case-insensitive header name.
|
||||||
|
*
|
||||||
|
* If the header does not appear in the message, this method MUST return an
|
||||||
|
* empty array.
|
||||||
|
*
|
||||||
|
* @param string $header Case-insensitive header field name.
|
||||||
|
* @return string[] An array of string values as provided for the given
|
||||||
|
* header. If the header does not appear in the message, this method MUST
|
||||||
|
* return an empty array.
|
||||||
|
*/
|
||||||
|
public function getHeader($header) : array
|
||||||
|
{
|
||||||
|
if (! $this->hasHeader($header)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$header = $this->headerNames[strtolower($header)];
|
||||||
|
|
||||||
|
return $this->headers[$header];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a comma-separated string of the values for a single header.
|
||||||
|
*
|
||||||
|
* This method returns all of the header values of the given
|
||||||
|
* case-insensitive header name as a string concatenated together using
|
||||||
|
* a comma.
|
||||||
|
*
|
||||||
|
* NOTE: Not all header values may be appropriately represented using
|
||||||
|
* comma concatenation. For such headers, use getHeader() instead
|
||||||
|
* and supply your own delimiter when concatenating.
|
||||||
|
*
|
||||||
|
* If the header does not appear in the message, this method MUST return
|
||||||
|
* an empty string.
|
||||||
|
*
|
||||||
|
* @param string $name Case-insensitive header field name.
|
||||||
|
* @return string A string of values as provided for the given header
|
||||||
|
* concatenated together using a comma. If the header does not appear in
|
||||||
|
* the message, this method MUST return an empty string.
|
||||||
|
*/
|
||||||
|
public function getHeaderLine($name) : string
|
||||||
|
{
|
||||||
|
$value = $this->getHeader($name);
|
||||||
|
if (empty($value)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode(',', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an instance with the provided header, replacing any existing
|
||||||
|
* values of any headers with the same case-insensitive name.
|
||||||
|
*
|
||||||
|
* While header names are case-insensitive, the casing of the header will
|
||||||
|
* be preserved by this function, and returned from getHeaders().
|
||||||
|
*
|
||||||
|
* This method MUST be implemented in such a way as to retain the
|
||||||
|
* immutability of the message, and MUST return an instance that has the
|
||||||
|
* new and/or updated header and value.
|
||||||
|
*
|
||||||
|
* @param string $header Case-insensitive header field name.
|
||||||
|
* @param string|string[] $value Header value(s).
|
||||||
|
* @return static
|
||||||
|
* @throws Exception\InvalidArgumentException for invalid header names or values.
|
||||||
|
*/
|
||||||
|
public function withHeader($header, $value) : MessageInterface
|
||||||
|
{
|
||||||
|
$this->assertHeader($header);
|
||||||
|
|
||||||
|
$normalized = strtolower($header);
|
||||||
|
|
||||||
|
$new = clone $this;
|
||||||
|
if ($new->hasHeader($header)) {
|
||||||
|
unset($new->headers[$new->headerNames[$normalized]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$value = $this->filterHeaderValue($value);
|
||||||
|
|
||||||
|
$new->headerNames[$normalized] = $header;
|
||||||
|
$new->headers[$header] = $value;
|
||||||
|
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an instance with the specified header appended with the
|
||||||
|
* given value.
|
||||||
|
*
|
||||||
|
* Existing values for the specified header will be maintained. The new
|
||||||
|
* value(s) will be appended to the existing list. If the header did not
|
||||||
|
* exist previously, it will be added.
|
||||||
|
*
|
||||||
|
* This method MUST be implemented in such a way as to retain the
|
||||||
|
* immutability of the message, and MUST return an instance that has the
|
||||||
|
* new header and/or value.
|
||||||
|
*
|
||||||
|
* @param string $header Case-insensitive header field name to add.
|
||||||
|
* @param string|string[] $value Header value(s).
|
||||||
|
* @return static
|
||||||
|
* @throws Exception\InvalidArgumentException for invalid header names or values.
|
||||||
|
*/
|
||||||
|
public function withAddedHeader($header, $value) : MessageInterface
|
||||||
|
{
|
||||||
|
$this->assertHeader($header);
|
||||||
|
|
||||||
|
if (! $this->hasHeader($header)) {
|
||||||
|
return $this->withHeader($header, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$header = $this->headerNames[strtolower($header)];
|
||||||
|
|
||||||
|
$new = clone $this;
|
||||||
|
$value = $this->filterHeaderValue($value);
|
||||||
|
$new->headers[$header] = array_merge($this->headers[$header], $value);
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an instance without the specified header.
|
||||||
|
*
|
||||||
|
* Header resolution MUST be done without case-sensitivity.
|
||||||
|
*
|
||||||
|
* This method MUST be implemented in such a way as to retain the
|
||||||
|
* immutability of the message, and MUST return an instance that removes
|
||||||
|
* the named header.
|
||||||
|
*
|
||||||
|
* @param string $header Case-insensitive header field name to remove.
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function withoutHeader($header) : MessageInterface
|
||||||
|
{
|
||||||
|
if (! $this->hasHeader($header)) {
|
||||||
|
return clone $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$normalized = strtolower($header);
|
||||||
|
$original = $this->headerNames[$normalized];
|
||||||
|
|
||||||
|
$new = clone $this;
|
||||||
|
unset($new->headers[$original], $new->headerNames[$normalized]);
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the body of the message.
|
||||||
|
*
|
||||||
|
* @return StreamInterface Returns the body as a stream.
|
||||||
|
*/
|
||||||
|
public function getBody() : StreamInterface
|
||||||
|
{
|
||||||
|
return $this->stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an instance with the specified message body.
|
||||||
|
*
|
||||||
|
* The body MUST be a StreamInterface object.
|
||||||
|
*
|
||||||
|
* This method MUST be implemented in such a way as to retain the
|
||||||
|
* immutability of the message, and MUST return a new instance that has the
|
||||||
|
* new body stream.
|
||||||
|
*
|
||||||
|
* @param StreamInterface $body Body.
|
||||||
|
* @return static
|
||||||
|
* @throws Exception\InvalidArgumentException When the body is not valid.
|
||||||
|
*/
|
||||||
|
public function withBody(StreamInterface $body) : MessageInterface
|
||||||
|
{
|
||||||
|
$new = clone $this;
|
||||||
|
$new->stream = $body;
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getStream($stream, string $modeIfNotInstance) : StreamInterface
|
||||||
|
{
|
||||||
|
if ($stream instanceof StreamInterface) {
|
||||||
|
return $stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! is_string($stream) && ! is_resource($stream)) {
|
||||||
|
throw new Exception\InvalidArgumentException(
|
||||||
|
'Stream must be a string stream resource identifier, '
|
||||||
|
. 'an actual stream resource, '
|
||||||
|
. 'or a Psr\Http\Message\StreamInterface implementation'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Stream($stream, $modeIfNotInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter a set of headers to ensure they are in the correct internal format.
|
||||||
|
*
|
||||||
|
* Used by message constructors to allow setting all initial headers at once.
|
||||||
|
*
|
||||||
|
* @param array $originalHeaders Headers to filter.
|
||||||
|
*/
|
||||||
|
private function setHeaders(array $originalHeaders) : void
|
||||||
|
{
|
||||||
|
$headerNames = $headers = [];
|
||||||
|
|
||||||
|
foreach ($originalHeaders as $header => $value) {
|
||||||
|
$value = $this->filterHeaderValue($value);
|
||||||
|
|
||||||
|
$this->assertHeader($header);
|
||||||
|
|
||||||
|
$headerNames[strtolower($header)] = $header;
|
||||||
|
$headers[$header] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->headerNames = $headerNames;
|
||||||
|
$this->headers = $headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the HTTP protocol version
|
||||||
|
*
|
||||||
|
* @param string $version
|
||||||
|
* @throws Exception\InvalidArgumentException on invalid HTTP protocol version
|
||||||
|
*/
|
||||||
|
private function validateProtocolVersion($version) : void
|
||||||
|
{
|
||||||
|
if (empty($version)) {
|
||||||
|
throw new Exception\InvalidArgumentException(
|
||||||
|
'HTTP protocol version can not be empty'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (! is_string($version)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'Unsupported HTTP protocol version; must be a string, received %s',
|
||||||
|
(is_object($version) ? get_class($version) : gettype($version))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTTP/1 uses a "<major>.<minor>" numbering scheme to indicate
|
||||||
|
// versions of the protocol, while HTTP/2 does not.
|
||||||
|
if (! preg_match('#^(1\.[01]|2(\.0)?)$#', $version)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'Unsupported HTTP protocol version "%s" provided',
|
||||||
|
$version
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $values
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
private function filterHeaderValue($values) : array
|
||||||
|
{
|
||||||
|
if (! is_array($values)) {
|
||||||
|
$values = [$values];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([] === $values) {
|
||||||
|
throw new Exception\InvalidArgumentException(
|
||||||
|
'Invalid header value: must be a string or array of strings; '
|
||||||
|
. 'cannot be an empty array'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_map(function ($value) {
|
||||||
|
HeaderSecurity::assertValid($value);
|
||||||
|
|
||||||
|
return (string) $value;
|
||||||
|
}, array_values($values));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure header name and values are valid.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @throws Exception\InvalidArgumentException
|
||||||
|
*/
|
||||||
|
private function assertHeader($name) : void
|
||||||
|
{
|
||||||
|
HeaderSecurity::assertValidName($name);
|
||||||
|
}
|
||||||
|
}
|
15
vendor/laminas/laminas-diactoros/src/Module.php
vendored
Normal file
15
vendor/laminas/laminas-diactoros/src/Module.php
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
class Module
|
||||||
|
{
|
||||||
|
public function getConfig(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'service_manager' => (new ConfigProvider())->getDependencies(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
88
vendor/laminas/laminas-diactoros/src/PhpInputStream.php
vendored
Normal file
88
vendor/laminas/laminas-diactoros/src/PhpInputStream.php
vendored
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use function stream_get_contents;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caching version of php://input
|
||||||
|
*/
|
||||||
|
class PhpInputStream extends Stream
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $cache = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $reachedEof = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|resource $stream
|
||||||
|
*/
|
||||||
|
public function __construct($stream = 'php://input')
|
||||||
|
{
|
||||||
|
parent::__construct($stream, 'r');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function __toString() : string
|
||||||
|
{
|
||||||
|
if ($this->reachedEof) {
|
||||||
|
return $this->cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->getContents();
|
||||||
|
return $this->cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function isWritable() : bool
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function read($length) : string
|
||||||
|
{
|
||||||
|
$content = parent::read($length);
|
||||||
|
if (! $this->reachedEof) {
|
||||||
|
$this->cache .= $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->eof()) {
|
||||||
|
$this->reachedEof = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getContents($maxLength = -1) : string
|
||||||
|
{
|
||||||
|
if ($this->reachedEof) {
|
||||||
|
return $this->cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
$contents = stream_get_contents($this->resource, $maxLength);
|
||||||
|
$this->cache .= $contents;
|
||||||
|
|
||||||
|
if ($maxLength === -1 || $this->eof()) {
|
||||||
|
$this->reachedEof = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $contents;
|
||||||
|
}
|
||||||
|
}
|
177
vendor/laminas/laminas-diactoros/src/RelativeStream.php
vendored
Normal file
177
vendor/laminas/laminas-diactoros/src/RelativeStream.php
vendored
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
|
||||||
|
use const SEEK_SET;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class RelativeStream
|
||||||
|
*
|
||||||
|
* Wrapper for default Stream class, representing subpart (starting from given offset) of initial stream.
|
||||||
|
* It can be used to avoid copying full stream, conserving memory.
|
||||||
|
* @example see Laminas\Diactoros\AbstractSerializer::splitStream()
|
||||||
|
*/
|
||||||
|
final class RelativeStream implements StreamInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var StreamInterface
|
||||||
|
*/
|
||||||
|
private $decoratedStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $offset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor
|
||||||
|
*
|
||||||
|
* @param StreamInterface $decoratedStream
|
||||||
|
* @param int $offset
|
||||||
|
*/
|
||||||
|
public function __construct(StreamInterface $decoratedStream, ?int $offset)
|
||||||
|
{
|
||||||
|
$this->decoratedStream = $decoratedStream;
|
||||||
|
$this->offset = (int) $offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function __toString() : string
|
||||||
|
{
|
||||||
|
if ($this->isSeekable()) {
|
||||||
|
$this->seek(0);
|
||||||
|
}
|
||||||
|
return $this->getContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function close() : void
|
||||||
|
{
|
||||||
|
$this->decoratedStream->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function detach()
|
||||||
|
{
|
||||||
|
return $this->decoratedStream->detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getSize() : int
|
||||||
|
{
|
||||||
|
return $this->decoratedStream->getSize() - $this->offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function tell() : int
|
||||||
|
{
|
||||||
|
return $this->decoratedStream->tell() - $this->offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function eof() : bool
|
||||||
|
{
|
||||||
|
return $this->decoratedStream->eof();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function isSeekable() : bool
|
||||||
|
{
|
||||||
|
return $this->decoratedStream->isSeekable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function seek($offset, $whence = SEEK_SET) : void
|
||||||
|
{
|
||||||
|
if ($whence == SEEK_SET) {
|
||||||
|
$this->decoratedStream->seek($offset + $this->offset, $whence);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$this->decoratedStream->seek($offset, $whence);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function rewind() : void
|
||||||
|
{
|
||||||
|
$this->seek(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function isWritable() : bool
|
||||||
|
{
|
||||||
|
return $this->decoratedStream->isWritable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function write($string) : int
|
||||||
|
{
|
||||||
|
if ($this->tell() < 0) {
|
||||||
|
throw new Exception\InvalidStreamPointerPositionException();
|
||||||
|
}
|
||||||
|
return $this->decoratedStream->write($string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function isReadable() : bool
|
||||||
|
{
|
||||||
|
return $this->decoratedStream->isReadable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function read($length) : string
|
||||||
|
{
|
||||||
|
if ($this->tell() < 0) {
|
||||||
|
throw new Exception\InvalidStreamPointerPositionException();
|
||||||
|
}
|
||||||
|
return $this->decoratedStream->read($length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getContents() : string
|
||||||
|
{
|
||||||
|
if ($this->tell() < 0) {
|
||||||
|
throw new Exception\InvalidStreamPointerPositionException();
|
||||||
|
}
|
||||||
|
return $this->decoratedStream->getContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getMetadata($key = null)
|
||||||
|
{
|
||||||
|
return $this->decoratedStream->getMetadata($key);
|
||||||
|
}
|
||||||
|
}
|
70
vendor/laminas/laminas-diactoros/src/Request.php
vendored
Normal file
70
vendor/laminas/laminas-diactoros/src/Request.php
vendored
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\RequestInterface;
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
use Psr\Http\Message\UriInterface;
|
||||||
|
|
||||||
|
use function strtolower;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP Request encapsulation
|
||||||
|
*
|
||||||
|
* Requests are considered immutable; all methods that might change state are
|
||||||
|
* implemented such that they retain the internal state of the current
|
||||||
|
* message and return a new instance that contains the changed state.
|
||||||
|
*/
|
||||||
|
class Request implements RequestInterface
|
||||||
|
{
|
||||||
|
use RequestTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param null|string|UriInterface $uri URI for the request, if any.
|
||||||
|
* @param null|string $method HTTP method for the request, if any.
|
||||||
|
* @param string|resource|StreamInterface $body Message body, if any.
|
||||||
|
* @param array $headers Headers for the message, if any.
|
||||||
|
* @throws Exception\InvalidArgumentException for any invalid value.
|
||||||
|
*/
|
||||||
|
public function __construct($uri = null, string $method = null, $body = 'php://temp', array $headers = [])
|
||||||
|
{
|
||||||
|
$this->initialize($uri, $method, $body, $headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getHeaders() : array
|
||||||
|
{
|
||||||
|
$headers = $this->headers;
|
||||||
|
if (! $this->hasHeader('host')
|
||||||
|
&& $this->uri->getHost()
|
||||||
|
) {
|
||||||
|
$headers['Host'] = [$this->getHostFromUri()];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getHeader($header) : array
|
||||||
|
{
|
||||||
|
if (! $this->hasHeader($header)) {
|
||||||
|
if (strtolower($header) === 'host'
|
||||||
|
&& $this->uri->getHost()
|
||||||
|
) {
|
||||||
|
return [$this->getHostFromUri()];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$header = $this->headerNames[strtolower($header)];
|
||||||
|
|
||||||
|
return $this->headers[$header];
|
||||||
|
}
|
||||||
|
}
|
77
vendor/laminas/laminas-diactoros/src/Request/ArraySerializer.php
vendored
Normal file
77
vendor/laminas/laminas-diactoros/src/Request/ArraySerializer.php
vendored
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Request;
|
||||||
|
|
||||||
|
use Laminas\Diactoros\Exception;
|
||||||
|
use Laminas\Diactoros\Request;
|
||||||
|
use Laminas\Diactoros\Stream;
|
||||||
|
use Psr\Http\Message\RequestInterface;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize or deserialize request messages to/from arrays.
|
||||||
|
*
|
||||||
|
* This class provides functionality for serializing a RequestInterface instance
|
||||||
|
* to an array, as well as the reverse operation of creating a Request instance
|
||||||
|
* from an array representing a message.
|
||||||
|
*/
|
||||||
|
final class ArraySerializer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Serialize a request message to an array.
|
||||||
|
*/
|
||||||
|
public static function toArray(RequestInterface $request) : array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'method' => $request->getMethod(),
|
||||||
|
'request_target' => $request->getRequestTarget(),
|
||||||
|
'uri' => (string) $request->getUri(),
|
||||||
|
'protocol_version' => $request->getProtocolVersion(),
|
||||||
|
'headers' => $request->getHeaders(),
|
||||||
|
'body' => (string) $request->getBody(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize a request array to a request instance.
|
||||||
|
*
|
||||||
|
* @throws Exception\DeserializationException when cannot deserialize response
|
||||||
|
*/
|
||||||
|
public static function fromArray(array $serializedRequest) : Request
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$uri = self::getValueFromKey($serializedRequest, 'uri');
|
||||||
|
$method = self::getValueFromKey($serializedRequest, 'method');
|
||||||
|
$body = new Stream('php://memory', 'wb+');
|
||||||
|
$body->write(self::getValueFromKey($serializedRequest, 'body'));
|
||||||
|
$headers = self::getValueFromKey($serializedRequest, 'headers');
|
||||||
|
$requestTarget = self::getValueFromKey($serializedRequest, 'request_target');
|
||||||
|
$protocolVersion = self::getValueFromKey($serializedRequest, 'protocol_version');
|
||||||
|
|
||||||
|
return (new Request($uri, $method, $body, $headers))
|
||||||
|
->withRequestTarget($requestTarget)
|
||||||
|
->withProtocolVersion($protocolVersion);
|
||||||
|
} catch (Throwable $exception) {
|
||||||
|
throw Exception\DeserializationException::forRequestFromArray($exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
* @throws Exception\DeserializationException
|
||||||
|
*/
|
||||||
|
private static function getValueFromKey(array $data, string $key, string $message = null)
|
||||||
|
{
|
||||||
|
if (isset($data[$key])) {
|
||||||
|
return $data[$key];
|
||||||
|
}
|
||||||
|
if ($message === null) {
|
||||||
|
$message = sprintf('Missing "%s" key in serialized request', $key);
|
||||||
|
}
|
||||||
|
throw new Exception\DeserializationException($message);
|
||||||
|
}
|
||||||
|
}
|
136
vendor/laminas/laminas-diactoros/src/Request/Serializer.php
vendored
Normal file
136
vendor/laminas/laminas-diactoros/src/Request/Serializer.php
vendored
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Request;
|
||||||
|
|
||||||
|
use Laminas\Diactoros\AbstractSerializer;
|
||||||
|
use Laminas\Diactoros\Exception;
|
||||||
|
use Laminas\Diactoros\Request;
|
||||||
|
use Laminas\Diactoros\Stream;
|
||||||
|
use Laminas\Diactoros\Uri;
|
||||||
|
use Psr\Http\Message\RequestInterface;
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
|
||||||
|
use function preg_match;
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize (cast to string) or deserialize (cast string to Request) messages.
|
||||||
|
*
|
||||||
|
* This class provides functionality for serializing a RequestInterface instance
|
||||||
|
* to a string, as well as the reverse operation of creating a Request instance
|
||||||
|
* from a string/stream representing a message.
|
||||||
|
*/
|
||||||
|
final class Serializer extends AbstractSerializer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Deserialize a request string to a request instance.
|
||||||
|
*
|
||||||
|
* Internally, casts the message to a stream and invokes fromStream().
|
||||||
|
*
|
||||||
|
* @throws Exception\SerializationException when errors occur parsing the message.
|
||||||
|
*/
|
||||||
|
public static function fromString(string $message) : Request
|
||||||
|
{
|
||||||
|
$stream = new Stream('php://temp', 'wb+');
|
||||||
|
$stream->write($message);
|
||||||
|
return self::fromStream($stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize a request stream to a request instance.
|
||||||
|
*
|
||||||
|
* @throws Exception\InvalidArgumentException if the message stream is not
|
||||||
|
* readable or seekable.
|
||||||
|
* @throws Exception\SerializationException if an invalid request line is detected.
|
||||||
|
*/
|
||||||
|
public static function fromStream(StreamInterface $stream) : Request
|
||||||
|
{
|
||||||
|
if (! $stream->isReadable() || ! $stream->isSeekable()) {
|
||||||
|
throw new Exception\InvalidArgumentException('Message stream must be both readable and seekable');
|
||||||
|
}
|
||||||
|
|
||||||
|
$stream->rewind();
|
||||||
|
|
||||||
|
[$method, $requestTarget, $version] = self::getRequestLine($stream);
|
||||||
|
$uri = self::createUriFromRequestTarget($requestTarget);
|
||||||
|
|
||||||
|
[$headers, $body] = self::splitStream($stream);
|
||||||
|
|
||||||
|
return (new Request($uri, $method, $body, $headers))
|
||||||
|
->withProtocolVersion($version)
|
||||||
|
->withRequestTarget($requestTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize a request message to a string.
|
||||||
|
*/
|
||||||
|
public static function toString(RequestInterface $request) : string
|
||||||
|
{
|
||||||
|
$httpMethod = $request->getMethod();
|
||||||
|
$headers = self::serializeHeaders($request->getHeaders());
|
||||||
|
$body = (string) $request->getBody();
|
||||||
|
$format = '%s %s HTTP/%s%s%s';
|
||||||
|
|
||||||
|
if (! empty($headers)) {
|
||||||
|
$headers = "\r\n" . $headers;
|
||||||
|
}
|
||||||
|
if (! empty($body)) {
|
||||||
|
$headers .= "\r\n\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
$format,
|
||||||
|
$httpMethod,
|
||||||
|
$request->getRequestTarget(),
|
||||||
|
$request->getProtocolVersion(),
|
||||||
|
$headers,
|
||||||
|
$body
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the components of the request line.
|
||||||
|
*
|
||||||
|
* Retrieves the first line of the stream and parses it, raising an
|
||||||
|
* exception if it does not follow specifications; if valid, returns a list
|
||||||
|
* with the method, target, and version, in that order.
|
||||||
|
*
|
||||||
|
* @throws Exception\SerializationException
|
||||||
|
*/
|
||||||
|
private static function getRequestLine(StreamInterface $stream) : array
|
||||||
|
{
|
||||||
|
$requestLine = self::getLine($stream);
|
||||||
|
|
||||||
|
if (! preg_match(
|
||||||
|
'#^(?P<method>[!\#$%&\'*+.^_`|~a-zA-Z0-9-]+) (?P<target>[^\s]+) HTTP/(?P<version>[1-9]\d*\.\d+)$#',
|
||||||
|
$requestLine,
|
||||||
|
$matches
|
||||||
|
)) {
|
||||||
|
throw Exception\SerializationException::forInvalidRequestLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
return [$matches['method'], $matches['target'], $matches['version']];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and return a Uri instance based on the provided request target.
|
||||||
|
*
|
||||||
|
* If the request target is of authority or asterisk form, an empty Uri
|
||||||
|
* instance is returned; otherwise, the value is used to create and return
|
||||||
|
* a new Uri instance.
|
||||||
|
*/
|
||||||
|
private static function createUriFromRequestTarget(string $requestTarget) : Uri
|
||||||
|
{
|
||||||
|
if (preg_match('#^https?://#', $requestTarget)) {
|
||||||
|
return new Uri($requestTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match('#^(\*|[^/])#', $requestTarget)) {
|
||||||
|
return new Uri();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Uri($requestTarget);
|
||||||
|
}
|
||||||
|
}
|
19
vendor/laminas/laminas-diactoros/src/RequestFactory.php
vendored
Normal file
19
vendor/laminas/laminas-diactoros/src/RequestFactory.php
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\RequestFactoryInterface;
|
||||||
|
use Psr\Http\Message\RequestInterface;
|
||||||
|
|
||||||
|
class RequestFactory implements RequestFactoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function createRequest(string $method, $uri) : RequestInterface
|
||||||
|
{
|
||||||
|
return new Request($uri, $method);
|
||||||
|
}
|
||||||
|
}
|
314
vendor/laminas/laminas-diactoros/src/RequestTrait.php
vendored
Normal file
314
vendor/laminas/laminas-diactoros/src/RequestTrait.php
vendored
Normal file
|
@ -0,0 +1,314 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\RequestInterface;
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
use Psr\Http\Message\UriInterface;
|
||||||
|
|
||||||
|
use function array_keys;
|
||||||
|
use function get_class;
|
||||||
|
use function gettype;
|
||||||
|
use function is_object;
|
||||||
|
use function is_string;
|
||||||
|
use function preg_match;
|
||||||
|
use function sprintf;
|
||||||
|
use function strtolower;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trait with common request behaviors.
|
||||||
|
*
|
||||||
|
* Server and client-side requests differ slightly in how the Host header is
|
||||||
|
* handled; on client-side, it should be calculated on-the-fly from the
|
||||||
|
* composed URI (if present), while on server-side, it will be calculated from
|
||||||
|
* the environment. As such, this trait exists to provide the common code
|
||||||
|
* between both client-side and server-side requests, and each can then
|
||||||
|
* use the headers functionality required by their implementations.
|
||||||
|
*/
|
||||||
|
trait RequestTrait
|
||||||
|
{
|
||||||
|
use MessageTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $method = 'GET';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request-target, if it has been provided or calculated.
|
||||||
|
*
|
||||||
|
* @var null|string
|
||||||
|
*/
|
||||||
|
private $requestTarget;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var UriInterface
|
||||||
|
*/
|
||||||
|
private $uri;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize request state.
|
||||||
|
*
|
||||||
|
* Used by constructors.
|
||||||
|
*
|
||||||
|
* @param null|string|UriInterface $uri URI for the request, if any.
|
||||||
|
* @param null|string $method HTTP method for the request, if any.
|
||||||
|
* @param string|resource|StreamInterface $body Message body, if any.
|
||||||
|
* @param array $headers Headers for the message, if any.
|
||||||
|
* @throws Exception\InvalidArgumentException for any invalid value.
|
||||||
|
*/
|
||||||
|
private function initialize(
|
||||||
|
$uri = null,
|
||||||
|
string $method = null,
|
||||||
|
$body = 'php://memory',
|
||||||
|
array $headers = []
|
||||||
|
) : void {
|
||||||
|
if ($method !== null) {
|
||||||
|
$this->setMethod($method);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->uri = $this->createUri($uri);
|
||||||
|
$this->stream = $this->getStream($body, 'wb+');
|
||||||
|
|
||||||
|
$this->setHeaders($headers);
|
||||||
|
|
||||||
|
// per PSR-7: attempt to set the Host header from a provided URI if no
|
||||||
|
// Host header is provided
|
||||||
|
if (! $this->hasHeader('Host') && $this->uri->getHost()) {
|
||||||
|
$this->headerNames['host'] = 'Host';
|
||||||
|
$this->headers['Host'] = [$this->getHostFromUri()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and return a URI instance.
|
||||||
|
*
|
||||||
|
* If `$uri` is a already a `UriInterface` instance, returns it.
|
||||||
|
*
|
||||||
|
* If `$uri` is a string, passes it to the `Uri` constructor to return an
|
||||||
|
* instance.
|
||||||
|
*
|
||||||
|
* If `$uri is null, creates and returns an empty `Uri` instance.
|
||||||
|
*
|
||||||
|
* Otherwise, it raises an exception.
|
||||||
|
*
|
||||||
|
* @param null|string|UriInterface $uri
|
||||||
|
* @throws Exception\InvalidArgumentException
|
||||||
|
*/
|
||||||
|
private function createUri($uri) : UriInterface
|
||||||
|
{
|
||||||
|
if ($uri instanceof UriInterface) {
|
||||||
|
return $uri;
|
||||||
|
}
|
||||||
|
if (is_string($uri)) {
|
||||||
|
return new Uri($uri);
|
||||||
|
}
|
||||||
|
if ($uri === null) {
|
||||||
|
return new Uri();
|
||||||
|
}
|
||||||
|
throw new Exception\InvalidArgumentException(
|
||||||
|
'Invalid URI provided; must be null, a string, or a Psr\Http\Message\UriInterface instance'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the message's request target.
|
||||||
|
*
|
||||||
|
* Retrieves the message's request-target either as it will appear (for
|
||||||
|
* clients), as it appeared at request (for servers), or as it was
|
||||||
|
* specified for the instance (see withRequestTarget()).
|
||||||
|
*
|
||||||
|
* In most cases, this will be the origin-form of the composed URI,
|
||||||
|
* unless a value was provided to the concrete implementation (see
|
||||||
|
* withRequestTarget() below).
|
||||||
|
*
|
||||||
|
* If no URI is available, and no request-target has been specifically
|
||||||
|
* provided, this method MUST return the string "/".
|
||||||
|
*/
|
||||||
|
public function getRequestTarget() : string
|
||||||
|
{
|
||||||
|
if (null !== $this->requestTarget) {
|
||||||
|
return $this->requestTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
$target = $this->uri->getPath();
|
||||||
|
if ($this->uri->getQuery()) {
|
||||||
|
$target .= '?' . $this->uri->getQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($target)) {
|
||||||
|
$target = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $target;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance with a specific request-target.
|
||||||
|
*
|
||||||
|
* If the request needs a non-origin-form request-target — e.g., for
|
||||||
|
* specifying an absolute-form, authority-form, or asterisk-form —
|
||||||
|
* this method may be used to create an instance with the specified
|
||||||
|
* request-target, verbatim.
|
||||||
|
*
|
||||||
|
* This method MUST be implemented in such a way as to retain the
|
||||||
|
* immutability of the message, and MUST return a new instance that has the
|
||||||
|
* changed request target.
|
||||||
|
*
|
||||||
|
* @link http://tools.ietf.org/html/rfc7230#section-2.7 (for the various
|
||||||
|
* request-target forms allowed in request messages)
|
||||||
|
* @param string $requestTarget
|
||||||
|
* @throws Exception\InvalidArgumentException if the request target is invalid.
|
||||||
|
*/
|
||||||
|
public function withRequestTarget($requestTarget) : RequestInterface
|
||||||
|
{
|
||||||
|
if (preg_match('#\s#', $requestTarget)) {
|
||||||
|
throw new Exception\InvalidArgumentException(
|
||||||
|
'Invalid request target provided; cannot contain whitespace'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$new = clone $this;
|
||||||
|
$new->requestTarget = $requestTarget;
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the HTTP method of the request.
|
||||||
|
*
|
||||||
|
* @return string Returns the request method.
|
||||||
|
*/
|
||||||
|
public function getMethod() : string
|
||||||
|
{
|
||||||
|
return $this->method;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an instance with the provided HTTP method.
|
||||||
|
*
|
||||||
|
* While HTTP method names are typically all uppercase characters, HTTP
|
||||||
|
* method names are case-sensitive and thus implementations SHOULD NOT
|
||||||
|
* modify the given string.
|
||||||
|
*
|
||||||
|
* This method MUST be implemented in such a way as to retain the
|
||||||
|
* immutability of the message, and MUST return an instance that has the
|
||||||
|
* changed request method.
|
||||||
|
*
|
||||||
|
* @param string $method Case-insensitive method.
|
||||||
|
* @throws Exception\InvalidArgumentException for invalid HTTP methods.
|
||||||
|
*/
|
||||||
|
public function withMethod($method) : RequestInterface
|
||||||
|
{
|
||||||
|
$new = clone $this;
|
||||||
|
$new->setMethod($method);
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the URI instance.
|
||||||
|
*
|
||||||
|
* This method MUST return a UriInterface instance.
|
||||||
|
*
|
||||||
|
* @link http://tools.ietf.org/html/rfc3986#section-4.3
|
||||||
|
* @return UriInterface Returns a UriInterface instance
|
||||||
|
* representing the URI of the request, if any.
|
||||||
|
*/
|
||||||
|
public function getUri() : UriInterface
|
||||||
|
{
|
||||||
|
return $this->uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an instance with the provided URI.
|
||||||
|
*
|
||||||
|
* This method will update the Host header of the returned request by
|
||||||
|
* default if the URI contains a host component. If the URI does not
|
||||||
|
* contain a host component, any pre-existing Host header will be carried
|
||||||
|
* over to the returned request.
|
||||||
|
*
|
||||||
|
* You can opt-in to preserving the original state of the Host header by
|
||||||
|
* setting `$preserveHost` to `true`. When `$preserveHost` is set to
|
||||||
|
* `true`, the returned request will not update the Host header of the
|
||||||
|
* returned message -- even if the message contains no Host header. This
|
||||||
|
* means that a call to `getHeader('Host')` on the original request MUST
|
||||||
|
* equal the return value of a call to `getHeader('Host')` on the returned
|
||||||
|
* request.
|
||||||
|
*
|
||||||
|
* This method MUST be implemented in such a way as to retain the
|
||||||
|
* immutability of the message, and MUST return an instance that has the
|
||||||
|
* new UriInterface instance.
|
||||||
|
*
|
||||||
|
* @link http://tools.ietf.org/html/rfc3986#section-4.3
|
||||||
|
* @param UriInterface $uri New request URI to use.
|
||||||
|
* @param bool $preserveHost Preserve the original state of the Host header.
|
||||||
|
*/
|
||||||
|
public function withUri(UriInterface $uri, $preserveHost = false) : RequestInterface
|
||||||
|
{
|
||||||
|
$new = clone $this;
|
||||||
|
$new->uri = $uri;
|
||||||
|
|
||||||
|
if ($preserveHost && $this->hasHeader('Host')) {
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $uri->getHost()) {
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
$host = $uri->getHost();
|
||||||
|
if ($uri->getPort()) {
|
||||||
|
$host .= ':' . $uri->getPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
$new->headerNames['host'] = 'Host';
|
||||||
|
|
||||||
|
// Remove an existing host header if present, regardless of current
|
||||||
|
// de-normalization of the header name.
|
||||||
|
// @see https://github.com/zendframework/zend-diactoros/issues/91
|
||||||
|
foreach (array_keys($new->headers) as $header) {
|
||||||
|
if (strtolower($header) === 'host') {
|
||||||
|
unset($new->headers[$header]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$new->headers['Host'] = [$host];
|
||||||
|
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set and validate the HTTP method
|
||||||
|
*
|
||||||
|
* @param string $method
|
||||||
|
* @throws Exception\InvalidArgumentException on invalid HTTP method.
|
||||||
|
*/
|
||||||
|
private function setMethod($method) : void
|
||||||
|
{
|
||||||
|
if (! is_string($method)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'Unsupported HTTP method; must be a string, received %s',
|
||||||
|
is_object($method) ? get_class($method) : gettype($method)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! preg_match('/^[!#$%&\'*+.^_`\|~0-9a-z-]+$/i', $method)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'Unsupported HTTP method "%s" provided',
|
||||||
|
$method
|
||||||
|
));
|
||||||
|
}
|
||||||
|
$this->method = $method;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the host from the URI instance
|
||||||
|
*/
|
||||||
|
private function getHostFromUri() : string
|
||||||
|
{
|
||||||
|
$host = $this->uri->getHost();
|
||||||
|
$host .= $this->uri->getPort() ? ':' . $this->uri->getPort() : '';
|
||||||
|
return $host;
|
||||||
|
}
|
||||||
|
}
|
196
vendor/laminas/laminas-diactoros/src/Response.php
vendored
Normal file
196
vendor/laminas/laminas-diactoros/src/Response.php
vendored
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
|
||||||
|
use function gettype;
|
||||||
|
use function is_float;
|
||||||
|
use function is_numeric;
|
||||||
|
use function is_scalar;
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP response encapsulation.
|
||||||
|
*
|
||||||
|
* Responses are considered immutable; all methods that might change state are
|
||||||
|
* implemented such that they retain the internal state of the current
|
||||||
|
* message and return a new instance that contains the changed state.
|
||||||
|
*/
|
||||||
|
class Response implements ResponseInterface
|
||||||
|
{
|
||||||
|
use MessageTrait;
|
||||||
|
|
||||||
|
const MIN_STATUS_CODE_VALUE = 100;
|
||||||
|
const MAX_STATUS_CODE_VALUE = 599;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of standard HTTP status code/reason phrases
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* @psalm-var array<positive-int, non-empty-string>
|
||||||
|
*/
|
||||||
|
private $phrases = [
|
||||||
|
// INFORMATIONAL CODES
|
||||||
|
100 => 'Continue',
|
||||||
|
101 => 'Switching Protocols',
|
||||||
|
102 => 'Processing',
|
||||||
|
103 => 'Early Hints',
|
||||||
|
// SUCCESS CODES
|
||||||
|
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',
|
||||||
|
226 => 'IM Used',
|
||||||
|
// REDIRECTION CODES
|
||||||
|
300 => 'Multiple Choices',
|
||||||
|
301 => 'Moved Permanently',
|
||||||
|
302 => 'Found',
|
||||||
|
303 => 'See Other',
|
||||||
|
304 => 'Not Modified',
|
||||||
|
305 => 'Use Proxy',
|
||||||
|
306 => 'Switch Proxy', // Deprecated to 306 => '(Unused)'
|
||||||
|
307 => 'Temporary Redirect',
|
||||||
|
308 => 'Permanent Redirect',
|
||||||
|
// CLIENT ERROR
|
||||||
|
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 Timeout',
|
||||||
|
409 => 'Conflict',
|
||||||
|
410 => 'Gone',
|
||||||
|
411 => 'Length Required',
|
||||||
|
412 => 'Precondition Failed',
|
||||||
|
413 => 'Payload Too Large',
|
||||||
|
414 => 'URI Too Long',
|
||||||
|
415 => 'Unsupported Media Type',
|
||||||
|
416 => 'Range Not Satisfiable',
|
||||||
|
417 => 'Expectation Failed',
|
||||||
|
418 => 'I\'m a teapot',
|
||||||
|
421 => 'Misdirected Request',
|
||||||
|
422 => 'Unprocessable Entity',
|
||||||
|
423 => 'Locked',
|
||||||
|
424 => 'Failed Dependency',
|
||||||
|
425 => 'Too Early',
|
||||||
|
426 => 'Upgrade Required',
|
||||||
|
428 => 'Precondition Required',
|
||||||
|
429 => 'Too Many Requests',
|
||||||
|
431 => 'Request Header Fields Too Large',
|
||||||
|
444 => 'Connection Closed Without Response',
|
||||||
|
451 => 'Unavailable For Legal Reasons',
|
||||||
|
// SERVER ERROR
|
||||||
|
499 => 'Client Closed Request',
|
||||||
|
500 => 'Internal Server Error',
|
||||||
|
501 => 'Not Implemented',
|
||||||
|
502 => 'Bad Gateway',
|
||||||
|
503 => 'Service Unavailable',
|
||||||
|
504 => 'Gateway Timeout',
|
||||||
|
505 => 'HTTP Version Not Supported',
|
||||||
|
506 => 'Variant Also Negotiates',
|
||||||
|
507 => 'Insufficient Storage',
|
||||||
|
508 => 'Loop Detected',
|
||||||
|
510 => 'Not Extended',
|
||||||
|
511 => 'Network Authentication Required',
|
||||||
|
599 => 'Network Connect Timeout Error',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $reasonPhrase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $statusCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|resource|StreamInterface $body Stream identifier and/or actual stream resource
|
||||||
|
* @param int $status Status code for the response, if any.
|
||||||
|
* @param array $headers Headers for the response, if any.
|
||||||
|
* @throws Exception\InvalidArgumentException on any invalid element.
|
||||||
|
*/
|
||||||
|
public function __construct($body = 'php://memory', int $status = 200, array $headers = [])
|
||||||
|
{
|
||||||
|
$this->setStatusCode($status);
|
||||||
|
$this->stream = $this->getStream($body, 'wb+');
|
||||||
|
$this->setHeaders($headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getStatusCode() : int
|
||||||
|
{
|
||||||
|
return $this->statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getReasonPhrase() : string
|
||||||
|
{
|
||||||
|
return $this->reasonPhrase;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function withStatus($code, $reasonPhrase = '') : Response
|
||||||
|
{
|
||||||
|
$new = clone $this;
|
||||||
|
$new->setStatusCode($code, $reasonPhrase);
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a valid status code.
|
||||||
|
*
|
||||||
|
* @param int $code
|
||||||
|
* @param string $reasonPhrase
|
||||||
|
* @throws Exception\InvalidArgumentException on an invalid status code.
|
||||||
|
*/
|
||||||
|
private function setStatusCode($code, $reasonPhrase = '') : void
|
||||||
|
{
|
||||||
|
if (! is_numeric($code)
|
||||||
|
|| is_float($code)
|
||||||
|
|| $code < static::MIN_STATUS_CODE_VALUE
|
||||||
|
|| $code > static::MAX_STATUS_CODE_VALUE
|
||||||
|
) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'Invalid status code "%s"; must be an integer between %d and %d, inclusive',
|
||||||
|
is_scalar($code) ? $code : gettype($code),
|
||||||
|
static::MIN_STATUS_CODE_VALUE,
|
||||||
|
static::MAX_STATUS_CODE_VALUE
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! is_string($reasonPhrase)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'Unsupported response reason phrase; must be a string, received %s',
|
||||||
|
is_object($reasonPhrase) ? get_class($reasonPhrase) : gettype($reasonPhrase)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($reasonPhrase === '' && isset($this->phrases[$code])) {
|
||||||
|
$reasonPhrase = $this->phrases[$code];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->reasonPhrase = $reasonPhrase;
|
||||||
|
$this->statusCode = (int) $code;
|
||||||
|
}
|
||||||
|
}
|
79
vendor/laminas/laminas-diactoros/src/Response/ArraySerializer.php
vendored
Normal file
79
vendor/laminas/laminas-diactoros/src/Response/ArraySerializer.php
vendored
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Response;
|
||||||
|
|
||||||
|
use Laminas\Diactoros\Exception;
|
||||||
|
use Laminas\Diactoros\Response;
|
||||||
|
use Laminas\Diactoros\Stream;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize or deserialize response messages to/from arrays.
|
||||||
|
*
|
||||||
|
* This class provides functionality for serializing a ResponseInterface instance
|
||||||
|
* to an array, as well as the reverse operation of creating a Response instance
|
||||||
|
* from an array representing a message.
|
||||||
|
*/
|
||||||
|
final class ArraySerializer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Serialize a response message to an array.
|
||||||
|
*/
|
||||||
|
public static function toArray(ResponseInterface $response) : array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'status_code' => $response->getStatusCode(),
|
||||||
|
'reason_phrase' => $response->getReasonPhrase(),
|
||||||
|
'protocol_version' => $response->getProtocolVersion(),
|
||||||
|
'headers' => $response->getHeaders(),
|
||||||
|
'body' => (string) $response->getBody(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize a response array to a response instance.
|
||||||
|
*
|
||||||
|
* @throws Exception\DeserializationException when cannot deserialize response
|
||||||
|
*/
|
||||||
|
public static function fromArray(array $serializedResponse) : Response
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$body = new Stream('php://memory', 'wb+');
|
||||||
|
$body->write(self::getValueFromKey($serializedResponse, 'body'));
|
||||||
|
|
||||||
|
$statusCode = self::getValueFromKey($serializedResponse, 'status_code');
|
||||||
|
$headers = self::getValueFromKey($serializedResponse, 'headers');
|
||||||
|
$protocolVersion = self::getValueFromKey($serializedResponse, 'protocol_version');
|
||||||
|
$reasonPhrase = self::getValueFromKey($serializedResponse, 'reason_phrase');
|
||||||
|
|
||||||
|
return (new Response($body, $statusCode, $headers))
|
||||||
|
->withProtocolVersion($protocolVersion)
|
||||||
|
->withStatus($statusCode, $reasonPhrase);
|
||||||
|
} catch (Throwable $exception) {
|
||||||
|
throw Exception\DeserializationException::forResponseFromArray($exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @param string $key
|
||||||
|
* @param string $message
|
||||||
|
* @return mixed
|
||||||
|
* @throws Exception\DeserializationException
|
||||||
|
*/
|
||||||
|
private static function getValueFromKey(array $data, string $key, string $message = null)
|
||||||
|
{
|
||||||
|
if (isset($data[$key])) {
|
||||||
|
return $data[$key];
|
||||||
|
}
|
||||||
|
if ($message === null) {
|
||||||
|
$message = sprintf('Missing "%s" key in serialized response', $key);
|
||||||
|
}
|
||||||
|
throw new Exception\DeserializationException($message);
|
||||||
|
}
|
||||||
|
}
|
37
vendor/laminas/laminas-diactoros/src/Response/EmptyResponse.php
vendored
Normal file
37
vendor/laminas/laminas-diactoros/src/Response/EmptyResponse.php
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Response;
|
||||||
|
|
||||||
|
use Laminas\Diactoros\Response;
|
||||||
|
use Laminas\Diactoros\Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class representing empty HTTP responses.
|
||||||
|
*/
|
||||||
|
class EmptyResponse extends Response
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create an empty response with the given status code.
|
||||||
|
*
|
||||||
|
* @param int $status Status code for the response, if any.
|
||||||
|
* @param array $headers Headers for the response, if any.
|
||||||
|
*/
|
||||||
|
public function __construct(int $status = 204, array $headers = [])
|
||||||
|
{
|
||||||
|
$body = new Stream('php://temp', 'r');
|
||||||
|
parent::__construct($body, $status, $headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an empty response with the given headers.
|
||||||
|
*
|
||||||
|
* @param array $headers Headers for the response.
|
||||||
|
* @return EmptyResponse
|
||||||
|
*/
|
||||||
|
public static function withHeaders(array $headers) : EmptyResponse
|
||||||
|
{
|
||||||
|
return new static(204, $headers);
|
||||||
|
}
|
||||||
|
}
|
74
vendor/laminas/laminas-diactoros/src/Response/HtmlResponse.php
vendored
Normal file
74
vendor/laminas/laminas-diactoros/src/Response/HtmlResponse.php
vendored
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Response;
|
||||||
|
|
||||||
|
use Laminas\Diactoros\Exception;
|
||||||
|
use Laminas\Diactoros\Response;
|
||||||
|
use Laminas\Diactoros\Stream;
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
|
||||||
|
use function get_class;
|
||||||
|
use function gettype;
|
||||||
|
use function is_object;
|
||||||
|
use function is_string;
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTML response.
|
||||||
|
*
|
||||||
|
* Allows creating a response by passing an HTML string to the constructor;
|
||||||
|
* by default, sets a status code of 200 and sets the Content-Type header to
|
||||||
|
* text/html.
|
||||||
|
*/
|
||||||
|
class HtmlResponse extends Response
|
||||||
|
{
|
||||||
|
use InjectContentTypeTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an HTML response.
|
||||||
|
*
|
||||||
|
* Produces an HTML response with a Content-Type of text/html and a default
|
||||||
|
* status of 200.
|
||||||
|
*
|
||||||
|
* @param string|StreamInterface $html HTML or stream for the message body.
|
||||||
|
* @param int $status Integer status code for the response; 200 by default.
|
||||||
|
* @param array $headers Array of headers to use at initialization.
|
||||||
|
* @throws Exception\InvalidArgumentException if $html is neither a string or stream.
|
||||||
|
*/
|
||||||
|
public function __construct($html, int $status = 200, array $headers = [])
|
||||||
|
{
|
||||||
|
parent::__construct(
|
||||||
|
$this->createBody($html),
|
||||||
|
$status,
|
||||||
|
$this->injectContentType('text/html; charset=utf-8', $headers)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the message body.
|
||||||
|
*
|
||||||
|
* @param string|StreamInterface $html
|
||||||
|
* @throws Exception\InvalidArgumentException if $html is neither a string or stream.
|
||||||
|
*/
|
||||||
|
private function createBody($html) : StreamInterface
|
||||||
|
{
|
||||||
|
if ($html instanceof StreamInterface) {
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! is_string($html)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'Invalid content (%s) provided to %s',
|
||||||
|
(is_object($html) ? get_class($html) : gettype($html)),
|
||||||
|
__CLASS__
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$body = new Stream('php://temp', 'wb+');
|
||||||
|
$body->write($html);
|
||||||
|
$body->rewind();
|
||||||
|
return $body;
|
||||||
|
}
|
||||||
|
}
|
30
vendor/laminas/laminas-diactoros/src/Response/InjectContentTypeTrait.php
vendored
Normal file
30
vendor/laminas/laminas-diactoros/src/Response/InjectContentTypeTrait.php
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Response;
|
||||||
|
|
||||||
|
use function array_keys;
|
||||||
|
use function array_reduce;
|
||||||
|
use function strtolower;
|
||||||
|
|
||||||
|
trait InjectContentTypeTrait
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Inject the provided Content-Type, if none is already present.
|
||||||
|
*
|
||||||
|
* @return array Headers with injected Content-Type
|
||||||
|
*/
|
||||||
|
private function injectContentType(string $contentType, array $headers) : array
|
||||||
|
{
|
||||||
|
$hasContentType = array_reduce(array_keys($headers), function ($carry, $item) {
|
||||||
|
return $carry ?: (strtolower($item) === 'content-type');
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
if (! $hasContentType) {
|
||||||
|
$headers['content-type'] = [$contentType];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $headers;
|
||||||
|
}
|
||||||
|
}
|
178
vendor/laminas/laminas-diactoros/src/Response/JsonResponse.php
vendored
Normal file
178
vendor/laminas/laminas-diactoros/src/Response/JsonResponse.php
vendored
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Response;
|
||||||
|
|
||||||
|
use Laminas\Diactoros\Exception;
|
||||||
|
use Laminas\Diactoros\Response;
|
||||||
|
use Laminas\Diactoros\Stream;
|
||||||
|
|
||||||
|
use function is_object;
|
||||||
|
use function is_resource;
|
||||||
|
use function json_encode;
|
||||||
|
use function json_last_error;
|
||||||
|
use function json_last_error_msg;
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
|
use const JSON_ERROR_NONE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSON response.
|
||||||
|
*
|
||||||
|
* Allows creating a response by passing data to the constructor; by default,
|
||||||
|
* serializes the data to JSON, sets a status code of 200 and sets the
|
||||||
|
* Content-Type header to application/json.
|
||||||
|
*/
|
||||||
|
class JsonResponse extends Response
|
||||||
|
{
|
||||||
|
use InjectContentTypeTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default flags for json_encode; value of:
|
||||||
|
*
|
||||||
|
* <code>
|
||||||
|
* JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT | JSON_UNESCAPED_SLASHES
|
||||||
|
* </code>
|
||||||
|
*
|
||||||
|
* @const int
|
||||||
|
*/
|
||||||
|
const DEFAULT_JSON_FLAGS = 79;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
private $payload;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $encodingOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a JSON response with the given data.
|
||||||
|
*
|
||||||
|
* Default JSON encoding is performed with the following options, which
|
||||||
|
* produces RFC4627-compliant JSON, capable of embedding into HTML.
|
||||||
|
*
|
||||||
|
* - JSON_HEX_TAG
|
||||||
|
* - JSON_HEX_APOS
|
||||||
|
* - JSON_HEX_AMP
|
||||||
|
* - JSON_HEX_QUOT
|
||||||
|
* - JSON_UNESCAPED_SLASHES
|
||||||
|
*
|
||||||
|
* @param mixed $data Data to convert to JSON.
|
||||||
|
* @param int $status Integer status code for the response; 200 by default.
|
||||||
|
* @param array $headers Array of headers to use at initialization.
|
||||||
|
* @param int $encodingOptions JSON encoding options to use.
|
||||||
|
* @throws Exception\InvalidArgumentException if unable to encode the $data to JSON.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
$data,
|
||||||
|
int $status = 200,
|
||||||
|
array $headers = [],
|
||||||
|
int $encodingOptions = self::DEFAULT_JSON_FLAGS
|
||||||
|
) {
|
||||||
|
$this->setPayload($data);
|
||||||
|
$this->encodingOptions = $encodingOptions;
|
||||||
|
|
||||||
|
$json = $this->jsonEncode($data, $this->encodingOptions);
|
||||||
|
$body = $this->createBodyFromJson($json);
|
||||||
|
|
||||||
|
$headers = $this->injectContentType('application/json', $headers);
|
||||||
|
|
||||||
|
parent::__construct($body, $status, $headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getPayload()
|
||||||
|
{
|
||||||
|
return $this->payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $data
|
||||||
|
*/
|
||||||
|
public function withPayload($data) : JsonResponse
|
||||||
|
{
|
||||||
|
$new = clone $this;
|
||||||
|
$new->setPayload($data);
|
||||||
|
return $this->updateBodyFor($new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEncodingOptions() : int
|
||||||
|
{
|
||||||
|
return $this->encodingOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withEncodingOptions(int $encodingOptions) : JsonResponse
|
||||||
|
{
|
||||||
|
$new = clone $this;
|
||||||
|
$new->encodingOptions = $encodingOptions;
|
||||||
|
return $this->updateBodyFor($new);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createBodyFromJson(string $json) : Stream
|
||||||
|
{
|
||||||
|
$body = new Stream('php://temp', 'wb+');
|
||||||
|
$body->write($json);
|
||||||
|
$body->rewind();
|
||||||
|
|
||||||
|
return $body;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode the provided data to JSON.
|
||||||
|
*
|
||||||
|
* @param mixed $data
|
||||||
|
* @throws Exception\InvalidArgumentException if unable to encode the $data to JSON.
|
||||||
|
*/
|
||||||
|
private function jsonEncode($data, int $encodingOptions) : string
|
||||||
|
{
|
||||||
|
if (is_resource($data)) {
|
||||||
|
throw new Exception\InvalidArgumentException('Cannot JSON encode resources');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear json_last_error()
|
||||||
|
json_encode(null);
|
||||||
|
|
||||||
|
$json = json_encode($data, $encodingOptions);
|
||||||
|
|
||||||
|
if (JSON_ERROR_NONE !== json_last_error()) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'Unable to encode data to JSON in %s: %s',
|
||||||
|
__CLASS__,
|
||||||
|
json_last_error_msg()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $json;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $data
|
||||||
|
*/
|
||||||
|
private function setPayload($data) : void
|
||||||
|
{
|
||||||
|
if (is_object($data)) {
|
||||||
|
$data = clone $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->payload = $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the response body for the given instance.
|
||||||
|
*
|
||||||
|
* @param self $toUpdate Instance to update.
|
||||||
|
* @return JsonResponse Returns a new instance with an updated body.
|
||||||
|
*/
|
||||||
|
private function updateBodyFor(JsonResponse $toUpdate) : JsonResponse
|
||||||
|
{
|
||||||
|
$json = $this->jsonEncode($toUpdate->payload, $toUpdate->encodingOptions);
|
||||||
|
$body = $this->createBodyFromJson($json);
|
||||||
|
return $toUpdate->withBody($body);
|
||||||
|
}
|
||||||
|
}
|
47
vendor/laminas/laminas-diactoros/src/Response/RedirectResponse.php
vendored
Normal file
47
vendor/laminas/laminas-diactoros/src/Response/RedirectResponse.php
vendored
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Response;
|
||||||
|
|
||||||
|
use Laminas\Diactoros\Exception;
|
||||||
|
use Laminas\Diactoros\Response;
|
||||||
|
use Psr\Http\Message\UriInterface;
|
||||||
|
|
||||||
|
use function get_class;
|
||||||
|
use function gettype;
|
||||||
|
use function is_object;
|
||||||
|
use function is_string;
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Produce a redirect response.
|
||||||
|
*/
|
||||||
|
class RedirectResponse extends Response
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a redirect response.
|
||||||
|
*
|
||||||
|
* Produces a redirect response with a Location header and the given status
|
||||||
|
* (302 by default).
|
||||||
|
*
|
||||||
|
* Note: this method overwrites the `location` $headers value.
|
||||||
|
*
|
||||||
|
* @param string|UriInterface $uri URI for the Location header.
|
||||||
|
* @param int $status Integer status code for the redirect; 302 by default.
|
||||||
|
* @param array $headers Array of headers to use at initialization.
|
||||||
|
*/
|
||||||
|
public function __construct($uri, int $status = 302, array $headers = [])
|
||||||
|
{
|
||||||
|
if (! is_string($uri) && ! $uri instanceof UriInterface) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'Uri provided to %s MUST be a string or Psr\Http\Message\UriInterface instance; received "%s"',
|
||||||
|
__CLASS__,
|
||||||
|
(is_object($uri) ? get_class($uri) : gettype($uri))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$headers['location'] = [(string) $uri];
|
||||||
|
parent::__construct('php://temp', $status, $headers);
|
||||||
|
}
|
||||||
|
}
|
99
vendor/laminas/laminas-diactoros/src/Response/Serializer.php
vendored
Normal file
99
vendor/laminas/laminas-diactoros/src/Response/Serializer.php
vendored
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Response;
|
||||||
|
|
||||||
|
use Laminas\Diactoros\AbstractSerializer;
|
||||||
|
use Laminas\Diactoros\Exception;
|
||||||
|
use Laminas\Diactoros\Response;
|
||||||
|
use Laminas\Diactoros\Stream;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
|
||||||
|
use function preg_match;
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
|
final class Serializer extends AbstractSerializer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Deserialize a response string to a response instance.
|
||||||
|
*
|
||||||
|
* @throws Exception\SerializationException when errors occur parsing the message.
|
||||||
|
*/
|
||||||
|
public static function fromString(string $message) : Response
|
||||||
|
{
|
||||||
|
$stream = new Stream('php://temp', 'wb+');
|
||||||
|
$stream->write($message);
|
||||||
|
return static::fromStream($stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a response from a stream.
|
||||||
|
*
|
||||||
|
* @throws Exception\InvalidArgumentException when the stream is not readable.
|
||||||
|
* @throws Exception\SerializationException when errors occur parsing the message.
|
||||||
|
*/
|
||||||
|
public static function fromStream(StreamInterface $stream) : Response
|
||||||
|
{
|
||||||
|
if (! $stream->isReadable() || ! $stream->isSeekable()) {
|
||||||
|
throw new Exception\InvalidArgumentException('Message stream must be both readable and seekable');
|
||||||
|
}
|
||||||
|
|
||||||
|
$stream->rewind();
|
||||||
|
|
||||||
|
[$version, $status, $reasonPhrase] = self::getStatusLine($stream);
|
||||||
|
[$headers, $body] = self::splitStream($stream);
|
||||||
|
|
||||||
|
return (new Response($body, $status, $headers))
|
||||||
|
->withProtocolVersion($version)
|
||||||
|
->withStatus((int) $status, $reasonPhrase);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a string representation of a response.
|
||||||
|
*/
|
||||||
|
public static function toString(ResponseInterface $response) : string
|
||||||
|
{
|
||||||
|
$reasonPhrase = $response->getReasonPhrase();
|
||||||
|
$headers = self::serializeHeaders($response->getHeaders());
|
||||||
|
$body = (string) $response->getBody();
|
||||||
|
$format = 'HTTP/%s %d%s%s%s';
|
||||||
|
|
||||||
|
if (! empty($headers)) {
|
||||||
|
$headers = "\r\n" . $headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
$headers .= "\r\n\r\n";
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
$format,
|
||||||
|
$response->getProtocolVersion(),
|
||||||
|
$response->getStatusCode(),
|
||||||
|
($reasonPhrase ? ' ' . $reasonPhrase : ''),
|
||||||
|
$headers,
|
||||||
|
$body
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the status line for the message.
|
||||||
|
*
|
||||||
|
* @return array Array with three elements: 0 => version, 1 => status, 2 => reason
|
||||||
|
* @throws Exception\SerializationException if line is malformed
|
||||||
|
*/
|
||||||
|
private static function getStatusLine(StreamInterface $stream) : array
|
||||||
|
{
|
||||||
|
$line = self::getLine($stream);
|
||||||
|
|
||||||
|
if (! preg_match(
|
||||||
|
'#^HTTP/(?P<version>[1-9]\d*\.\d) (?P<status>[1-5]\d{2})(\s+(?P<reason>.+))?$#',
|
||||||
|
$line,
|
||||||
|
$matches
|
||||||
|
)) {
|
||||||
|
throw Exception\SerializationException::forInvalidStatusLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
return [$matches['version'], (int) $matches['status'], isset($matches['reason']) ? $matches['reason'] : ''];
|
||||||
|
}
|
||||||
|
}
|
74
vendor/laminas/laminas-diactoros/src/Response/TextResponse.php
vendored
Normal file
74
vendor/laminas/laminas-diactoros/src/Response/TextResponse.php
vendored
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Response;
|
||||||
|
|
||||||
|
use Laminas\Diactoros\Exception;
|
||||||
|
use Laminas\Diactoros\Response;
|
||||||
|
use Laminas\Diactoros\Stream;
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
|
||||||
|
use function get_class;
|
||||||
|
use function gettype;
|
||||||
|
use function is_object;
|
||||||
|
use function is_string;
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plain text response.
|
||||||
|
*
|
||||||
|
* Allows creating a response by passing a string to the constructor;
|
||||||
|
* by default, sets a status code of 200 and sets the Content-Type header to
|
||||||
|
* text/plain.
|
||||||
|
*/
|
||||||
|
class TextResponse extends Response
|
||||||
|
{
|
||||||
|
use InjectContentTypeTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a plain text response.
|
||||||
|
*
|
||||||
|
* Produces a text response with a Content-Type of text/plain and a default
|
||||||
|
* status of 200.
|
||||||
|
*
|
||||||
|
* @param string|StreamInterface $text String or stream for the message body.
|
||||||
|
* @param int $status Integer status code for the response; 200 by default.
|
||||||
|
* @param array $headers Array of headers to use at initialization.
|
||||||
|
* @throws Exception\InvalidArgumentException if $text is neither a string or stream.
|
||||||
|
*/
|
||||||
|
public function __construct($text, int $status = 200, array $headers = [])
|
||||||
|
{
|
||||||
|
parent::__construct(
|
||||||
|
$this->createBody($text),
|
||||||
|
$status,
|
||||||
|
$this->injectContentType('text/plain; charset=utf-8', $headers)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the message body.
|
||||||
|
*
|
||||||
|
* @param string|StreamInterface $text
|
||||||
|
* @throws Exception\InvalidArgumentException if $text is neither a string or stream.
|
||||||
|
*/
|
||||||
|
private function createBody($text) : StreamInterface
|
||||||
|
{
|
||||||
|
if ($text instanceof StreamInterface) {
|
||||||
|
return $text;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! is_string($text)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'Invalid content (%s) provided to %s',
|
||||||
|
(is_object($text) ? get_class($text) : gettype($text)),
|
||||||
|
__CLASS__
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$body = new Stream('php://temp', 'wb+');
|
||||||
|
$body->write($text);
|
||||||
|
$body->rewind();
|
||||||
|
return $body;
|
||||||
|
}
|
||||||
|
}
|
76
vendor/laminas/laminas-diactoros/src/Response/XmlResponse.php
vendored
Normal file
76
vendor/laminas/laminas-diactoros/src/Response/XmlResponse.php
vendored
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros\Response;
|
||||||
|
|
||||||
|
use Laminas\Diactoros\Exception;
|
||||||
|
use Laminas\Diactoros\Response;
|
||||||
|
use Laminas\Diactoros\Stream;
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
|
||||||
|
use function get_class;
|
||||||
|
use function gettype;
|
||||||
|
use function is_object;
|
||||||
|
use function is_string;
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML response.
|
||||||
|
*
|
||||||
|
* Allows creating a response by passing an XML string to the constructor; by default,
|
||||||
|
* sets a status code of 200 and sets the Content-Type header to application/xml.
|
||||||
|
*/
|
||||||
|
class XmlResponse extends Response
|
||||||
|
{
|
||||||
|
use InjectContentTypeTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an XML response.
|
||||||
|
*
|
||||||
|
* Produces an XML response with a Content-Type of application/xml and a default
|
||||||
|
* status of 200.
|
||||||
|
*
|
||||||
|
* @param string|StreamInterface $xml String or stream for the message body.
|
||||||
|
* @param int $status Integer status code for the response; 200 by default.
|
||||||
|
* @param array $headers Array of headers to use at initialization.
|
||||||
|
* @throws Exception\InvalidArgumentException if $text is neither a string or stream.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
$xml,
|
||||||
|
int $status = 200,
|
||||||
|
array $headers = []
|
||||||
|
) {
|
||||||
|
parent::__construct(
|
||||||
|
$this->createBody($xml),
|
||||||
|
$status,
|
||||||
|
$this->injectContentType('application/xml; charset=utf-8', $headers)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the message body.
|
||||||
|
*
|
||||||
|
* @param string|StreamInterface $xml
|
||||||
|
* @throws Exception\InvalidArgumentException if $xml is neither a string or stream.
|
||||||
|
*/
|
||||||
|
private function createBody($xml) : StreamInterface
|
||||||
|
{
|
||||||
|
if ($xml instanceof StreamInterface) {
|
||||||
|
return $xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! is_string($xml)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'Invalid content (%s) provided to %s',
|
||||||
|
(is_object($xml) ? get_class($xml) : gettype($xml)),
|
||||||
|
__CLASS__
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$body = new Stream('php://temp', 'wb+');
|
||||||
|
$body->write($xml);
|
||||||
|
$body->rewind();
|
||||||
|
return $body;
|
||||||
|
}
|
||||||
|
}
|
20
vendor/laminas/laminas-diactoros/src/ResponseFactory.php
vendored
Normal file
20
vendor/laminas/laminas-diactoros/src/ResponseFactory.php
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\ResponseFactoryInterface;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
||||||
|
class ResponseFactory implements ResponseFactoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function createResponse(int $code = 200, string $reasonPhrase = '') : ResponseInterface
|
||||||
|
{
|
||||||
|
return (new Response())
|
||||||
|
->withStatus($code, $reasonPhrase);
|
||||||
|
}
|
||||||
|
}
|
250
vendor/laminas/laminas-diactoros/src/ServerRequest.php
vendored
Normal file
250
vendor/laminas/laminas-diactoros/src/ServerRequest.php
vendored
Normal file
|
@ -0,0 +1,250 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
use Psr\Http\Message\UploadedFileInterface;
|
||||||
|
use Psr\Http\Message\UriInterface;
|
||||||
|
|
||||||
|
use function array_key_exists;
|
||||||
|
use function is_array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server-side HTTP request
|
||||||
|
*
|
||||||
|
* Extends the Request definition to add methods for accessing incoming data,
|
||||||
|
* specifically server parameters, cookies, matched path parameters, query
|
||||||
|
* string arguments, body parameters, and upload file information.
|
||||||
|
*
|
||||||
|
* "Attributes" are discovered via decomposing the request (and usually
|
||||||
|
* specifically the URI path), and typically will be injected by the application.
|
||||||
|
*
|
||||||
|
* Requests are considered immutable; all methods that might change state are
|
||||||
|
* implemented such that they retain the internal state of the current
|
||||||
|
* message and return a new instance that contains the changed state.
|
||||||
|
*/
|
||||||
|
class ServerRequest implements ServerRequestInterface
|
||||||
|
{
|
||||||
|
use RequestTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $attributes = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $cookieParams = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var null|array|object
|
||||||
|
*/
|
||||||
|
private $parsedBody;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $queryParams = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $serverParams;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $uploadedFiles;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $serverParams Server parameters, typically from $_SERVER
|
||||||
|
* @param array $uploadedFiles Upload file information, a tree of UploadedFiles
|
||||||
|
* @param null|string|UriInterface $uri URI for the request, if any.
|
||||||
|
* @param null|string $method HTTP method for the request, if any.
|
||||||
|
* @param string|resource|StreamInterface $body Message body, if any.
|
||||||
|
* @param array $headers Headers for the message, if any.
|
||||||
|
* @param array $cookies Cookies for the message, if any.
|
||||||
|
* @param array $queryParams Query params for the message, if any.
|
||||||
|
* @param null|array|object $parsedBody The deserialized body parameters, if any.
|
||||||
|
* @param string $protocol HTTP protocol version.
|
||||||
|
* @throws Exception\InvalidArgumentException for any invalid value.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
array $serverParams = [],
|
||||||
|
array $uploadedFiles = [],
|
||||||
|
$uri = null,
|
||||||
|
string $method = null,
|
||||||
|
$body = 'php://input',
|
||||||
|
array $headers = [],
|
||||||
|
array $cookies = [],
|
||||||
|
array $queryParams = [],
|
||||||
|
$parsedBody = null,
|
||||||
|
string $protocol = '1.1'
|
||||||
|
) {
|
||||||
|
$this->validateUploadedFiles($uploadedFiles);
|
||||||
|
|
||||||
|
if ($body === 'php://input') {
|
||||||
|
$body = new PhpInputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->initialize($uri, $method, $body, $headers);
|
||||||
|
$this->serverParams = $serverParams;
|
||||||
|
$this->uploadedFiles = $uploadedFiles;
|
||||||
|
$this->cookieParams = $cookies;
|
||||||
|
$this->queryParams = $queryParams;
|
||||||
|
$this->parsedBody = $parsedBody;
|
||||||
|
$this->protocol = $protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getServerParams() : array
|
||||||
|
{
|
||||||
|
return $this->serverParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getUploadedFiles() : array
|
||||||
|
{
|
||||||
|
return $this->uploadedFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function withUploadedFiles(array $uploadedFiles) : ServerRequest
|
||||||
|
{
|
||||||
|
$this->validateUploadedFiles($uploadedFiles);
|
||||||
|
$new = clone $this;
|
||||||
|
$new->uploadedFiles = $uploadedFiles;
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getCookieParams() : array
|
||||||
|
{
|
||||||
|
return $this->cookieParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function withCookieParams(array $cookies) : ServerRequest
|
||||||
|
{
|
||||||
|
$new = clone $this;
|
||||||
|
$new->cookieParams = $cookies;
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getQueryParams() : array
|
||||||
|
{
|
||||||
|
return $this->queryParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function withQueryParams(array $query) : ServerRequest
|
||||||
|
{
|
||||||
|
$new = clone $this;
|
||||||
|
$new->queryParams = $query;
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getParsedBody()
|
||||||
|
{
|
||||||
|
return $this->parsedBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function withParsedBody($data) : ServerRequest
|
||||||
|
{
|
||||||
|
if (! is_array($data) && ! is_object($data) && null !== $data) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'%s expects a null, array, or object argument; received %s',
|
||||||
|
__METHOD__,
|
||||||
|
gettype($data)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$new = clone $this;
|
||||||
|
$new->parsedBody = $data;
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getAttributes() : array
|
||||||
|
{
|
||||||
|
return $this->attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getAttribute($attribute, $default = null)
|
||||||
|
{
|
||||||
|
if (! array_key_exists($attribute, $this->attributes)) {
|
||||||
|
return $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->attributes[$attribute];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function withAttribute($attribute, $value) : ServerRequest
|
||||||
|
{
|
||||||
|
$new = clone $this;
|
||||||
|
$new->attributes[$attribute] = $value;
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function withoutAttribute($attribute) : ServerRequest
|
||||||
|
{
|
||||||
|
$new = clone $this;
|
||||||
|
unset($new->attributes[$attribute]);
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively validate the structure in an uploaded files array.
|
||||||
|
*
|
||||||
|
* @throws Exception\InvalidArgumentException if any leaf is not an UploadedFileInterface instance.
|
||||||
|
*/
|
||||||
|
private function validateUploadedFiles(array $uploadedFiles) : void
|
||||||
|
{
|
||||||
|
foreach ($uploadedFiles as $file) {
|
||||||
|
if (is_array($file)) {
|
||||||
|
$this->validateUploadedFiles($file);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $file instanceof UploadedFileInterface) {
|
||||||
|
throw new Exception\InvalidArgumentException('Invalid leaf in uploaded files structure');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
94
vendor/laminas/laminas-diactoros/src/ServerRequestFactory.php
vendored
Normal file
94
vendor/laminas/laminas-diactoros/src/ServerRequestFactory.php
vendored
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\ServerRequestFactoryInterface;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
|
use function array_key_exists;
|
||||||
|
use function is_callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for marshaling a request object from the current PHP environment.
|
||||||
|
*
|
||||||
|
* Logic largely refactored from the Laminas Laminas\Http\PhpEnvironment\Request class.
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2005-2015 Laminas (https://www.zend.com)
|
||||||
|
* @license https://getlaminas.org/license/new-bsd New BSD License
|
||||||
|
*/
|
||||||
|
class ServerRequestFactory implements ServerRequestFactoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Function to use to get apache request headers; present only to simplify mocking.
|
||||||
|
*
|
||||||
|
* @var callable
|
||||||
|
*/
|
||||||
|
private static $apacheRequestHeaders = 'apache_request_headers';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a request from the supplied superglobal values.
|
||||||
|
*
|
||||||
|
* If any argument is not supplied, the corresponding superglobal value will
|
||||||
|
* be used.
|
||||||
|
*
|
||||||
|
* The ServerRequest created is then passed to the fromServer() method in
|
||||||
|
* order to marshal the request URI and headers.
|
||||||
|
*
|
||||||
|
* @see fromServer()
|
||||||
|
* @param array $server $_SERVER superglobal
|
||||||
|
* @param array $query $_GET superglobal
|
||||||
|
* @param array $body $_POST superglobal
|
||||||
|
* @param array $cookies $_COOKIE superglobal
|
||||||
|
* @param array $files $_FILES superglobal
|
||||||
|
* @return ServerRequest
|
||||||
|
*/
|
||||||
|
public static function fromGlobals(
|
||||||
|
array $server = null,
|
||||||
|
array $query = null,
|
||||||
|
array $body = null,
|
||||||
|
array $cookies = null,
|
||||||
|
array $files = null
|
||||||
|
) : ServerRequest {
|
||||||
|
$server = normalizeServer(
|
||||||
|
$server ?: $_SERVER,
|
||||||
|
is_callable(self::$apacheRequestHeaders) ? self::$apacheRequestHeaders : null
|
||||||
|
);
|
||||||
|
$files = normalizeUploadedFiles($files ?: $_FILES);
|
||||||
|
$headers = marshalHeadersFromSapi($server);
|
||||||
|
|
||||||
|
if (null === $cookies && array_key_exists('cookie', $headers)) {
|
||||||
|
$cookies = parseCookieHeader($headers['cookie']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ServerRequest(
|
||||||
|
$server,
|
||||||
|
$files,
|
||||||
|
marshalUriFromSapi($server, $headers),
|
||||||
|
marshalMethodFromSapi($server),
|
||||||
|
'php://input',
|
||||||
|
$headers,
|
||||||
|
$cookies ?: $_COOKIE,
|
||||||
|
$query ?: $_GET,
|
||||||
|
$body ?: $_POST,
|
||||||
|
marshalProtocolVersionFromSapi($server)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function createServerRequest(string $method, $uri, array $serverParams = []) : ServerRequestInterface
|
||||||
|
{
|
||||||
|
$uploadedFiles = [];
|
||||||
|
|
||||||
|
return new ServerRequest(
|
||||||
|
$serverParams,
|
||||||
|
$uploadedFiles,
|
||||||
|
$uri,
|
||||||
|
$method,
|
||||||
|
'php://temp'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
377
vendor/laminas/laminas-diactoros/src/Stream.php
vendored
Normal file
377
vendor/laminas/laminas-diactoros/src/Stream.php
vendored
Normal file
|
@ -0,0 +1,377 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
use function array_key_exists;
|
||||||
|
use function fclose;
|
||||||
|
use function feof;
|
||||||
|
use function fopen;
|
||||||
|
use function fread;
|
||||||
|
use function fseek;
|
||||||
|
use function fstat;
|
||||||
|
use function ftell;
|
||||||
|
use function fwrite;
|
||||||
|
use function get_resource_type;
|
||||||
|
use function is_int;
|
||||||
|
use function is_resource;
|
||||||
|
use function is_string;
|
||||||
|
use function restore_error_handler;
|
||||||
|
use function set_error_handler;
|
||||||
|
use function stream_get_contents;
|
||||||
|
use function stream_get_meta_data;
|
||||||
|
use function strstr;
|
||||||
|
|
||||||
|
use const E_WARNING;
|
||||||
|
use const SEEK_SET;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of PSR HTTP streams
|
||||||
|
*/
|
||||||
|
class Stream implements StreamInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A list of allowed stream resource types that are allowed to instantiate a Stream
|
||||||
|
*/
|
||||||
|
private const ALLOWED_STREAM_RESOURCE_TYPES = ['gd', 'stream'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var resource|null
|
||||||
|
*/
|
||||||
|
protected $resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string|resource
|
||||||
|
*/
|
||||||
|
protected $stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|resource $stream
|
||||||
|
* @param string $mode Mode with which to open stream
|
||||||
|
* @throws Exception\InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function __construct($stream, string $mode = 'r')
|
||||||
|
{
|
||||||
|
$this->setStream($stream, $mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function __toString() : string
|
||||||
|
{
|
||||||
|
if (! $this->isReadable()) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($this->isSeekable()) {
|
||||||
|
$this->rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->getContents();
|
||||||
|
} catch (RuntimeException $e) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function close() : void
|
||||||
|
{
|
||||||
|
if (! $this->resource) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$resource = $this->detach();
|
||||||
|
fclose($resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function detach()
|
||||||
|
{
|
||||||
|
$resource = $this->resource;
|
||||||
|
$this->resource = null;
|
||||||
|
return $resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attach a new stream/resource to the instance.
|
||||||
|
*
|
||||||
|
* @param string|resource $resource
|
||||||
|
* @param string $mode
|
||||||
|
* @throws Exception\InvalidArgumentException for stream identifier that cannot be
|
||||||
|
* cast to a resource
|
||||||
|
* @throws Exception\InvalidArgumentException for non-resource stream
|
||||||
|
*/
|
||||||
|
public function attach($resource, string $mode = 'r') : void
|
||||||
|
{
|
||||||
|
$this->setStream($resource, $mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getSize() : ?int
|
||||||
|
{
|
||||||
|
if (null === $this->resource) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stats = fstat($this->resource);
|
||||||
|
if ($stats !== false) {
|
||||||
|
return $stats['size'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function tell() : int
|
||||||
|
{
|
||||||
|
if (! $this->resource) {
|
||||||
|
throw Exception\UntellableStreamException::dueToMissingResource();
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = ftell($this->resource);
|
||||||
|
if (! is_int($result)) {
|
||||||
|
throw Exception\UntellableStreamException::dueToPhpError();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function eof() : bool
|
||||||
|
{
|
||||||
|
if (! $this->resource) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return feof($this->resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function isSeekable() : bool
|
||||||
|
{
|
||||||
|
if (! $this->resource) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$meta = stream_get_meta_data($this->resource);
|
||||||
|
return $meta['seekable'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function seek($offset, $whence = SEEK_SET) : void
|
||||||
|
{
|
||||||
|
if (! $this->resource) {
|
||||||
|
throw Exception\UnseekableStreamException::dueToMissingResource();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $this->isSeekable()) {
|
||||||
|
throw Exception\UnseekableStreamException::dueToConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = fseek($this->resource, $offset, $whence);
|
||||||
|
|
||||||
|
if (0 !== $result) {
|
||||||
|
throw Exception\UnseekableStreamException::dueToPhpError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function rewind() : void
|
||||||
|
{
|
||||||
|
$this->seek(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function isWritable() : bool
|
||||||
|
{
|
||||||
|
if (! $this->resource) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$meta = stream_get_meta_data($this->resource);
|
||||||
|
$mode = $meta['mode'];
|
||||||
|
|
||||||
|
return (
|
||||||
|
strstr($mode, 'x')
|
||||||
|
|| strstr($mode, 'w')
|
||||||
|
|| strstr($mode, 'c')
|
||||||
|
|| strstr($mode, 'a')
|
||||||
|
|| strstr($mode, '+')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function write($string) : int
|
||||||
|
{
|
||||||
|
if (! $this->resource) {
|
||||||
|
throw Exception\UnwritableStreamException::dueToMissingResource();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $this->isWritable()) {
|
||||||
|
throw Exception\UnwritableStreamException::dueToConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = fwrite($this->resource, $string);
|
||||||
|
|
||||||
|
if (false === $result) {
|
||||||
|
throw Exception\UnwritableStreamException::dueToPhpError();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function isReadable() : bool
|
||||||
|
{
|
||||||
|
if (! $this->resource) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$meta = stream_get_meta_data($this->resource);
|
||||||
|
$mode = $meta['mode'];
|
||||||
|
|
||||||
|
return (strstr($mode, 'r') || strstr($mode, '+'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function read($length) : string
|
||||||
|
{
|
||||||
|
if (! $this->resource) {
|
||||||
|
throw Exception\UnreadableStreamException::dueToMissingResource();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $this->isReadable()) {
|
||||||
|
throw Exception\UnreadableStreamException::dueToConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = fread($this->resource, $length);
|
||||||
|
|
||||||
|
if (false === $result) {
|
||||||
|
throw Exception\UnreadableStreamException::dueToPhpError();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getContents() : string
|
||||||
|
{
|
||||||
|
if (! $this->isReadable()) {
|
||||||
|
throw Exception\UnreadableStreamException::dueToConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = stream_get_contents($this->resource);
|
||||||
|
if (false === $result) {
|
||||||
|
throw Exception\UnreadableStreamException::dueToPhpError();
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getMetadata($key = null)
|
||||||
|
{
|
||||||
|
if (null === $key) {
|
||||||
|
return stream_get_meta_data($this->resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
$metadata = stream_get_meta_data($this->resource);
|
||||||
|
if (! array_key_exists($key, $metadata)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $metadata[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the internal stream resource.
|
||||||
|
*
|
||||||
|
* @param string|resource $stream String stream target or stream resource.
|
||||||
|
* @param string $mode Resource mode for stream target.
|
||||||
|
* @throws Exception\InvalidArgumentException for invalid streams or resources.
|
||||||
|
*/
|
||||||
|
private function setStream($stream, string $mode = 'r') : void
|
||||||
|
{
|
||||||
|
$error = null;
|
||||||
|
$resource = $stream;
|
||||||
|
|
||||||
|
if (is_string($stream)) {
|
||||||
|
set_error_handler(function ($e) use (&$error) {
|
||||||
|
if ($e !== E_WARNING) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$error = $e;
|
||||||
|
});
|
||||||
|
$resource = fopen($stream, $mode);
|
||||||
|
restore_error_handler();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($error) {
|
||||||
|
throw new Exception\RuntimeException('Invalid stream reference provided');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $this->isValidStreamResourceType($resource)) {
|
||||||
|
throw new Exception\InvalidArgumentException(
|
||||||
|
'Invalid stream provided; must be a string stream identifier or stream resource'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($stream !== $resource) {
|
||||||
|
$this->stream = $stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->resource = $resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if a resource is one of the resource types allowed to instantiate a Stream
|
||||||
|
*
|
||||||
|
* @param resource $resource Stream resource.
|
||||||
|
*/
|
||||||
|
private function isValidStreamResourceType($resource): bool
|
||||||
|
{
|
||||||
|
if (is_resource($resource)) {
|
||||||
|
return in_array(get_resource_type($resource), self::ALLOWED_STREAM_RESOURCE_TYPES, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PHP_VERSION_ID >= 80000 && $resource instanceof \GdImage) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
45
vendor/laminas/laminas-diactoros/src/StreamFactory.php
vendored
Normal file
45
vendor/laminas/laminas-diactoros/src/StreamFactory.php
vendored
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\StreamFactoryInterface;
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
|
||||||
|
use function fopen;
|
||||||
|
use function fwrite;
|
||||||
|
use function get_resource_type;
|
||||||
|
use function is_resource;
|
||||||
|
use function rewind;
|
||||||
|
|
||||||
|
class StreamFactory implements StreamFactoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function createStream(string $content = '') : StreamInterface
|
||||||
|
{
|
||||||
|
$resource = fopen('php://temp', 'r+');
|
||||||
|
fwrite($resource, $content);
|
||||||
|
rewind($resource);
|
||||||
|
|
||||||
|
return $this->createStreamFromResource($resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function createStreamFromFile(string $file, string $mode = 'r') : StreamInterface
|
||||||
|
{
|
||||||
|
return new Stream($file, $mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function createStreamFromResource($resource) : StreamInterface
|
||||||
|
{
|
||||||
|
return new Stream($resource);
|
||||||
|
}
|
||||||
|
}
|
262
vendor/laminas/laminas-diactoros/src/UploadedFile.php
vendored
Normal file
262
vendor/laminas/laminas-diactoros/src/UploadedFile.php
vendored
Normal file
|
@ -0,0 +1,262 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
use Psr\Http\Message\UploadedFileInterface;
|
||||||
|
|
||||||
|
use function dirname;
|
||||||
|
use function fclose;
|
||||||
|
use function fopen;
|
||||||
|
use function fwrite;
|
||||||
|
use function is_dir;
|
||||||
|
use function is_int;
|
||||||
|
use function is_resource;
|
||||||
|
use function is_string;
|
||||||
|
use function is_writable;
|
||||||
|
use function move_uploaded_file;
|
||||||
|
use function sprintf;
|
||||||
|
use function strpos;
|
||||||
|
|
||||||
|
use const PHP_SAPI;
|
||||||
|
use const UPLOAD_ERR_CANT_WRITE;
|
||||||
|
use const UPLOAD_ERR_EXTENSION;
|
||||||
|
use const UPLOAD_ERR_FORM_SIZE;
|
||||||
|
use const UPLOAD_ERR_INI_SIZE;
|
||||||
|
use const UPLOAD_ERR_NO_FILE;
|
||||||
|
use const UPLOAD_ERR_NO_TMP_DIR;
|
||||||
|
use const UPLOAD_ERR_OK;
|
||||||
|
use const UPLOAD_ERR_PARTIAL;
|
||||||
|
|
||||||
|
class UploadedFile implements UploadedFileInterface
|
||||||
|
{
|
||||||
|
const ERROR_MESSAGES = [
|
||||||
|
UPLOAD_ERR_OK => 'There is no error, the file uploaded with success',
|
||||||
|
UPLOAD_ERR_INI_SIZE => 'The uploaded file exceeds the upload_max_filesize directive in php.ini',
|
||||||
|
UPLOAD_ERR_FORM_SIZE => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was '
|
||||||
|
. 'specified in the HTML form',
|
||||||
|
UPLOAD_ERR_PARTIAL => 'The uploaded file was only partially uploaded',
|
||||||
|
UPLOAD_ERR_NO_FILE => 'No file was uploaded',
|
||||||
|
UPLOAD_ERR_NO_TMP_DIR => 'Missing a temporary folder',
|
||||||
|
UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk',
|
||||||
|
UPLOAD_ERR_EXTENSION => 'A PHP extension stopped the file upload.',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string|null
|
||||||
|
*/
|
||||||
|
private $clientFilename;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string|null
|
||||||
|
*/
|
||||||
|
private $clientMediaType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var null|string
|
||||||
|
*/
|
||||||
|
private $file;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $moved = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var null|StreamInterface
|
||||||
|
*/
|
||||||
|
private $stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|resource|StreamInterface $streamOrFile
|
||||||
|
* @param int $size
|
||||||
|
* @param int $errorStatus
|
||||||
|
* @param string|null $clientFilename
|
||||||
|
* @param string|null $clientMediaType
|
||||||
|
* @throws Exception\InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
$streamOrFile,
|
||||||
|
int $size,
|
||||||
|
int $errorStatus,
|
||||||
|
string $clientFilename = null,
|
||||||
|
string $clientMediaType = null
|
||||||
|
) {
|
||||||
|
if ($errorStatus === UPLOAD_ERR_OK) {
|
||||||
|
if (is_string($streamOrFile)) {
|
||||||
|
$this->file = $streamOrFile;
|
||||||
|
}
|
||||||
|
if (is_resource($streamOrFile)) {
|
||||||
|
$this->stream = new Stream($streamOrFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $this->file && ! $this->stream) {
|
||||||
|
if (! $streamOrFile instanceof StreamInterface) {
|
||||||
|
throw new Exception\InvalidArgumentException('Invalid stream or file provided for UploadedFile');
|
||||||
|
}
|
||||||
|
$this->stream = $streamOrFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->size = $size;
|
||||||
|
|
||||||
|
if (0 > $errorStatus || 8 < $errorStatus) {
|
||||||
|
throw new Exception\InvalidArgumentException(
|
||||||
|
'Invalid error status for UploadedFile; must be an UPLOAD_ERR_* constant'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$this->error = $errorStatus;
|
||||||
|
|
||||||
|
$this->clientFilename = $clientFilename;
|
||||||
|
$this->clientMediaType = $clientMediaType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
* @throws Exception\UploadedFileAlreadyMovedException if the upload was
|
||||||
|
* not successful.
|
||||||
|
*/
|
||||||
|
public function getStream() : StreamInterface
|
||||||
|
{
|
||||||
|
if ($this->error !== UPLOAD_ERR_OK) {
|
||||||
|
throw Exception\UploadedFileErrorException::dueToStreamUploadError(
|
||||||
|
self::ERROR_MESSAGES[$this->error]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->moved) {
|
||||||
|
throw new Exception\UploadedFileAlreadyMovedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->stream instanceof StreamInterface) {
|
||||||
|
return $this->stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->stream = new Stream($this->file);
|
||||||
|
return $this->stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @see http://php.net/is_uploaded_file
|
||||||
|
* @see http://php.net/move_uploaded_file
|
||||||
|
* @param string $targetPath Path to which to move the uploaded file.
|
||||||
|
* @throws Exception\UploadedFileErrorException if the upload was not successful.
|
||||||
|
* @throws Exception\InvalidArgumentException if the $path specified is invalid.
|
||||||
|
* @throws Exception\UploadedFileErrorException on any error during the
|
||||||
|
* move operation, or on the second or subsequent call to the method.
|
||||||
|
*/
|
||||||
|
public function moveTo($targetPath) : void
|
||||||
|
{
|
||||||
|
if ($this->moved) {
|
||||||
|
throw new Exception\UploadedFileAlreadyMovedException('Cannot move file; already moved!');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->error !== UPLOAD_ERR_OK) {
|
||||||
|
throw Exception\UploadedFileErrorException::dueToStreamUploadError(
|
||||||
|
self::ERROR_MESSAGES[$this->error]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! is_string($targetPath) || empty($targetPath)) {
|
||||||
|
throw new Exception\InvalidArgumentException(
|
||||||
|
'Invalid path provided for move operation; must be a non-empty string'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$targetDirectory = dirname($targetPath);
|
||||||
|
if (! is_dir($targetDirectory) || ! is_writable($targetDirectory)) {
|
||||||
|
throw Exception\UploadedFileErrorException::dueToUnwritableTarget($targetDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sapi = PHP_SAPI;
|
||||||
|
switch (true) {
|
||||||
|
case (empty($sapi) || 0 === strpos($sapi, 'cli') || 0 === strpos($sapi, 'phpdbg') || ! $this->file):
|
||||||
|
// Non-SAPI environment, or no filename present
|
||||||
|
$this->writeFile($targetPath);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// SAPI environment, with file present
|
||||||
|
if (false === move_uploaded_file($this->file, $targetPath)) {
|
||||||
|
throw Exception\UploadedFileErrorException::forUnmovableFile();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->moved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @return int|null The file size in bytes or null if unknown.
|
||||||
|
*/
|
||||||
|
public function getSize() : ?int
|
||||||
|
{
|
||||||
|
return $this->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @see http://php.net/manual/en/features.file-upload.errors.php
|
||||||
|
* @return int One of PHP's UPLOAD_ERR_XXX constants.
|
||||||
|
*/
|
||||||
|
public function getError() : int
|
||||||
|
{
|
||||||
|
return $this->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @return string|null The filename sent by the client or null if none
|
||||||
|
* was provided.
|
||||||
|
*/
|
||||||
|
public function getClientFilename() : ?string
|
||||||
|
{
|
||||||
|
return $this->clientFilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getClientMediaType() : ?string
|
||||||
|
{
|
||||||
|
return $this->clientMediaType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write internal stream to given path
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
*/
|
||||||
|
private function writeFile(string $path) : void
|
||||||
|
{
|
||||||
|
$handle = fopen($path, 'wb+');
|
||||||
|
if (false === $handle) {
|
||||||
|
throw Exception\UploadedFileErrorException::dueToUnwritablePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
$stream = $this->getStream();
|
||||||
|
$stream->rewind();
|
||||||
|
while (! $stream->eof()) {
|
||||||
|
fwrite($handle, $stream->read(4096));
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose($handle);
|
||||||
|
}
|
||||||
|
}
|
31
vendor/laminas/laminas-diactoros/src/UploadedFileFactory.php
vendored
Normal file
31
vendor/laminas/laminas-diactoros/src/UploadedFileFactory.php
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
use Psr\Http\Message\UploadedFileFactoryInterface;
|
||||||
|
use Psr\Http\Message\UploadedFileInterface;
|
||||||
|
|
||||||
|
use const UPLOAD_ERR_OK;
|
||||||
|
|
||||||
|
class UploadedFileFactory implements UploadedFileFactoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function createUploadedFile(
|
||||||
|
StreamInterface $stream,
|
||||||
|
int $size = null,
|
||||||
|
int $error = UPLOAD_ERR_OK,
|
||||||
|
string $clientFilename = null,
|
||||||
|
string $clientMediaType = null
|
||||||
|
) : UploadedFileInterface {
|
||||||
|
if ($size === null) {
|
||||||
|
$size = $stream->getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UploadedFile($stream, $size, $error, $clientFilename, $clientMediaType);
|
||||||
|
}
|
||||||
|
}
|
692
vendor/laminas/laminas-diactoros/src/Uri.php
vendored
Normal file
692
vendor/laminas/laminas-diactoros/src/Uri.php
vendored
Normal file
|
@ -0,0 +1,692 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\UriInterface;
|
||||||
|
|
||||||
|
use function array_keys;
|
||||||
|
use function explode;
|
||||||
|
use function get_class;
|
||||||
|
use function gettype;
|
||||||
|
use function implode;
|
||||||
|
use function is_numeric;
|
||||||
|
use function is_object;
|
||||||
|
use function is_string;
|
||||||
|
use function ltrim;
|
||||||
|
use function parse_url;
|
||||||
|
use function preg_match;
|
||||||
|
use function preg_replace;
|
||||||
|
use function preg_replace_callback;
|
||||||
|
use function rawurlencode;
|
||||||
|
use function sprintf;
|
||||||
|
use function str_split;
|
||||||
|
use function strpos;
|
||||||
|
use function strtolower;
|
||||||
|
use function substr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of Psr\Http\UriInterface.
|
||||||
|
*
|
||||||
|
* Provides a value object representing a URI for HTTP requests.
|
||||||
|
*
|
||||||
|
* Instances of this class are considered immutable; all methods that
|
||||||
|
* might change state are implemented such that they retain the internal
|
||||||
|
* state of the current instance and return a new instance that contains the
|
||||||
|
* changed state.
|
||||||
|
*/
|
||||||
|
class Uri implements UriInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Sub-delimiters used in user info, query strings and fragments.
|
||||||
|
*
|
||||||
|
* @const string
|
||||||
|
*/
|
||||||
|
const CHAR_SUB_DELIMS = '!\$&\'\(\)\*\+,;=';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unreserved characters used in user info, paths, query strings, and fragments.
|
||||||
|
*
|
||||||
|
* @const string
|
||||||
|
*/
|
||||||
|
const CHAR_UNRESERVED = 'a-zA-Z0-9_\-\.~\pL';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int[] Array indexed by valid scheme names to their corresponding ports.
|
||||||
|
*/
|
||||||
|
protected $allowedSchemes = [
|
||||||
|
'http' => 80,
|
||||||
|
'https' => 443,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $scheme = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $userInfo = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $host = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int|null
|
||||||
|
*/
|
||||||
|
private $port;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $path = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $query = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $fragment = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generated uri string cache
|
||||||
|
* @var string|null
|
||||||
|
*/
|
||||||
|
private $uriString;
|
||||||
|
|
||||||
|
public function __construct(string $uri = '')
|
||||||
|
{
|
||||||
|
if ('' === $uri) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->parseUri($uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operations to perform on clone.
|
||||||
|
*
|
||||||
|
* Since cloning usually is for purposes of mutation, we reset the
|
||||||
|
* $uriString property so it will be re-calculated.
|
||||||
|
*/
|
||||||
|
public function __clone()
|
||||||
|
{
|
||||||
|
$this->uriString = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function __toString() : string
|
||||||
|
{
|
||||||
|
if (null !== $this->uriString) {
|
||||||
|
return $this->uriString;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->uriString = static::createUriString(
|
||||||
|
$this->scheme,
|
||||||
|
$this->getAuthority(),
|
||||||
|
$this->getPath(), // Absolute URIs should use a "/" for an empty path
|
||||||
|
$this->query,
|
||||||
|
$this->fragment
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->uriString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getScheme() : string
|
||||||
|
{
|
||||||
|
return $this->scheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getAuthority() : string
|
||||||
|
{
|
||||||
|
if ('' === $this->host) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$authority = $this->host;
|
||||||
|
if ('' !== $this->userInfo) {
|
||||||
|
$authority = $this->userInfo . '@' . $authority;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->isNonStandardPort($this->scheme, $this->host, $this->port)) {
|
||||||
|
$authority .= ':' . $this->port;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $authority;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the user-info part of the URI.
|
||||||
|
*
|
||||||
|
* This value is percent-encoded, per RFC 3986 Section 3.2.1.
|
||||||
|
*
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getUserInfo() : string
|
||||||
|
{
|
||||||
|
return $this->userInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getHost() : string
|
||||||
|
{
|
||||||
|
return $this->host;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getPort() : ?int
|
||||||
|
{
|
||||||
|
return $this->isNonStandardPort($this->scheme, $this->host, $this->port)
|
||||||
|
? $this->port
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getPath() : string
|
||||||
|
{
|
||||||
|
return $this->path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getQuery() : string
|
||||||
|
{
|
||||||
|
return $this->query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getFragment() : string
|
||||||
|
{
|
||||||
|
return $this->fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function withScheme($scheme) : UriInterface
|
||||||
|
{
|
||||||
|
if (! is_string($scheme)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'%s expects a string argument; received %s',
|
||||||
|
__METHOD__,
|
||||||
|
is_object($scheme) ? get_class($scheme) : gettype($scheme)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$scheme = $this->filterScheme($scheme);
|
||||||
|
|
||||||
|
if ($scheme === $this->scheme) {
|
||||||
|
// Do nothing if no change was made.
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$new = clone $this;
|
||||||
|
$new->scheme = $scheme;
|
||||||
|
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and return a new instance containing the provided user credentials.
|
||||||
|
*
|
||||||
|
* The value will be percent-encoded in the new instance, but with measures
|
||||||
|
* taken to prevent double-encoding.
|
||||||
|
*
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function withUserInfo($user, $password = null) : UriInterface
|
||||||
|
{
|
||||||
|
if (! is_string($user)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'%s expects a string user argument; received %s',
|
||||||
|
__METHOD__,
|
||||||
|
is_object($user) ? get_class($user) : gettype($user)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if (null !== $password && ! is_string($password)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'%s expects a string or null password argument; received %s',
|
||||||
|
__METHOD__,
|
||||||
|
is_object($password) ? get_class($password) : gettype($password)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$info = $this->filterUserInfoPart($user);
|
||||||
|
if (null !== $password) {
|
||||||
|
$info .= ':' . $this->filterUserInfoPart($password);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($info === $this->userInfo) {
|
||||||
|
// Do nothing if no change was made.
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$new = clone $this;
|
||||||
|
$new->userInfo = $info;
|
||||||
|
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function withHost($host) : UriInterface
|
||||||
|
{
|
||||||
|
if (! is_string($host)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'%s expects a string argument; received %s',
|
||||||
|
__METHOD__,
|
||||||
|
is_object($host) ? get_class($host) : gettype($host)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($host === $this->host) {
|
||||||
|
// Do nothing if no change was made.
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$new = clone $this;
|
||||||
|
$new->host = strtolower($host);
|
||||||
|
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function withPort($port) : UriInterface
|
||||||
|
{
|
||||||
|
if ($port !== null) {
|
||||||
|
if (! is_numeric($port) || is_float($port)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'Invalid port "%s" specified; must be an integer, an integer string, or null',
|
||||||
|
is_object($port) ? get_class($port) : gettype($port)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$port = (int) $port;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($port === $this->port) {
|
||||||
|
// Do nothing if no change was made.
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($port !== null && ($port < 1 || $port > 65535)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'Invalid port "%d" specified; must be a valid TCP/UDP port',
|
||||||
|
$port
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$new = clone $this;
|
||||||
|
$new->port = $port;
|
||||||
|
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function withPath($path) : UriInterface
|
||||||
|
{
|
||||||
|
if (! is_string($path)) {
|
||||||
|
throw new Exception\InvalidArgumentException(
|
||||||
|
'Invalid path provided; must be a string'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strpos($path, '?') !== false) {
|
||||||
|
throw new Exception\InvalidArgumentException(
|
||||||
|
'Invalid path provided; must not contain a query string'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strpos($path, '#') !== false) {
|
||||||
|
throw new Exception\InvalidArgumentException(
|
||||||
|
'Invalid path provided; must not contain a URI fragment'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$path = $this->filterPath($path);
|
||||||
|
|
||||||
|
if ($path === $this->path) {
|
||||||
|
// Do nothing if no change was made.
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$new = clone $this;
|
||||||
|
$new->path = $path;
|
||||||
|
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function withQuery($query) : UriInterface
|
||||||
|
{
|
||||||
|
if (! is_string($query)) {
|
||||||
|
throw new Exception\InvalidArgumentException(
|
||||||
|
'Query string must be a string'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strpos($query, '#') !== false) {
|
||||||
|
throw new Exception\InvalidArgumentException(
|
||||||
|
'Query string must not include a URI fragment'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = $this->filterQuery($query);
|
||||||
|
|
||||||
|
if ($query === $this->query) {
|
||||||
|
// Do nothing if no change was made.
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$new = clone $this;
|
||||||
|
$new->query = $query;
|
||||||
|
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function withFragment($fragment) : UriInterface
|
||||||
|
{
|
||||||
|
if (! is_string($fragment)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'%s expects a string argument; received %s',
|
||||||
|
__METHOD__,
|
||||||
|
is_object($fragment) ? get_class($fragment) : gettype($fragment)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$fragment = $this->filterFragment($fragment);
|
||||||
|
|
||||||
|
if ($fragment === $this->fragment) {
|
||||||
|
// Do nothing if no change was made.
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$new = clone $this;
|
||||||
|
$new->fragment = $fragment;
|
||||||
|
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a URI into its parts, and set the properties
|
||||||
|
*/
|
||||||
|
private function parseUri(string $uri) : void
|
||||||
|
{
|
||||||
|
$parts = parse_url($uri);
|
||||||
|
|
||||||
|
if (false === $parts) {
|
||||||
|
throw new Exception\InvalidArgumentException(
|
||||||
|
'The source URI string appears to be malformed'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->scheme = isset($parts['scheme']) ? $this->filterScheme($parts['scheme']) : '';
|
||||||
|
$this->userInfo = isset($parts['user']) ? $this->filterUserInfoPart($parts['user']) : '';
|
||||||
|
$this->host = isset($parts['host']) ? strtolower($parts['host']) : '';
|
||||||
|
$this->port = isset($parts['port']) ? $parts['port'] : null;
|
||||||
|
$this->path = isset($parts['path']) ? $this->filterPath($parts['path']) : '';
|
||||||
|
$this->query = isset($parts['query']) ? $this->filterQuery($parts['query']) : '';
|
||||||
|
$this->fragment = isset($parts['fragment']) ? $this->filterFragment($parts['fragment']) : '';
|
||||||
|
|
||||||
|
if (isset($parts['pass'])) {
|
||||||
|
$this->userInfo .= ':' . $parts['pass'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 .= sprintf('%s:', $scheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('' !== $authority) {
|
||||||
|
$uri .= '//' . $authority;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('' !== $path && '/' !== substr($path, 0, 1)) {
|
||||||
|
$path = '/' . $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
$uri .= $path;
|
||||||
|
|
||||||
|
|
||||||
|
if ('' !== $query) {
|
||||||
|
$uri .= sprintf('?%s', $query);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('' !== $fragment) {
|
||||||
|
$uri .= sprintf('#%s', $fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is a given port non-standard for the current scheme?
|
||||||
|
*/
|
||||||
|
private function isNonStandardPort(string $scheme, string $host, ?int $port) : bool
|
||||||
|
{
|
||||||
|
if ('' === $scheme) {
|
||||||
|
return '' === $host || null !== $port;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('' === $host || null === $port) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ! isset($this->allowedSchemes[$scheme]) || $port !== $this->allowedSchemes[$scheme];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the scheme to ensure it is a valid scheme.
|
||||||
|
*
|
||||||
|
* @param string $scheme Scheme name.
|
||||||
|
* @return string Filtered scheme.
|
||||||
|
*/
|
||||||
|
private function filterScheme(string $scheme) : string
|
||||||
|
{
|
||||||
|
$scheme = strtolower($scheme);
|
||||||
|
$scheme = preg_replace('#:(//)?$#', '', $scheme);
|
||||||
|
|
||||||
|
if ('' === $scheme) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! isset($this->allowedSchemes[$scheme])) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'Unsupported scheme "%s"; must be any empty string or in the set (%s)',
|
||||||
|
$scheme,
|
||||||
|
implode(', ', array_keys($this->allowedSchemes))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $scheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters a part of user info in a URI to ensure it is properly encoded.
|
||||||
|
*
|
||||||
|
* @param string $part
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function filterUserInfoPart(string $part) : string
|
||||||
|
{
|
||||||
|
$part = $this->filterInvalidUtf8($part);
|
||||||
|
|
||||||
|
// Note the addition of `%` to initial charset; this allows `|` portion
|
||||||
|
// to match and thus prevent double-encoding.
|
||||||
|
return preg_replace_callback(
|
||||||
|
'/(?:[^%' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . ']+|%(?![A-Fa-f0-9]{2}))/u',
|
||||||
|
[$this, 'urlEncodeChar'],
|
||||||
|
$part
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the path of a URI to ensure it is properly encoded.
|
||||||
|
*/
|
||||||
|
private function filterPath(string $path) : string
|
||||||
|
{
|
||||||
|
$path = $this->filterInvalidUtf8($path);
|
||||||
|
|
||||||
|
$path = preg_replace_callback(
|
||||||
|
'/(?:[^' . self::CHAR_UNRESERVED . ')(:@&=\+\$,\/;%]+|%(?![A-Fa-f0-9]{2}))/u',
|
||||||
|
[$this, 'urlEncodeChar'],
|
||||||
|
$path
|
||||||
|
);
|
||||||
|
|
||||||
|
if ('' === $path) {
|
||||||
|
// No path
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($path[0] !== '/') {
|
||||||
|
// Relative path
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure only one leading slash, to prevent XSS attempts.
|
||||||
|
return '/' . ltrim($path, '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode invalid UTF-8 characters in given string. All other characters are unchanged.
|
||||||
|
*/
|
||||||
|
private function filterInvalidUtf8(string $string) : string
|
||||||
|
{
|
||||||
|
// check if given string contains only valid UTF-8 characters
|
||||||
|
if (preg_match('//u', $string)) {
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
$letters = str_split($string);
|
||||||
|
foreach ($letters as $i => $letter) {
|
||||||
|
if (! preg_match('//u', $letter)) {
|
||||||
|
$letters[$i] = $this->urlEncodeChar([$letter]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode('', $letters);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter a query string to ensure it is propertly encoded.
|
||||||
|
*
|
||||||
|
* Ensures that the values in the query string are properly urlencoded.
|
||||||
|
*/
|
||||||
|
private function filterQuery(string $query) : string
|
||||||
|
{
|
||||||
|
if ('' !== $query && strpos($query, '?') === 0) {
|
||||||
|
$query = substr($query, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
$parts = explode('&', $query);
|
||||||
|
foreach ($parts as $index => $part) {
|
||||||
|
[$key, $value] = $this->splitQueryValue($part);
|
||||||
|
if ($value === null) {
|
||||||
|
$parts[$index] = $this->filterQueryOrFragment($key);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$parts[$index] = sprintf(
|
||||||
|
'%s=%s',
|
||||||
|
$this->filterQueryOrFragment($key),
|
||||||
|
$this->filterQueryOrFragment($value)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode('&', $parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Split a query value into a key/value tuple.
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
* @return array A value with exactly two elements, key and value
|
||||||
|
*/
|
||||||
|
private function splitQueryValue(string $value) : array
|
||||||
|
{
|
||||||
|
$data = explode('=', $value, 2);
|
||||||
|
if (! isset($data[1])) {
|
||||||
|
$data[] = null;
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter a fragment value to ensure it is properly encoded.
|
||||||
|
*/
|
||||||
|
private function filterFragment(string $fragment) : string
|
||||||
|
{
|
||||||
|
if ('' !== $fragment && strpos($fragment, '#') === 0) {
|
||||||
|
$fragment = '%23' . substr($fragment, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->filterQueryOrFragment($fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter a query string key or value, or a fragment.
|
||||||
|
*/
|
||||||
|
private function filterQueryOrFragment(string $value) : string
|
||||||
|
{
|
||||||
|
$value = $this->filterInvalidUtf8($value);
|
||||||
|
|
||||||
|
return preg_replace_callback(
|
||||||
|
'/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\/\?]+|%(?![A-Fa-f0-9]{2}))/u',
|
||||||
|
[$this, 'urlEncodeChar'],
|
||||||
|
$value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URL encode a character returned by a regex.
|
||||||
|
*/
|
||||||
|
private function urlEncodeChar(array $matches) : string
|
||||||
|
{
|
||||||
|
return rawurlencode($matches[0]);
|
||||||
|
}
|
||||||
|
}
|
19
vendor/laminas/laminas-diactoros/src/UriFactory.php
vendored
Normal file
19
vendor/laminas/laminas-diactoros/src/UriFactory.php
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\UriFactoryInterface;
|
||||||
|
use Psr\Http\Message\UriInterface;
|
||||||
|
|
||||||
|
class UriFactory implements UriFactoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function createUri(string $uri = '') : UriInterface
|
||||||
|
{
|
||||||
|
return new Uri($uri);
|
||||||
|
}
|
||||||
|
}
|
15
vendor/laminas/laminas-diactoros/src/functions/create_uploaded_file.legacy.php
vendored
Normal file
15
vendor/laminas/laminas-diactoros/src/functions/create_uploaded_file.legacy.php
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Zend\Diactoros;
|
||||||
|
|
||||||
|
use function Laminas\Diactoros\createUploadedFile as laminas_createUploadedFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use Laminas\Diactoros\createUploadedFile instead
|
||||||
|
*/
|
||||||
|
function createUploadedFile(array $spec) : UploadedFile
|
||||||
|
{
|
||||||
|
return laminas_createUploadedFile(...func_get_args());
|
||||||
|
}
|
34
vendor/laminas/laminas-diactoros/src/functions/create_uploaded_file.php
vendored
Normal file
34
vendor/laminas/laminas-diactoros/src/functions/create_uploaded_file.php
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an uploaded file instance from an array of values.
|
||||||
|
*
|
||||||
|
* @param array $spec A single $_FILES entry.
|
||||||
|
* @throws Exception\InvalidArgumentException if one or more of the tmp_name,
|
||||||
|
* size, or error keys are missing from $spec.
|
||||||
|
*/
|
||||||
|
function createUploadedFile(array $spec) : UploadedFile
|
||||||
|
{
|
||||||
|
if (! isset($spec['tmp_name'])
|
||||||
|
|| ! isset($spec['size'])
|
||||||
|
|| ! isset($spec['error'])
|
||||||
|
) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'$spec provided to %s MUST contain each of the keys "tmp_name",'
|
||||||
|
. ' "size", and "error"; one or more were missing',
|
||||||
|
__FUNCTION__
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UploadedFile(
|
||||||
|
$spec['tmp_name'],
|
||||||
|
(int) $spec['size'],
|
||||||
|
$spec['error'],
|
||||||
|
$spec['name'] ?? null,
|
||||||
|
$spec['type'] ?? null
|
||||||
|
);
|
||||||
|
}
|
15
vendor/laminas/laminas-diactoros/src/functions/marshal_headers_from_sapi.legacy.php
vendored
Normal file
15
vendor/laminas/laminas-diactoros/src/functions/marshal_headers_from_sapi.legacy.php
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Zend\Diactoros;
|
||||||
|
|
||||||
|
use function Laminas\Diactoros\marshalHeadersFromSapi as laminas_marshalHeadersFromSapi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use Laminas\Diactoros\marshalHeadersFromSapi instead
|
||||||
|
*/
|
||||||
|
function marshalHeadersFromSapi(array $server) : array
|
||||||
|
{
|
||||||
|
return laminas_marshalHeadersFromSapi(...func_get_args());
|
||||||
|
}
|
69
vendor/laminas/laminas-diactoros/src/functions/marshal_headers_from_sapi.php
vendored
Normal file
69
vendor/laminas/laminas-diactoros/src/functions/marshal_headers_from_sapi.php
vendored
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use function array_key_exists;
|
||||||
|
use function is_string;
|
||||||
|
use function strpos;
|
||||||
|
use function strtolower;
|
||||||
|
use function strtr;
|
||||||
|
use function substr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $server Values obtained from the SAPI (generally `$_SERVER`).
|
||||||
|
* @return array Header/value pairs
|
||||||
|
*/
|
||||||
|
function marshalHeadersFromSapi(array $server) : array
|
||||||
|
{
|
||||||
|
$contentHeaderLookup = isset($server['LAMINAS_DIACTOROS_STRICT_CONTENT_HEADER_LOOKUP'])
|
||||||
|
? static function (string $key) : bool {
|
||||||
|
static $contentHeaders = [
|
||||||
|
'CONTENT_TYPE' => true,
|
||||||
|
'CONTENT_LENGTH' => true,
|
||||||
|
'CONTENT_MD5' => true,
|
||||||
|
];
|
||||||
|
return isset($contentHeaders[$key]);
|
||||||
|
}
|
||||||
|
: static function (string $key): bool {
|
||||||
|
return strpos($key, 'CONTENT_') === 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
$headers = [];
|
||||||
|
foreach ($server as $key => $value) {
|
||||||
|
if (! is_string($key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($value === '') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apache prefixes environment variables with REDIRECT_
|
||||||
|
// if they are added by rewrite rules
|
||||||
|
if (strpos($key, 'REDIRECT_') === 0) {
|
||||||
|
$key = substr($key, 9);
|
||||||
|
|
||||||
|
// We will not overwrite existing variables with the
|
||||||
|
// prefixed versions, though
|
||||||
|
if (array_key_exists($key, $server)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strpos($key, 'HTTP_') === 0) {
|
||||||
|
$name = strtr(strtolower(substr($key, 5)), '_', '-');
|
||||||
|
$headers[$name] = $value;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($contentHeaderLookup($key)) {
|
||||||
|
$name = strtr(strtolower($key), '_', '-');
|
||||||
|
$headers[$name] = $value;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $headers;
|
||||||
|
}
|
15
vendor/laminas/laminas-diactoros/src/functions/marshal_method_from_sapi.legacy.php
vendored
Normal file
15
vendor/laminas/laminas-diactoros/src/functions/marshal_method_from_sapi.legacy.php
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Zend\Diactoros;
|
||||||
|
|
||||||
|
use function Laminas\Diactoros\marshalMethodFromSapi as laminas_marshalMethodFromSapi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use Laminas\Diactoros\marshalMethodFromSapi instead
|
||||||
|
*/
|
||||||
|
function marshalMethodFromSapi(array $server) : string
|
||||||
|
{
|
||||||
|
return laminas_marshalMethodFromSapi(...func_get_args());
|
||||||
|
}
|
13
vendor/laminas/laminas-diactoros/src/functions/marshal_method_from_sapi.php
vendored
Normal file
13
vendor/laminas/laminas-diactoros/src/functions/marshal_method_from_sapi.php
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the request method from the SAPI parameters.
|
||||||
|
*/
|
||||||
|
function marshalMethodFromSapi(array $server) : string
|
||||||
|
{
|
||||||
|
return $server['REQUEST_METHOD'] ?? 'GET';
|
||||||
|
}
|
15
vendor/laminas/laminas-diactoros/src/functions/marshal_protocol_version_from_sapi.legacy.php
vendored
Normal file
15
vendor/laminas/laminas-diactoros/src/functions/marshal_protocol_version_from_sapi.legacy.php
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Zend\Diactoros;
|
||||||
|
|
||||||
|
use function Laminas\Diactoros\marshalProtocolVersionFromSapi as laminas_marshalProtocolVersionFromSapi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use Laminas\Diactoros\marshalProtocolVersionFromSapi instead
|
||||||
|
*/
|
||||||
|
function marshalProtocolVersionFromSapi(array $server) : string
|
||||||
|
{
|
||||||
|
return laminas_marshalProtocolVersionFromSapi(...func_get_args());
|
||||||
|
}
|
28
vendor/laminas/laminas-diactoros/src/functions/marshal_protocol_version_from_sapi.php
vendored
Normal file
28
vendor/laminas/laminas-diactoros/src/functions/marshal_protocol_version_from_sapi.php
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use function preg_match;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return HTTP protocol version (X.Y) as discovered within a `$_SERVER` array.
|
||||||
|
*
|
||||||
|
* @throws Exception\UnrecognizedProtocolVersionException if the
|
||||||
|
* $server['SERVER_PROTOCOL'] value is malformed.
|
||||||
|
*/
|
||||||
|
function marshalProtocolVersionFromSapi(array $server) : string
|
||||||
|
{
|
||||||
|
if (! isset($server['SERVER_PROTOCOL'])) {
|
||||||
|
return '1.1';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! preg_match('#^(HTTP/)?(?P<version>[1-9]\d*(?:\.\d)?)$#', $server['SERVER_PROTOCOL'], $matches)) {
|
||||||
|
throw Exception\UnrecognizedProtocolVersionException::forVersion(
|
||||||
|
(string) $server['SERVER_PROTOCOL']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $matches['version'];
|
||||||
|
}
|
15
vendor/laminas/laminas-diactoros/src/functions/marshal_uri_from_sapi.legacy.php
vendored
Normal file
15
vendor/laminas/laminas-diactoros/src/functions/marshal_uri_from_sapi.legacy.php
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Zend\Diactoros;
|
||||||
|
|
||||||
|
use function Laminas\Diactoros\marshalUriFromSapi as laminas_marshalUriFromSapi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use Laminas\Diactoros\marshalUriFromSapi instead
|
||||||
|
*/
|
||||||
|
function marshalUriFromSapi(array $server, array $headers) : Uri
|
||||||
|
{
|
||||||
|
return laminas_marshalUriFromSapi(...func_get_args());
|
||||||
|
}
|
218
vendor/laminas/laminas-diactoros/src/functions/marshal_uri_from_sapi.php
vendored
Normal file
218
vendor/laminas/laminas-diactoros/src/functions/marshal_uri_from_sapi.php
vendored
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use function array_change_key_case;
|
||||||
|
use function array_key_exists;
|
||||||
|
use function explode;
|
||||||
|
use function implode;
|
||||||
|
use function is_array;
|
||||||
|
use function ltrim;
|
||||||
|
use function preg_match;
|
||||||
|
use function preg_replace;
|
||||||
|
use function strlen;
|
||||||
|
use function strpos;
|
||||||
|
use function strtolower;
|
||||||
|
use function substr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marshal a Uri instance based on the values presnt in the $_SERVER array and headers.
|
||||||
|
*
|
||||||
|
* @param array $server SAPI parameters
|
||||||
|
* @param array $headers HTTP request headers
|
||||||
|
*/
|
||||||
|
function marshalUriFromSapi(array $server, array $headers) : Uri
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Retrieve a header value from an array of headers using a case-insensitive lookup.
|
||||||
|
*
|
||||||
|
* @param array $headers Key/value header pairs
|
||||||
|
* @param mixed $default Default value to return if header not found
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
$getHeaderFromArray = function (string $name, array $headers, $default = null) {
|
||||||
|
$header = strtolower($name);
|
||||||
|
$headers = array_change_key_case($headers, CASE_LOWER);
|
||||||
|
if (array_key_exists($header, $headers)) {
|
||||||
|
$value = is_array($headers[$header]) ? implode(', ', $headers[$header]) : $headers[$header];
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $default;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marshal the host and port from HTTP headers and/or the PHP environment.
|
||||||
|
*
|
||||||
|
* @return array Array of two items, host and port, in that order (can be
|
||||||
|
* passed to a list() operation).
|
||||||
|
*/
|
||||||
|
$marshalHostAndPort = function (array $headers, array $server) use ($getHeaderFromArray) : array {
|
||||||
|
/**
|
||||||
|
* @param string|array $host
|
||||||
|
* @return array Array of two items, host and port, in that order (can be
|
||||||
|
* passed to a list() operation).
|
||||||
|
*/
|
||||||
|
$marshalHostAndPortFromHeader = function ($host) {
|
||||||
|
if (is_array($host)) {
|
||||||
|
$host = implode(', ', $host);
|
||||||
|
}
|
||||||
|
|
||||||
|
$port = null;
|
||||||
|
|
||||||
|
// works for regname, IPv4 & IPv6
|
||||||
|
if (preg_match('|\:(\d+)$|', $host, $matches)) {
|
||||||
|
$host = substr($host, 0, -1 * (strlen($matches[1]) + 1));
|
||||||
|
$port = (int) $matches[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [$host, $port];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array Array of two items, host and port, in that order (can be
|
||||||
|
* passed to a list() operation).
|
||||||
|
*/
|
||||||
|
$marshalIpv6HostAndPort = function (array $server, ?int $port) : array {
|
||||||
|
$host = '[' . $server['SERVER_ADDR'] . ']';
|
||||||
|
$port = $port ?: 80;
|
||||||
|
if ($port . ']' === substr($host, strrpos($host, ':') + 1)) {
|
||||||
|
// The last digit of the IPv6-Address has been taken as port
|
||||||
|
// Unset the port so the default port can be used
|
||||||
|
$port = null;
|
||||||
|
}
|
||||||
|
return [$host, $port];
|
||||||
|
};
|
||||||
|
|
||||||
|
static $defaults = ['', null];
|
||||||
|
|
||||||
|
$forwardedHost = $getHeaderFromArray('x-forwarded-host', $headers, false);
|
||||||
|
if ($forwardedHost !== false) {
|
||||||
|
return $marshalHostAndPortFromHeader($forwardedHost);
|
||||||
|
}
|
||||||
|
|
||||||
|
$host = $getHeaderFromArray('host', $headers, false);
|
||||||
|
if ($host !== false) {
|
||||||
|
return $marshalHostAndPortFromHeader($host);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! isset($server['SERVER_NAME'])) {
|
||||||
|
return $defaults;
|
||||||
|
}
|
||||||
|
|
||||||
|
$host = $server['SERVER_NAME'];
|
||||||
|
$port = isset($server['SERVER_PORT']) ? (int) $server['SERVER_PORT'] : null;
|
||||||
|
|
||||||
|
if (! isset($server['SERVER_ADDR'])
|
||||||
|
|| ! preg_match('/^\[[0-9a-fA-F\:]+\]$/', $host)
|
||||||
|
) {
|
||||||
|
return [$host, $port];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Misinterpreted IPv6-Address
|
||||||
|
// Reported for Safari on Windows
|
||||||
|
return $marshalIpv6HostAndPort($server, $port);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect the path for the request
|
||||||
|
*
|
||||||
|
* Looks at a variety of criteria in order to attempt to autodetect the base
|
||||||
|
* request path, including:
|
||||||
|
*
|
||||||
|
* - IIS7 UrlRewrite environment
|
||||||
|
* - REQUEST_URI
|
||||||
|
* - ORIG_PATH_INFO
|
||||||
|
*
|
||||||
|
* From Laminas\Http\PhpEnvironment\Request class
|
||||||
|
*/
|
||||||
|
$marshalRequestPath = function (array $server) : string {
|
||||||
|
// IIS7 with URL Rewrite: make sure we get the unencoded url
|
||||||
|
// (double slash problem).
|
||||||
|
$iisUrlRewritten = $server['IIS_WasUrlRewritten'] ?? null;
|
||||||
|
$unencodedUrl = $server['UNENCODED_URL'] ?? '';
|
||||||
|
if ('1' === $iisUrlRewritten && ! empty($unencodedUrl)) {
|
||||||
|
return $unencodedUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
$requestUri = $server['REQUEST_URI'] ?? null;
|
||||||
|
|
||||||
|
if ($requestUri !== null) {
|
||||||
|
return preg_replace('#^[^/:]+://[^/]+#', '', $requestUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
$origPathInfo = $server['ORIG_PATH_INFO'] ?? null;
|
||||||
|
if (empty($origPathInfo)) {
|
||||||
|
return '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $origPathInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
$uri = new Uri('');
|
||||||
|
|
||||||
|
// URI scheme
|
||||||
|
$scheme = 'http';
|
||||||
|
$marshalHttpsValue = function ($https) : bool {
|
||||||
|
if (is_bool($https)) {
|
||||||
|
return $https;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! is_string($https)) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'SAPI HTTPS value MUST be a string or boolean; received %s',
|
||||||
|
gettype($https)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'on' === strtolower($https);
|
||||||
|
};
|
||||||
|
if (array_key_exists('HTTPS', $server)) {
|
||||||
|
$https = $marshalHttpsValue($server['HTTPS']);
|
||||||
|
} elseif (array_key_exists('https', $server)) {
|
||||||
|
$https = $marshalHttpsValue($server['https']);
|
||||||
|
} else {
|
||||||
|
$https = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($https
|
||||||
|
|| strtolower($getHeaderFromArray('x-forwarded-proto', $headers, '')) === 'https'
|
||||||
|
) {
|
||||||
|
$scheme = 'https';
|
||||||
|
}
|
||||||
|
$uri = $uri->withScheme($scheme);
|
||||||
|
|
||||||
|
// Set the host
|
||||||
|
[$host, $port] = $marshalHostAndPort($headers, $server);
|
||||||
|
if (! empty($host)) {
|
||||||
|
$uri = $uri->withHost($host);
|
||||||
|
if (! empty($port)) {
|
||||||
|
$uri = $uri->withPort($port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// URI path
|
||||||
|
$path = $marshalRequestPath($server);
|
||||||
|
|
||||||
|
// Strip query string
|
||||||
|
$path = explode('?', $path, 2)[0];
|
||||||
|
|
||||||
|
// URI query
|
||||||
|
$query = '';
|
||||||
|
if (isset($server['QUERY_STRING'])) {
|
||||||
|
$query = ltrim($server['QUERY_STRING'], '?');
|
||||||
|
}
|
||||||
|
|
||||||
|
// URI fragment
|
||||||
|
$fragment = '';
|
||||||
|
if (strpos($path, '#') !== false) {
|
||||||
|
[$path, $fragment] = explode('#', $path, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $uri
|
||||||
|
->withPath($path)
|
||||||
|
->withFragment($fragment)
|
||||||
|
->withQuery($query);
|
||||||
|
}
|
15
vendor/laminas/laminas-diactoros/src/functions/normalize_server.legacy.php
vendored
Normal file
15
vendor/laminas/laminas-diactoros/src/functions/normalize_server.legacy.php
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Zend\Diactoros;
|
||||||
|
|
||||||
|
use function Laminas\Diactoros\normalizeServer as laminas_normalizeServer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use Laminas\Diactoros\normalizeServer instead
|
||||||
|
*/
|
||||||
|
function normalizeServer(array $server, callable $apacheRequestHeaderCallback = null) : array
|
||||||
|
{
|
||||||
|
return laminas_normalizeServer(...func_get_args());
|
||||||
|
}
|
47
vendor/laminas/laminas-diactoros/src/functions/normalize_server.php
vendored
Normal file
47
vendor/laminas/laminas-diactoros/src/functions/normalize_server.php
vendored
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use function is_callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marshal the $_SERVER array
|
||||||
|
*
|
||||||
|
* Pre-processes and returns the $_SERVER superglobal. In particularly, it
|
||||||
|
* attempts to detect the Authorization header, which is often not aggregated
|
||||||
|
* correctly under various SAPI/httpd combinations.
|
||||||
|
*
|
||||||
|
* @param null|callable $apacheRequestHeaderCallback Callback that can be used to
|
||||||
|
* retrieve Apache request headers. This defaults to
|
||||||
|
* `apache_request_headers` under the Apache mod_php.
|
||||||
|
* @return array Either $server verbatim, or with an added HTTP_AUTHORIZATION header.
|
||||||
|
*/
|
||||||
|
function normalizeServer(array $server, callable $apacheRequestHeaderCallback = null) : array
|
||||||
|
{
|
||||||
|
if (null === $apacheRequestHeaderCallback && is_callable('apache_request_headers')) {
|
||||||
|
$apacheRequestHeaderCallback = 'apache_request_headers';
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the HTTP_AUTHORIZATION value is already set, or the callback is not
|
||||||
|
// callable, we return verbatim
|
||||||
|
if (isset($server['HTTP_AUTHORIZATION'])
|
||||||
|
|| ! is_callable($apacheRequestHeaderCallback)
|
||||||
|
) {
|
||||||
|
return $server;
|
||||||
|
}
|
||||||
|
|
||||||
|
$apacheRequestHeaders = $apacheRequestHeaderCallback();
|
||||||
|
if (isset($apacheRequestHeaders['Authorization'])) {
|
||||||
|
$server['HTTP_AUTHORIZATION'] = $apacheRequestHeaders['Authorization'];
|
||||||
|
return $server;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($apacheRequestHeaders['authorization'])) {
|
||||||
|
$server['HTTP_AUTHORIZATION'] = $apacheRequestHeaders['authorization'];
|
||||||
|
return $server;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $server;
|
||||||
|
}
|
17
vendor/laminas/laminas-diactoros/src/functions/normalize_uploaded_files.legacy.php
vendored
Normal file
17
vendor/laminas/laminas-diactoros/src/functions/normalize_uploaded_files.legacy.php
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Zend\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\UploadedFileInterface;
|
||||||
|
|
||||||
|
use function Laminas\Diactoros\normalizeUploadedFiles as laminas_normalizeUploadedFiles;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use Laminas\Diactoros\normalizeUploadedFiles instead
|
||||||
|
*/
|
||||||
|
function normalizeUploadedFiles(array $files) : array
|
||||||
|
{
|
||||||
|
return laminas_normalizeUploadedFiles(...func_get_args());
|
||||||
|
}
|
124
vendor/laminas/laminas-diactoros/src/functions/normalize_uploaded_files.php
vendored
Normal file
124
vendor/laminas/laminas-diactoros/src/functions/normalize_uploaded_files.php
vendored
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use Psr\Http\Message\UploadedFileInterface;
|
||||||
|
|
||||||
|
use function is_array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize uploaded files
|
||||||
|
*
|
||||||
|
* Transforms each value into an UploadedFile instance, and ensures that nested
|
||||||
|
* arrays are normalized.
|
||||||
|
*
|
||||||
|
* @return UploadedFileInterface[]
|
||||||
|
* @throws Exception\InvalidArgumentException for unrecognized values
|
||||||
|
*/
|
||||||
|
function normalizeUploadedFiles(array $files) : array
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Traverse a nested tree of uploaded file specifications.
|
||||||
|
*
|
||||||
|
* @param string[]|array[] $tmpNameTree
|
||||||
|
* @param int[]|array[] $sizeTree
|
||||||
|
* @param int[]|array[] $errorTree
|
||||||
|
* @param string[]|array[]|null $nameTree
|
||||||
|
* @param string[]|array[]|null $typeTree
|
||||||
|
* @return UploadedFile[]|array[]
|
||||||
|
*/
|
||||||
|
$recursiveNormalize = function (
|
||||||
|
array $tmpNameTree,
|
||||||
|
array $sizeTree,
|
||||||
|
array $errorTree,
|
||||||
|
array $nameTree = null,
|
||||||
|
array $typeTree = null
|
||||||
|
) use (&$recursiveNormalize) : array {
|
||||||
|
$normalized = [];
|
||||||
|
foreach ($tmpNameTree as $key => $value) {
|
||||||
|
if (is_array($value)) {
|
||||||
|
// Traverse
|
||||||
|
$normalized[$key] = $recursiveNormalize(
|
||||||
|
$tmpNameTree[$key],
|
||||||
|
$sizeTree[$key],
|
||||||
|
$errorTree[$key],
|
||||||
|
$nameTree[$key] ?? null,
|
||||||
|
$typeTree[$key] ?? null
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$normalized[$key] = createUploadedFile([
|
||||||
|
'tmp_name' => $tmpNameTree[$key],
|
||||||
|
'size' => $sizeTree[$key],
|
||||||
|
'error' => $errorTree[$key],
|
||||||
|
'name' => $nameTree[$key] ?? null,
|
||||||
|
'type' => $typeTree[$key] ?? null,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
return $normalized;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize an array of file specifications.
|
||||||
|
*
|
||||||
|
* Loops through all nested files (as determined by receiving an array to the
|
||||||
|
* `tmp_name` key of a `$_FILES` specification) and returns a normalized array
|
||||||
|
* of UploadedFile instances.
|
||||||
|
*
|
||||||
|
* This function normalizes a `$_FILES` array representing a nested set of
|
||||||
|
* uploaded files as produced by the php-fpm SAPI, CGI SAPI, or mod_php
|
||||||
|
* SAPI.
|
||||||
|
*
|
||||||
|
* @param array $files
|
||||||
|
* @return UploadedFile[]
|
||||||
|
*/
|
||||||
|
$normalizeUploadedFileSpecification = function (array $files = []) use (&$recursiveNormalize) : array {
|
||||||
|
if (! isset($files['tmp_name']) || ! is_array($files['tmp_name'])
|
||||||
|
|| ! isset($files['size']) || ! is_array($files['size'])
|
||||||
|
|| ! isset($files['error']) || ! is_array($files['error'])
|
||||||
|
) {
|
||||||
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
|
'$files provided to %s MUST contain each of the keys "tmp_name",'
|
||||||
|
. ' "size", and "error", with each represented as an array;'
|
||||||
|
. ' one or more were missing or non-array values',
|
||||||
|
__FUNCTION__
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $recursiveNormalize(
|
||||||
|
$files['tmp_name'],
|
||||||
|
$files['size'],
|
||||||
|
$files['error'],
|
||||||
|
$files['name'] ?? null,
|
||||||
|
$files['type'] ?? null
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
$normalized = [];
|
||||||
|
foreach ($files as $key => $value) {
|
||||||
|
if ($value instanceof UploadedFileInterface) {
|
||||||
|
$normalized[$key] = $value;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($value) && isset($value['tmp_name']) && is_array($value['tmp_name'])) {
|
||||||
|
$normalized[$key] = $normalizeUploadedFileSpecification($value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($value) && isset($value['tmp_name'])) {
|
||||||
|
$normalized[$key] = createUploadedFile($value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($value)) {
|
||||||
|
$normalized[$key] = normalizeUploadedFiles($value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Exception\InvalidArgumentException('Invalid value in files specification');
|
||||||
|
}
|
||||||
|
return $normalized;
|
||||||
|
}
|
15
vendor/laminas/laminas-diactoros/src/functions/parse_cookie_header.legacy.php
vendored
Normal file
15
vendor/laminas/laminas-diactoros/src/functions/parse_cookie_header.legacy.php
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Zend\Diactoros;
|
||||||
|
|
||||||
|
use function Laminas\Diactoros\parseCookieHeader as laminas_parseCookieHeader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use Laminas\Diactoros\parseCookieHeader instead
|
||||||
|
*/
|
||||||
|
function parseCookieHeader($cookieHeader) : array
|
||||||
|
{
|
||||||
|
return laminas_parseCookieHeader(...func_get_args());
|
||||||
|
}
|
38
vendor/laminas/laminas-diactoros/src/functions/parse_cookie_header.php
vendored
Normal file
38
vendor/laminas/laminas-diactoros/src/functions/parse_cookie_header.php
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Laminas\Diactoros;
|
||||||
|
|
||||||
|
use function preg_match_all;
|
||||||
|
use function urldecode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a cookie header according to RFC 6265.
|
||||||
|
*
|
||||||
|
* PHP will replace special characters in cookie names, which results in other cookies not being available due to
|
||||||
|
* overwriting. Thus, the server request should take the cookies from the request header instead.
|
||||||
|
*
|
||||||
|
* @param string $cookieHeader A string cookie header value.
|
||||||
|
* @return array key/value cookie pairs.
|
||||||
|
*/
|
||||||
|
function parseCookieHeader($cookieHeader) : array
|
||||||
|
{
|
||||||
|
preg_match_all('(
|
||||||
|
(?:^\\n?[ \t]*|;[ ])
|
||||||
|
(?P<name>[!#$%&\'*+-.0-9A-Z^_`a-z|~]+)
|
||||||
|
=
|
||||||
|
(?P<DQUOTE>"?)
|
||||||
|
(?P<value>[\x21\x23-\x2b\x2d-\x3a\x3c-\x5b\x5d-\x7e]*)
|
||||||
|
(?P=DQUOTE)
|
||||||
|
(?=\\n?[ \t]*$|;[ ])
|
||||||
|
)x', $cookieHeader, $matches, PREG_SET_ORDER);
|
||||||
|
|
||||||
|
$cookies = [];
|
||||||
|
|
||||||
|
foreach ($matches as $match) {
|
||||||
|
$cookies[$match['name']] = urldecode($match['value']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $cookies;
|
||||||
|
}
|
Loading…
Reference in a new issue