updated-packages

This commit is contained in:
RafficMohammed
2023-01-08 00:13:22 +05:30
parent 3ff7df7487
commit da241bacb6
12659 changed files with 563377 additions and 510538 deletions

View File

@@ -1,9 +0,0 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

View File

@@ -0,0 +1,2 @@
github: [Nyholm, GrahamCampbell]
tidelift: "packagist/guzzlehttp/psr7"

View File

@@ -0,0 +1,14 @@
daysUntilStale: 120
daysUntilClose: 14
exemptLabels:
- lifecycle/keep-open
- lifecycle/ready-for-merge
# Label to use when marking an issue as stale
staleLabel: lifecycle/stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed after 2 weeks if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

View File

@@ -0,0 +1,34 @@
name: CI
on:
pull_request:
jobs:
build:
name: Build
runs-on: ubuntu-latest
strategy:
max-parallel: 10
matrix:
php: ['5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1']
steps:
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: 'none'
extensions: mbstring
- name: Checkout code
uses: actions/checkout@v2
- name: Mimic PHP 8.0
run: composer config platform.php 8.0.999
if: matrix.php > 8
- name: Install dependencies
run: composer update --no-interaction --no-progress
- name: Run tests
run: make test

View File

@@ -0,0 +1,37 @@
name: Integration
on:
pull_request:
jobs:
build:
name: Test
runs-on: ubuntu-latest
strategy:
max-parallel: 10
matrix:
php: ['7.2', '7.3', '7.4', '8.0']
steps:
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: none
- name: Checkout code
uses: actions/checkout@v2
- name: Download dependencies
uses: ramsey/composer-install@v1
with:
composer-options: --no-interaction --optimize-autoloader
- name: Start server
run: php -S 127.0.0.1:10002 tests/Integration/server.php &
- name: Run tests
env:
TEST_SERVER: 127.0.0.1:10002
run: ./vendor/bin/phpunit --testsuite Integration

View File

@@ -0,0 +1,29 @@
name: Static analysis
on:
pull_request:
jobs:
php-cs-fixer:
name: PHP-CS-Fixer
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '7.4'
coverage: none
extensions: mbstring
- name: Download dependencies
run: composer update --no-interaction --no-progress
- name: Download PHP CS Fixer
run: composer require "friendsofphp/php-cs-fixer:2.18.4"
- name: Execute PHP CS Fixer
run: vendor/bin/php-cs-fixer fix --diff-format udiff --dry-run

56
vendor/guzzlehttp/psr7/.php_cs.dist vendored Normal file
View File

@@ -0,0 +1,56 @@
<?php
$config = PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setRules([
'@PSR2' => true,
'array_syntax' => ['syntax' => 'short'],
'concat_space' => ['spacing' => 'one'],
'declare_strict_types' => false,
'final_static_access' => true,
'fully_qualified_strict_types' => true,
'header_comment' => false,
'is_null' => ['use_yoda_style' => true],
'list_syntax' => ['syntax' => 'long'],
'lowercase_cast' => true,
'magic_method_casing' => true,
'modernize_types_casting' => true,
'multiline_comment_opening_closing' => true,
'no_alias_functions' => true,
'no_alternative_syntax' => true,
'no_blank_lines_after_phpdoc' => true,
'no_empty_comment' => true,
'no_empty_phpdoc' => true,
'no_empty_statement' => true,
'no_extra_blank_lines' => true,
'no_leading_import_slash' => true,
'no_trailing_comma_in_singleline_array' => true,
'no_unset_cast' => true,
'no_unused_imports' => true,
'no_whitespace_in_blank_line' => true,
'ordered_imports' => true,
'php_unit_ordered_covers' => true,
'php_unit_test_annotation' => ['style' => 'prefix'],
'php_unit_test_case_static_method_calls' => ['call_type' => 'self'],
'phpdoc_align' => ['align' => 'vertical'],
'phpdoc_no_useless_inheritdoc' => true,
'phpdoc_scalar' => true,
'phpdoc_separation' => true,
'phpdoc_single_line_var_spacing' => true,
'phpdoc_trim' => true,
'phpdoc_trim_consecutive_blank_line_separation' => true,
'phpdoc_types' => true,
'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'],
'phpdoc_var_without_name' => true,
'single_trait_insert_per_statement' => true,
'standardize_not_equals' => true,
])
->setFinder(
PhpCsFixer\Finder::create()
->in(__DIR__.'/src')
->in(__DIR__.'/tests')
->name('*.php')
)
;
return $config;

View File

@@ -3,11 +3,104 @@
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## Unreleased
## 1.9.0 - 2022-06-20
### Added
- Added `UriComparator::isCrossOrigin` method
## 1.8.5 - 2022-03-20
### Fixed
- Correct header value validation
## 1.8.4 - 2022-03-20
### Fixed
- Validate header values properly
## 1.8.3 - 2021-10-05
### Fixed
- Return `null` in caching stream size if remote size is `null`
## 1.8.2 - 2021-04-26
### Fixed
- Handle possibly unset `url` in `stream_get_meta_data`
## 1.8.1 - 2021-03-21
### Fixed
- Issue parsing IPv6 URLs
- Issue modifying ServerRequest lost all its attributes
## 1.8.0 - 2021-03-21
### Added
- Locale independent URL parsing
- Most classes got a `@final` annotation to prepare for 2.0
### Fixed
- Issue when creating stream from `php://input` and curl-ext is not installed
- Broken `Utils::tryFopen()` on PHP 8
## 1.7.0 - 2020-09-30
### Added
- Replaced functions by static methods
### Fixed
- Converting a non-seekable stream to a string
- Handle multiple Set-Cookie correctly
- Ignore array keys in header values when merging
- Allow multibyte characters to be parsed in `Message:bodySummary()`
### Changed
- Restored partial HHVM 3 support
## [1.6.1] - 2019-07-02
### Fixed
- Accept null and bool header values again
## [1.6.0] - 2019-06-30
### Added
- Allowed version `^3.0` of `ralouphie/getallheaders` dependency (#244)
- Added MIME type for WEBP image format (#246)
- Added more validation of values according to PSR-7 and RFC standards, e.g. status code range (#250, #272)
### Changed
- Tests don't pass with HHVM 4.0, so HHVM support got dropped. Other libraries like composer have done the same. (#262)
- Accept port number 0 to be valid (#270)
### Fixed
- Fixed subsequent reads from `php://input` in ServerRequest (#247)
- Fixed readable/writable detection for certain stream modes (#248)
- Fixed encoding of special characters in the `userInfo` component of an URI (#253)
## [1.5.2] - 2018-12-04
@@ -209,7 +302,7 @@ Currently unsupported:
[Unreleased]: https://github.com/guzzle/psr7/compare/1.5.2...HEAD
[1.6.0]: https://github.com/guzzle/psr7/compare/1.5.2...1.6.0
[1.5.2]: https://github.com/guzzle/psr7/compare/1.5.1...1.5.2
[1.5.1]: https://github.com/guzzle/psr7/compare/1.5.0...1.5.1
[1.5.0]: https://github.com/guzzle/psr7/compare/1.4.2...1.5.0

View File

@@ -1,4 +1,11 @@
Copyright (c) 2015 Michael Dowling, https://github.com/mtdowling <mtdowling@gmail.com>
The MIT License (MIT)
Copyright (c) 2015 Michael Dowling <mtdowling@gmail.com>
Copyright (c) 2015 Márk Sági-Kazár <mark.sagikazar@gmail.com>
Copyright (c) 2015 Graham Campbell <hello@gjcampbell.co.uk>
Copyright (c) 2016 Tobias Schultze <webmaster@tubo-world.de>
Copyright (c) 2016 George Mponos <gmponos@gmail.com>
Copyright (c) 2018 Tobias Nyholm <tobias.nyholm@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,6 +1,6 @@
# PSR-7 Message Implementation
This repository contains a full [PSR-7](http://www.php-fig.org/psr/psr-7/)
This repository contains a full [PSR-7](https://www.php-fig.org/psr/psr-7/)
message implementation, several stream decorators, and some helpful
functionality like query string parsing.
@@ -23,11 +23,11 @@ Reads from multiple streams, one after the other.
```php
use GuzzleHttp\Psr7;
$a = Psr7\stream_for('abc, ');
$b = Psr7\stream_for('123.');
$a = Psr7\Utils::streamFor('abc, ');
$b = Psr7\Utils::streamFor('123.');
$composed = new Psr7\AppendStream([$a, $b]);
$composed->addStream(Psr7\stream_for(' Above all listen to me'));
$composed->addStream(Psr7\Utils::streamFor(' Above all listen to me'));
echo $composed; // abc, 123. Above all listen to me.
```
@@ -65,7 +65,7 @@ then on disk.
```php
use GuzzleHttp\Psr7;
$original = Psr7\stream_for(fopen('http://www.google.com', 'r'));
$original = Psr7\Utils::streamFor(fopen('http://www.google.com', 'r'));
$stream = new Psr7\CachingStream($original);
$stream->read(1024);
@@ -89,7 +89,7 @@ stream becomes too full.
use GuzzleHttp\Psr7;
// Create an empty stream
$stream = Psr7\stream_for();
$stream = Psr7\Utils::streamFor();
// Start dropping data when the stream has more than 10 bytes
$dropping = new Psr7\DroppingStream($stream, 10);
@@ -112,7 +112,7 @@ to create a concrete class for a simple extension point.
use GuzzleHttp\Psr7;
$stream = Psr7\stream_for('hi');
$stream = Psr7\Utils::streamFor('hi');
$fnStream = Psr7\FnStream::decorate($stream, [
'rewind' => function () use ($stream) {
echo 'About to rewind - ';
@@ -167,7 +167,7 @@ chunks (e.g. Amazon S3's multipart upload API).
```php
use GuzzleHttp\Psr7;
$original = Psr7\stream_for(fopen('/tmp/test.txt', 'r+'));
$original = Psr7\Utils::streamFor(fopen('/tmp/test.txt', 'r+'));
echo $original->getSize();
// >>> 1048576
@@ -197,7 +197,7 @@ NoSeekStream wraps a stream and does not allow seeking.
```php
use GuzzleHttp\Psr7;
$original = Psr7\stream_for('foo');
$original = Psr7\Utils::streamFor('foo');
$noSeek = new Psr7\NoSeekStream($original);
echo $noSeek->read(3);
@@ -271,7 +271,7 @@ This decorator could be added to any existing stream and used like so:
```php
use GuzzleHttp\Psr7;
$original = Psr7\stream_for('foo');
$original = Psr7\Utils::streamFor('foo');
$eofStream = new EofCallbackStream($original, function () {
echo 'EOF!';
@@ -297,53 +297,189 @@ stream from a PSR-7 stream.
```php
use GuzzleHttp\Psr7\StreamWrapper;
$stream = GuzzleHttp\Psr7\stream_for('hello!');
$stream = GuzzleHttp\Psr7\Utils::streamFor('hello!');
$resource = StreamWrapper::getResource($stream);
echo fread($resource, 6); // outputs hello!
```
# Function API
# Static API
There are various functions available under the `GuzzleHttp\Psr7` namespace.
There are various static methods available under the `GuzzleHttp\Psr7` namespace.
## `function str`
## `GuzzleHttp\Psr7\Message::toString`
`function str(MessageInterface $message)`
`public static function toString(MessageInterface $message): string`
Returns the string representation of an HTTP message.
```php
$request = new GuzzleHttp\Psr7\Request('GET', 'http://example.com');
echo GuzzleHttp\Psr7\str($request);
echo GuzzleHttp\Psr7\Message::toString($request);
```
## `function uri_for`
## `GuzzleHttp\Psr7\Message::bodySummary`
`function uri_for($uri)`
`public static function bodySummary(MessageInterface $message, int $truncateAt = 120): string|null`
This function accepts a string or `Psr\Http\Message\UriInterface` and returns a
UriInterface for the given value. If the value is already a `UriInterface`, it
is returned as-is.
Get a short summary of the message body.
```php
$uri = GuzzleHttp\Psr7\uri_for('http://example.com');
assert($uri === GuzzleHttp\Psr7\uri_for($uri));
```
Will return `null` if the response is not printable.
## `function stream_for`
## `GuzzleHttp\Psr7\Message::rewindBody`
`function stream_for($resource = '', array $options = [])`
`public static function rewindBody(MessageInterface $message): void`
Attempts to rewind a message body and throws an exception on failure.
The body of the message will only be rewound if a call to `tell()`
returns a value other than `0`.
## `GuzzleHttp\Psr7\Message::parseMessage`
`public static function parseMessage(string $message): array`
Parses an HTTP message into an associative array.
The array contains the "start-line" key containing the start line of
the message, "headers" key containing an associative array of header
array values, and a "body" key containing the body of the message.
## `GuzzleHttp\Psr7\Message::parseRequestUri`
`public static function parseRequestUri(string $path, array $headers): string`
Constructs a URI for an HTTP request message.
## `GuzzleHttp\Psr7\Message::parseRequest`
`public static function parseRequest(string $message): Request`
Parses a request message string into a request object.
## `GuzzleHttp\Psr7\Message::parseResponse`
`public static function parseResponse(string $message): Response`
Parses a response message string into a response object.
## `GuzzleHttp\Psr7\Header::parse`
`public static function parse(string|array $header): array`
Parse an array of header values containing ";" separated data into an
array of associative arrays representing the header key value pair data
of the header. When a parameter does not contain a value, but just
contains a key, this function will inject a key with a '' string value.
## `GuzzleHttp\Psr7\Header::normalize`
`public static function normalize(string|array $header): array`
Converts an array of header values that may contain comma separated
headers into an array of headers with no comma separated values.
## `GuzzleHttp\Psr7\Query::parse`
`public static function parse(string $str, int|bool $urlEncoding = true): array`
Parse a query string into an associative array.
If multiple values are found for the same key, the value of that key
value pair will become an array. This function does not parse nested
PHP style arrays into an associative array (e.g., `foo[a]=1&foo[b]=2`
will be parsed into `['foo[a]' => '1', 'foo[b]' => '2'])`.
## `GuzzleHttp\Psr7\Query::build`
`public static function build(array $params, int|false $encoding = PHP_QUERY_RFC3986): string`
Build a query string from an array of key value pairs.
This function can use the return value of `parse()` to build a query
string. This function does not modify the provided keys when an array is
encountered (like `http_build_query()` would).
## `GuzzleHttp\Psr7\Utils::caselessRemove`
`public static function caselessRemove(iterable<string> $keys, $keys, array $data): array`
Remove the items given by the keys, case insensitively from the data.
## `GuzzleHttp\Psr7\Utils::copyToStream`
`public static function copyToStream(StreamInterface $source, StreamInterface $dest, int $maxLen = -1): void`
Copy the contents of a stream into another stream until the given number
of bytes have been read.
## `GuzzleHttp\Psr7\Utils::copyToString`
`public static function copyToString(StreamInterface $stream, int $maxLen = -1): string`
Copy the contents of a stream into a string until the given number of
bytes have been read.
## `GuzzleHttp\Psr7\Utils::hash`
`public static function hash(StreamInterface $stream, string $algo, bool $rawOutput = false): string`
Calculate a hash of a stream.
This method reads the entire stream to calculate a rolling hash, based on
PHP's `hash_init` functions.
## `GuzzleHttp\Psr7\Utils::modifyRequest`
`public static function modifyRequest(RequestInterface $request, array $changes): RequestInterface`
Clone and modify a request with the given changes.
This method is useful for reducing the number of clones needed to mutate
a message.
- method: (string) Changes the HTTP method.
- set_headers: (array) Sets the given headers.
- remove_headers: (array) Remove the given headers.
- body: (mixed) Sets the given body.
- uri: (UriInterface) Set the URI.
- query: (string) Set the query string value of the URI.
- version: (string) Set the protocol version.
## `GuzzleHttp\Psr7\Utils::readLine`
`public static function readLine(StreamInterface $stream, int $maxLength = null): string`
Read a line from the stream up to the maximum allowed buffer length.
## `GuzzleHttp\Psr7\Utils::streamFor`
`public static function streamFor(resource|string|null|int|float|bool|StreamInterface|callable|\Iterator $resource = '', array $options = []): StreamInterface`
Create a new stream based on the input type.
Options is an associative array that can contain the following keys:
* - metadata: Array of custom metadata.
* - size: Size of the stream.
- metadata: Array of custom metadata.
- size: Size of the stream.
This method accepts the following `$resource` types:
@@ -369,8 +505,8 @@ This method accepts the following `$resource` types:
buffered and used in subsequent reads.
```php
$stream = GuzzleHttp\Psr7\stream_for('foo');
$stream = GuzzleHttp\Psr7\stream_for(fopen('/path/to/file', 'r'));
$stream = GuzzleHttp\Psr7\Utils::streamFor('foo');
$stream = GuzzleHttp\Psr7\Utils::streamFor(fopen('/path/to/file', 'r'));
$generator = function ($bytes) {
for ($i = 0; $i < $bytes; $i++) {
@@ -378,147 +514,75 @@ $generator = function ($bytes) {
}
}
$stream = GuzzleHttp\Psr7\stream_for($generator(100));
$stream = GuzzleHttp\Psr7\Utils::streamFor($generator(100));
```
## `function parse_header`
## `GuzzleHttp\Psr7\Utils::tryFopen`
`function parse_header($header)`
Parse an array of header values containing ";" separated data into an array of
associative arrays representing the header key value pair data of the header.
When a parameter does not contain a value, but just contains a key, this
function will inject a key with a '' string value.
## `function normalize_header`
`function normalize_header($header)`
Converts an array of header values that may contain comma separated headers
into an array of headers with no comma separated values.
## `function modify_request`
`function modify_request(RequestInterface $request, array $changes)`
Clone and modify a request with the given changes. This method is useful for
reducing the number of clones needed to mutate a message.
The changes can be one of:
- method: (string) Changes the HTTP method.
- set_headers: (array) Sets the given headers.
- remove_headers: (array) Remove the given headers.
- body: (mixed) Sets the given body.
- uri: (UriInterface) Set the URI.
- query: (string) Set the query string value of the URI.
- version: (string) Set the protocol version.
## `function rewind_body`
`function rewind_body(MessageInterface $message)`
Attempts to rewind a message body and throws an exception on failure. The body
of the message will only be rewound if a call to `tell()` returns a value other
than `0`.
## `function try_fopen`
`function try_fopen($filename, $mode)`
`public static function tryFopen(string $filename, string $mode): resource`
Safely opens a PHP stream resource using a filename.
When fopen fails, PHP normally raises a warning. This function adds an error
handler that checks for errors and throws an exception instead.
When fopen fails, PHP normally raises a warning. This function adds an
error handler that checks for errors and throws an exception instead.
## `function copy_to_string`
## `GuzzleHttp\Psr7\Utils::uriFor`
`function copy_to_string(StreamInterface $stream, $maxLen = -1)`
`public static function uriFor(string|UriInterface $uri): UriInterface`
Copy the contents of a stream into a string until the given number of bytes
have been read.
Returns a UriInterface for the given value.
This function accepts a string or UriInterface and returns a
UriInterface for the given value. If the value is already a
UriInterface, it is returned as-is.
## `function copy_to_stream`
## `GuzzleHttp\Psr7\MimeType::fromFilename`
`function copy_to_stream(StreamInterface $source, StreamInterface $dest, $maxLen = -1)`
Copy the contents of a stream into another stream until the given number of
bytes have been read.
## `function hash`
`function hash(StreamInterface $stream, $algo, $rawOutput = false)`
Calculate a hash of a Stream. This method reads the entire stream to calculate
a rolling hash (based on PHP's hash_init functions).
## `function readline`
`function readline(StreamInterface $stream, $maxLength = null)`
Read a line from the stream up to the maximum allowed buffer length.
## `function parse_request`
`function parse_request($message)`
Parses a request message string into a request object.
## `function parse_response`
`function parse_response($message)`
Parses a response message string into a response object.
## `function parse_query`
`function parse_query($str, $urlEncoding = true)`
Parse a query string into an associative array.
If multiple values are found for the same key, the value of that key value pair
will become an array. This function does not parse nested PHP style arrays into
an associative array (e.g., `foo[a]=1&foo[b]=2` will be parsed into
`['foo[a]' => '1', 'foo[b]' => '2']`).
## `function build_query`
`function build_query(array $params, $encoding = PHP_QUERY_RFC3986)`
Build a query string from an array of key value pairs.
This function can use the return value of parse_query() to build a query string.
This function does not modify the provided keys when an array is encountered
(like http_build_query would).
## `function mimetype_from_filename`
`function mimetype_from_filename($filename)`
`public static function fromFilename(string $filename): string|null`
Determines the mimetype of a file by looking at its extension.
## `function mimetype_from_extension`
## `GuzzleHttp\Psr7\MimeType::fromExtension`
`function mimetype_from_extension($extension)`
`public static function fromExtension(string $extension): string|null`
Maps a file extensions to a mimetype.
## Upgrading from Function API
The static API was first introduced in 1.7.0, in order to mitigate problems with functions conflicting between global and local copies of the package. The function API will be removed in 2.0.0. A migration table has been provided here for your convenience:
| Original Function | Replacement Method |
|----------------|----------------|
| `str` | `Message::toString` |
| `uri_for` | `Utils::uriFor` |
| `stream_for` | `Utils::streamFor` |
| `parse_header` | `Header::parse` |
| `normalize_header` | `Header::normalize` |
| `modify_request` | `Utils::modifyRequest` |
| `rewind_body` | `Message::rewindBody` |
| `try_fopen` | `Utils::tryFopen` |
| `copy_to_string` | `Utils::copyToString` |
| `copy_to_stream` | `Utils::copyToStream` |
| `hash` | `Utils::hash` |
| `readline` | `Utils::readLine` |
| `parse_request` | `Message::parseRequest` |
| `parse_response` | `Message::parseResponse` |
| `parse_query` | `Query::parse` |
| `build_query` | `Query::build` |
| `mimetype_from_filename` | `MimeType::fromFilename` |
| `mimetype_from_extension` | `MimeType::fromExtension` |
| `_parse_message` | `Message::parseMessage` |
| `_parse_request_uri` | `Message::parseRequestUri` |
| `get_message_body_summary` | `Message::bodySummary` |
| `_caseless_remove` | `Utils::caselessRemove` |
# Additional URI Methods
Aside from the standard `Psr\Http\Message\UriInterface` implementation in form of the `GuzzleHttp\Psr7\Uri` class,
@@ -595,7 +659,7 @@ manually but instead is used indirectly via `Psr\Http\Message\UriInterface::__to
`public static function fromParts(array $parts): UriInterface`
Creates a URI from a hash of [`parse_url`](http://php.net/manual/en/function.parse-url.php) components.
Creates a URI from a hash of [`parse_url`](https://www.php.net/manual/en/function.parse-url.php) components.
### `GuzzleHttp\Psr7\Uri::withQueryValue`
@@ -620,6 +684,16 @@ associative array of key => value.
Creates a new URI with a specific query string value removed. Any existing query string values that exactly match the
provided key are removed.
## Cross-Origin Detection
`GuzzleHttp\Psr7\UriComparator` provides methods to determine if a modified URL should be considered cross-origin.
### `GuzzleHttp\Psr7\UriComparator::isCrossOrigin`
`public static function isCrossOrigin(UriInterface $original, UriInterface $modified): bool`
Determines if a modified URL should be considered cross-origin with respect to an original URL.
## Reference Resolution
`GuzzleHttp\Psr7\UriResolver` provides methods to resolve a URI reference in the context of a base URI according
@@ -743,3 +817,28 @@ Whether two URIs can be considered equivalent. Both URIs are normalized automati
`$normalizations` bitmask. The method also accepts relative URI references and returns true when they are equivalent.
This of course assumes they will be resolved against the same base URI. If this is not the case, determination of
equivalence or difference of relative references does not mean anything.
## Version Guidance
| Version | Status | PHP Version |
|---------|----------------|------------------|
| 1.x | Security fixes | >=5.4,<8.1 |
| 2.x | Latest | ^7.2.5 \|\| ^8.0 |
## Security
If you discover a security vulnerability within this package, please send an email to security@tidelift.com. All security vulnerabilities will be promptly addressed. Please do not disclose security-related issues publicly until a fix has been announced. Please see [Security Policy](https://github.com/guzzle/psr7/security/policy) for more information.
## License
Guzzle is made available under the MIT License (MIT). Please see [License File](LICENSE) for more information.
## For Enterprise
Available as part of the Tidelift Subscription
The maintainers of Guzzle and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/packagist-guzzlehttp-psr7?utm_source=packagist-guzzlehttp-psr7&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)

View File

@@ -1,31 +1,55 @@
{
"name": "guzzlehttp/psr7",
"type": "library",
"description": "PSR-7 message implementation that also provides common utility methods",
"keywords": ["request", "response", "message", "stream", "http", "uri", "url", "psr-7"],
"license": "MIT",
"authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
},
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "George Mponos",
"email": "gmponos@gmail.com",
"homepage": "https://github.com/gmponos"
},
{
"name": "Tobias Nyholm",
"email": "tobias.nyholm@gmail.com",
"homepage": "https://github.com/Nyholm"
},
{
"name": "Márk Sági-Kazár",
"email": "mark.sagikazar@gmail.com",
"homepage": "https://github.com/sagikazarmark"
},
{
"name": "Tobias Schultze",
"email": "webmaster@tubo-world.de",
"homepage": "https://github.com/Tobion"
}
],
"require": {
"php": ">=5.4.0",
"psr/http-message": "~1.0",
"ralouphie/getallheaders": "^2.0.5"
"ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
},
"require-dev": {
"phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
"phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10",
"ext-zlib": "*"
},
"provide": {
"psr/http-message-implementation": "1.0"
},
"suggest": {
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Psr7\\": "src/"
@@ -39,7 +63,14 @@
},
"extra": {
"branch-alias": {
"dev-master": "1.5-dev"
"dev-master": "1.9-dev"
}
},
"config": {
"preferred-install": "dist",
"sort-packages": true,
"allow-plugins": {
"bamarni/composer-bin-plugin": true
}
}
}

View File

@@ -1,4 +1,5 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface;
@@ -7,6 +8,8 @@ use Psr\Http\Message\StreamInterface;
* Reads from multiple streams, one after the other.
*
* This is a read-only stream decorator.
*
* @final
*/
class AppendStream implements StreamInterface
{
@@ -61,7 +64,7 @@ class AppendStream implements StreamInterface
public function getContents()
{
return copy_to_string($this);
return Utils::copyToString($this);
}
/**
@@ -98,6 +101,8 @@ class AppendStream implements StreamInterface
}
$this->streams = [];
return null;
}
public function tell()

View File

@@ -1,4 +1,5 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface;
@@ -10,6 +11,8 @@ use Psr\Http\Message\StreamInterface;
* This stream returns a "hwm" metadata value that tells upstream consumers
* what the configured high water mark of the stream is, or the maximum
* preferred size of the buffer.
*
* @final
*/
class BufferStream implements StreamInterface
{
@@ -49,6 +52,8 @@ class BufferStream implements StreamInterface
public function detach()
{
$this->close();
return null;
}
public function getSize()

View File

@@ -1,4 +1,5 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface;
@@ -6,6 +7,8 @@ use Psr\Http\Message\StreamInterface;
/**
* Stream decorator that can cache previously read bytes from a sequentially
* read stream.
*
* @final
*/
class CachingStream implements StreamInterface
{
@@ -20,7 +23,7 @@ class CachingStream implements StreamInterface
/**
* We will treat the buffer object as the body of the stream
*
* @param StreamInterface $stream Stream to cache
* @param StreamInterface $stream Stream to cache. The cursor is assumed to be at the beginning of the stream.
* @param StreamInterface $target Optionally specify where data is cached
*/
public function __construct(
@@ -28,12 +31,18 @@ class CachingStream implements StreamInterface
StreamInterface $target = null
) {
$this->remoteStream = $stream;
$this->stream = $target ?: new Stream(fopen('php://temp', 'r+'));
$this->stream = $target ?: new Stream(Utils::tryFopen('php://temp', 'r+'));
}
public function getSize()
{
return max($this->stream->getSize(), $this->remoteStream->getSize());
$remoteSize = $this->remoteStream->getSize();
if (null === $remoteSize) {
return null;
}
return max($this->stream->getSize(), $remoteSize);
}
public function rewind()
@@ -131,7 +140,7 @@ class CachingStream implements StreamInterface
private function cacheEntireStream()
{
$target = new FnStream(['write' => 'strlen']);
copy_to_stream($this, $target);
Utils::copyToStream($this, $target);
return $this->tell();
}

View File

@@ -1,4 +1,5 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface;
@@ -6,6 +7,8 @@ use Psr\Http\Message\StreamInterface;
/**
* Stream decorator that begins dropping data once the size of the underlying
* stream becomes too full.
*
* @final
*/
class DroppingStream implements StreamInterface
{

View File

@@ -1,4 +1,5 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface;
@@ -8,6 +9,8 @@ use Psr\Http\Message\StreamInterface;
*
* Allows for easy testing and extension of a provided stream without needing
* to create a concrete class for a simple extension point.
*
* @final
*/
class FnStream implements StreamInterface
{
@@ -34,6 +37,7 @@ class FnStream implements StreamInterface
/**
* Lazily determine which methods are not implemented.
*
* @throws \BadMethodCallException
*/
public function __get($name)
@@ -54,6 +58,7 @@ class FnStream implements StreamInterface
/**
* An unserialize would allow the __destruct to run when the unserialized value goes out of scope.
*
* @throws \LogicException
*/
public function __wakeup()

71
vendor/guzzlehttp/psr7/src/Header.php vendored Normal file
View File

@@ -0,0 +1,71 @@
<?php
namespace GuzzleHttp\Psr7;
final class Header
{
/**
* Parse an array of header values containing ";" separated data into an
* array of associative arrays representing the header key value pair data
* of the header. When a parameter does not contain a value, but just
* contains a key, this function will inject a key with a '' string value.
*
* @param string|array $header Header to parse into components.
*
* @return array Returns the parsed header values.
*/
public static function parse($header)
{
static $trimmed = "\"' \n\t\r";
$params = $matches = [];
foreach (self::normalize($header) as $val) {
$part = [];
foreach (preg_split('/;(?=([^"]*"[^"]*")*[^"]*$)/', $val) as $kvp) {
if (preg_match_all('/<[^>]+>|[^=]+/', $kvp, $matches)) {
$m = $matches[0];
if (isset($m[1])) {
$part[trim($m[0], $trimmed)] = trim($m[1], $trimmed);
} else {
$part[] = trim($m[0], $trimmed);
}
}
}
if ($part) {
$params[] = $part;
}
}
return $params;
}
/**
* Converts an array of header values that may contain comma separated
* headers into an array of headers with no comma separated values.
*
* @param string|array $header Header to normalize.
*
* @return array Returns the normalized header field values.
*/
public static function normalize($header)
{
if (!is_array($header)) {
return array_map('trim', explode(',', $header));
}
$result = [];
foreach ($header as $value) {
foreach ((array) $value as $v) {
if (strpos($v, ',') === false) {
$result[] = $v;
continue;
}
foreach (preg_split('/,(?=([^"]*"[^"]*")*[^"]*$)/', $v) as $vv) {
$result[] = trim($vv);
}
}
}
return $result;
}
}

View File

@@ -1,4 +1,5 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface;
@@ -13,6 +14,8 @@ use Psr\Http\Message\StreamInterface;
*
* @link http://tools.ietf.org/html/rfc1952
* @link http://php.net/manual/en/filters.compression.php
*
* @final
*/
class InflateStream implements StreamInterface
{
@@ -33,6 +36,7 @@ class InflateStream implements StreamInterface
/**
* @param StreamInterface $stream
* @param $header
*
* @return int
*/
private function getLengthOfPossibleFilenameHeader(StreamInterface $stream, $header)

View File

@@ -1,4 +1,5 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface;
@@ -6,6 +7,8 @@ use Psr\Http\Message\StreamInterface;
/**
* Lazily reads or writes to a file that is opened only after an IO operation
* take place on the stream.
*
* @final
*/
class LazyOpenStream implements StreamInterface
{
@@ -14,7 +17,7 @@ class LazyOpenStream implements StreamInterface
/** @var string File to open */
private $filename;
/** @var string $mode */
/** @var string */
private $mode;
/**
@@ -34,6 +37,6 @@ class LazyOpenStream implements StreamInterface
*/
protected function createStream()
{
return stream_for(try_fopen($this->filename, $this->mode));
return Utils::streamFor(Utils::tryFopen($this->filename, $this->mode));
}
}

View File

@@ -1,11 +1,13 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface;
/**
* Decorator used to return only a subset of a stream
* Decorator used to return only a subset of a stream.
*
* @final
*/
class LimitStream implements StreamInterface
{
@@ -72,7 +74,7 @@ class LimitStream implements StreamInterface
{
if ($whence !== SEEK_SET || $offset < 0) {
throw new \RuntimeException(sprintf(
'Cannot seek to offset % with whence %s',
'Cannot seek to offset %s with whence %s',
$offset,
$whence
));

252
vendor/guzzlehttp/psr7/src/Message.php vendored Normal file
View File

@@ -0,0 +1,252 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
final class Message
{
/**
* Returns the string representation of an HTTP message.
*
* @param MessageInterface $message Message to convert to a string.
*
* @return string
*/
public static function toString(MessageInterface $message)
{
if ($message instanceof RequestInterface) {
$msg = trim($message->getMethod() . ' '
. $message->getRequestTarget())
. ' HTTP/' . $message->getProtocolVersion();
if (!$message->hasHeader('host')) {
$msg .= "\r\nHost: " . $message->getUri()->getHost();
}
} elseif ($message instanceof ResponseInterface) {
$msg = 'HTTP/' . $message->getProtocolVersion() . ' '
. $message->getStatusCode() . ' '
. $message->getReasonPhrase();
} else {
throw new \InvalidArgumentException('Unknown message type');
}
foreach ($message->getHeaders() as $name => $values) {
if (strtolower($name) === 'set-cookie') {
foreach ($values as $value) {
$msg .= "\r\n{$name}: " . $value;
}
} else {
$msg .= "\r\n{$name}: " . implode(', ', $values);
}
}
return "{$msg}\r\n\r\n" . $message->getBody();
}
/**
* Get a short summary of the message body.
*
* Will return `null` if the response is not printable.
*
* @param MessageInterface $message The message to get the body summary
* @param int $truncateAt The maximum allowed size of the summary
*
* @return string|null
*/
public static function bodySummary(MessageInterface $message, $truncateAt = 120)
{
$body = $message->getBody();
if (!$body->isSeekable() || !$body->isReadable()) {
return null;
}
$size = $body->getSize();
if ($size === 0) {
return null;
}
$summary = $body->read($truncateAt);
$body->rewind();
if ($size > $truncateAt) {
$summary .= ' (truncated...)';
}
// Matches any printable character, including unicode characters:
// letters, marks, numbers, punctuation, spacing, and separators.
if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/u', $summary)) {
return null;
}
return $summary;
}
/**
* Attempts to rewind a message body and throws an exception on failure.
*
* The body of the message will only be rewound if a call to `tell()`
* returns a value other than `0`.
*
* @param MessageInterface $message Message to rewind
*
* @throws \RuntimeException
*/
public static function rewindBody(MessageInterface $message)
{
$body = $message->getBody();
if ($body->tell()) {
$body->rewind();
}
}
/**
* Parses an HTTP message into an associative array.
*
* The array contains the "start-line" key containing the start line of
* the message, "headers" key containing an associative array of header
* array values, and a "body" key containing the body of the message.
*
* @param string $message HTTP request or response to parse.
*
* @return array
*/
public static function parseMessage($message)
{
if (!$message) {
throw new \InvalidArgumentException('Invalid message');
}
$message = ltrim($message, "\r\n");
$messageParts = preg_split("/\r?\n\r?\n/", $message, 2);
if ($messageParts === false || count($messageParts) !== 2) {
throw new \InvalidArgumentException('Invalid message: Missing header delimiter');
}
list($rawHeaders, $body) = $messageParts;
$rawHeaders .= "\r\n"; // Put back the delimiter we split previously
$headerParts = preg_split("/\r?\n/", $rawHeaders, 2);
if ($headerParts === false || count($headerParts) !== 2) {
throw new \InvalidArgumentException('Invalid message: Missing status line');
}
list($startLine, $rawHeaders) = $headerParts;
if (preg_match("/(?:^HTTP\/|^[A-Z]+ \S+ HTTP\/)(\d+(?:\.\d+)?)/i", $startLine, $matches) && $matches[1] === '1.0') {
// Header folding is deprecated for HTTP/1.1, but allowed in HTTP/1.0
$rawHeaders = preg_replace(Rfc7230::HEADER_FOLD_REGEX, ' ', $rawHeaders);
}
/** @var array[] $headerLines */
$count = preg_match_all(Rfc7230::HEADER_REGEX, $rawHeaders, $headerLines, PREG_SET_ORDER);
// If these aren't the same, then one line didn't match and there's an invalid header.
if ($count !== substr_count($rawHeaders, "\n")) {
// Folding is deprecated, see https://tools.ietf.org/html/rfc7230#section-3.2.4
if (preg_match(Rfc7230::HEADER_FOLD_REGEX, $rawHeaders)) {
throw new \InvalidArgumentException('Invalid header syntax: Obsolete line folding');
}
throw new \InvalidArgumentException('Invalid header syntax');
}
$headers = [];
foreach ($headerLines as $headerLine) {
$headers[$headerLine[1]][] = $headerLine[2];
}
return [
'start-line' => $startLine,
'headers' => $headers,
'body' => $body,
];
}
/**
* Constructs a URI for an HTTP request message.
*
* @param string $path Path from the start-line
* @param array $headers Array of headers (each value an array).
*
* @return string
*/
public static function parseRequestUri($path, array $headers)
{
$hostKey = array_filter(array_keys($headers), function ($k) {
return strtolower($k) === 'host';
});
// If no host is found, then a full URI cannot be constructed.
if (!$hostKey) {
return $path;
}
$host = $headers[reset($hostKey)][0];
$scheme = substr($host, -4) === ':443' ? 'https' : 'http';
return $scheme . '://' . $host . '/' . ltrim($path, '/');
}
/**
* Parses a request message string into a request object.
*
* @param string $message Request message string.
*
* @return Request
*/
public static function parseRequest($message)
{
$data = self::parseMessage($message);
$matches = [];
if (!preg_match('/^[\S]+\s+([a-zA-Z]+:\/\/|\/).*/', $data['start-line'], $matches)) {
throw new \InvalidArgumentException('Invalid request string');
}
$parts = explode(' ', $data['start-line'], 3);
$version = isset($parts[2]) ? explode('/', $parts[2])[1] : '1.1';
$request = new Request(
$parts[0],
$matches[1] === '/' ? self::parseRequestUri($parts[1], $data['headers']) : $parts[1],
$data['headers'],
$data['body'],
$version
);
return $matches[1] === '/' ? $request : $request->withRequestTarget($parts[1]);
}
/**
* Parses a response message string into a response object.
*
* @param string $message Response message string.
*
* @return Response
*/
public static function parseResponse($message)
{
$data = self::parseMessage($message);
// According to https://tools.ietf.org/html/rfc7230#section-3.1.2 the space
// between status-code and reason-phrase is required. But browsers accept
// responses without space and reason as well.
if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) {
throw new \InvalidArgumentException('Invalid response string: ' . $data['start-line']);
}
$parts = explode(' ', $data['start-line'], 3);
return new Response(
(int) $parts[1],
$data['headers'],
$data['body'],
explode('/', $parts[0])[1],
isset($parts[2]) ? $parts[2] : null
);
}
}

View File

@@ -1,4 +1,5 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface;
@@ -17,7 +18,7 @@ trait MessageTrait
/** @var string */
private $protocol = '1.1';
/** @var StreamInterface */
/** @var StreamInterface|null */
private $stream;
public function getProtocolVersion()
@@ -66,11 +67,8 @@ trait MessageTrait
public function withHeader($header, $value)
{
if (!is_array($value)) {
$value = [$value];
}
$value = $this->trimHeaderValues($value);
$this->assertHeader($header);
$value = $this->normalizeHeaderValue($value);
$normalized = strtolower($header);
$new = clone $this;
@@ -85,11 +83,8 @@ trait MessageTrait
public function withAddedHeader($header, $value)
{
if (!is_array($value)) {
$value = [$value];
}
$value = $this->trimHeaderValues($value);
$this->assertHeader($header);
$value = $this->normalizeHeaderValue($value);
$normalized = strtolower($header);
$new = clone $this;
@@ -123,7 +118,7 @@ trait MessageTrait
public function getBody()
{
if (!$this->stream) {
$this->stream = stream_for('');
$this->stream = Utils::streamFor('');
}
return $this->stream;
@@ -144,11 +139,13 @@ trait MessageTrait
{
$this->headerNames = $this->headers = [];
foreach ($headers as $header => $value) {
if (!is_array($value)) {
$value = [$value];
if (is_int($header)) {
// Numeric array keys are converted to int by PHP but having a header name '123' is not forbidden by the spec
// and also allowed in withHeader(). So we need to cast it to string again for the following assertion to pass.
$header = (string) $header;
}
$value = $this->trimHeaderValues($value);
$this->assertHeader($header);
$value = $this->normalizeHeaderValue($value);
$normalized = strtolower($header);
if (isset($this->headerNames[$normalized])) {
$header = $this->headerNames[$normalized];
@@ -160,6 +157,24 @@ trait MessageTrait
}
}
/**
* @param mixed $value
*
* @return string[]
*/
private function normalizeHeaderValue($value)
{
if (!is_array($value)) {
return $this->trimAndValidateHeaderValues([$value]);
}
if (count($value) === 0) {
throw new \InvalidArgumentException('Header value can not be an empty array.');
}
return $this->trimAndValidateHeaderValues($value);
}
/**
* Trims whitespace from the header values.
*
@@ -168,16 +183,88 @@ trait MessageTrait
* header-field = field-name ":" OWS field-value OWS
* OWS = *( SP / HTAB )
*
* @param string[] $values Header values
* @param mixed[] $values Header values
*
* @return string[] Trimmed header values
*
* @see https://tools.ietf.org/html/rfc7230#section-3.2.4
*/
private function trimHeaderValues(array $values)
private function trimAndValidateHeaderValues(array $values)
{
return array_map(function ($value) {
return trim($value, " \t");
}, $values);
if (!is_scalar($value) && null !== $value) {
throw new \InvalidArgumentException(sprintf(
'Header value must be scalar or null but %s provided.',
is_object($value) ? get_class($value) : gettype($value)
));
}
$trimmed = trim((string) $value, " \t");
$this->assertValue($trimmed);
return $trimmed;
}, array_values($values));
}
/**
* @see https://tools.ietf.org/html/rfc7230#section-3.2
*
* @param mixed $header
*
* @return void
*/
private function assertHeader($header)
{
if (!is_string($header)) {
throw new \InvalidArgumentException(sprintf(
'Header name must be a string but %s provided.',
is_object($header) ? get_class($header) : gettype($header)
));
}
if ($header === '') {
throw new \InvalidArgumentException('Header name can not be empty.');
}
if (! preg_match('/^[a-zA-Z0-9\'`#$%&*+.^_|~!-]+$/', $header)) {
throw new \InvalidArgumentException(
sprintf(
'"%s" is not valid header name',
$header
)
);
}
}
/**
* @param string $value
*
* @return void
*
* @see https://tools.ietf.org/html/rfc7230#section-3.2
*
* field-value = *( field-content / obs-fold )
* field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
* field-vchar = VCHAR / obs-text
* VCHAR = %x21-7E
* obs-text = %x80-FF
* obs-fold = CRLF 1*( SP / HTAB )
*/
private function assertValue($value)
{
// The regular expression intentionally does not support the obs-fold production, because as
// per RFC 7230#3.2.4:
//
// A sender MUST NOT generate a message that includes
// line folding (i.e., that has any field-value that contains a match to
// the obs-fold rule) unless the message is intended for packaging
// within the message/http media type.
//
// Clients must not send a request with line folding and a server sending folded headers is
// likely very rare. Line folding is a fairly obscure feature of HTTP/1.1 and thus not accepting
// folding is not likely to break any legitimate use case.
if (! preg_match('/^[\x20\x09\x21-\x7E\x80-\xFF]*$/', $value)) {
throw new \InvalidArgumentException(sprintf('"%s" is not valid header value', $value));
}
}
}

140
vendor/guzzlehttp/psr7/src/MimeType.php vendored Normal file
View File

@@ -0,0 +1,140 @@
<?php
namespace GuzzleHttp\Psr7;
final class MimeType
{
/**
* Determines the mimetype of a file by looking at its extension.
*
* @param string $filename
*
* @return string|null
*/
public static function fromFilename($filename)
{
return self::fromExtension(pathinfo($filename, PATHINFO_EXTENSION));
}
/**
* Maps a file extensions to a mimetype.
*
* @param string $extension string The file extension.
*
* @return string|null
*
* @link http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types
*/
public static function fromExtension($extension)
{
static $mimetypes = [
'3gp' => 'video/3gpp',
'7z' => 'application/x-7z-compressed',
'aac' => 'audio/x-aac',
'ai' => 'application/postscript',
'aif' => 'audio/x-aiff',
'asc' => 'text/plain',
'asf' => 'video/x-ms-asf',
'atom' => 'application/atom+xml',
'avi' => 'video/x-msvideo',
'bmp' => 'image/bmp',
'bz2' => 'application/x-bzip2',
'cer' => 'application/pkix-cert',
'crl' => 'application/pkix-crl',
'crt' => 'application/x-x509-ca-cert',
'css' => 'text/css',
'csv' => 'text/csv',
'cu' => 'application/cu-seeme',
'deb' => 'application/x-debian-package',
'doc' => 'application/msword',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'dvi' => 'application/x-dvi',
'eot' => 'application/vnd.ms-fontobject',
'eps' => 'application/postscript',
'epub' => 'application/epub+zip',
'etx' => 'text/x-setext',
'flac' => 'audio/flac',
'flv' => 'video/x-flv',
'gif' => 'image/gif',
'gz' => 'application/gzip',
'htm' => 'text/html',
'html' => 'text/html',
'ico' => 'image/x-icon',
'ics' => 'text/calendar',
'ini' => 'text/plain',
'iso' => 'application/x-iso9660-image',
'jar' => 'application/java-archive',
'jpe' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'js' => 'text/javascript',
'json' => 'application/json',
'latex' => 'application/x-latex',
'log' => 'text/plain',
'm4a' => 'audio/mp4',
'm4v' => 'video/mp4',
'mid' => 'audio/midi',
'midi' => 'audio/midi',
'mov' => 'video/quicktime',
'mkv' => 'video/x-matroska',
'mp3' => 'audio/mpeg',
'mp4' => 'video/mp4',
'mp4a' => 'audio/mp4',
'mp4v' => 'video/mp4',
'mpe' => 'video/mpeg',
'mpeg' => 'video/mpeg',
'mpg' => 'video/mpeg',
'mpg4' => 'video/mp4',
'oga' => 'audio/ogg',
'ogg' => 'audio/ogg',
'ogv' => 'video/ogg',
'ogx' => 'application/ogg',
'pbm' => 'image/x-portable-bitmap',
'pdf' => 'application/pdf',
'pgm' => 'image/x-portable-graymap',
'png' => 'image/png',
'pnm' => 'image/x-portable-anymap',
'ppm' => 'image/x-portable-pixmap',
'ppt' => 'application/vnd.ms-powerpoint',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'ps' => 'application/postscript',
'qt' => 'video/quicktime',
'rar' => 'application/x-rar-compressed',
'ras' => 'image/x-cmu-raster',
'rss' => 'application/rss+xml',
'rtf' => 'application/rtf',
'sgm' => 'text/sgml',
'sgml' => 'text/sgml',
'svg' => 'image/svg+xml',
'swf' => 'application/x-shockwave-flash',
'tar' => 'application/x-tar',
'tif' => 'image/tiff',
'tiff' => 'image/tiff',
'torrent' => 'application/x-bittorrent',
'ttf' => 'application/x-font-ttf',
'txt' => 'text/plain',
'wav' => 'audio/x-wav',
'webm' => 'video/webm',
'webp' => 'image/webp',
'wma' => 'audio/x-ms-wma',
'wmv' => 'video/x-ms-wmv',
'woff' => 'application/x-font-woff',
'wsdl' => 'application/wsdl+xml',
'xbm' => 'image/x-xbitmap',
'xls' => 'application/vnd.ms-excel',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'xml' => 'application/xml',
'xpm' => 'image/x-xpixmap',
'xwd' => 'image/x-xwindowdump',
'yaml' => 'text/yaml',
'yml' => 'text/yaml',
'zip' => 'application/zip',
];
$extension = strtolower($extension);
return isset($mimetypes[$extension])
? $mimetypes[$extension]
: null;
}
}

View File

@@ -1,4 +1,5 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface;
@@ -6,6 +7,8 @@ use Psr\Http\Message\StreamInterface;
/**
* Stream that when read returns bytes for a streaming multipart or
* multipart/form-data stream.
*
* @final
*/
class MultipartStream implements StreamInterface
{
@@ -71,7 +74,7 @@ class MultipartStream implements StreamInterface
}
// Add the trailing boundary with CRLF
$stream->addStream(stream_for("--{$this->boundary}--\r\n"));
$stream->addStream(Utils::streamFor("--{$this->boundary}--\r\n"));
return $stream;
}
@@ -84,7 +87,7 @@ class MultipartStream implements StreamInterface
}
}
$element['contents'] = stream_for($element['contents']);
$element['contents'] = Utils::streamFor($element['contents']);
if (empty($element['filename'])) {
$uri = $element['contents']->getMetadata('uri');
@@ -100,9 +103,9 @@ class MultipartStream implements StreamInterface
isset($element['headers']) ? $element['headers'] : []
);
$stream->addStream(stream_for($this->getHeaders($headers)));
$stream->addStream(Utils::streamFor($this->getHeaders($headers)));
$stream->addStream($body);
$stream->addStream(stream_for("\r\n"));
$stream->addStream(Utils::streamFor("\r\n"));
}
/**
@@ -114,9 +117,11 @@ class MultipartStream implements StreamInterface
$disposition = $this->getHeader($headers, 'content-disposition');
if (!$disposition) {
$headers['Content-Disposition'] = ($filename === '0' || $filename)
? sprintf('form-data; name="%s"; filename="%s"',
? sprintf(
'form-data; name="%s"; filename="%s"',
$name,
basename($filename))
basename($filename)
)
: "form-data; name=\"{$name}\"";
}
@@ -131,7 +136,7 @@ class MultipartStream implements StreamInterface
// Set a default Content-Type if one was not supplied
$type = $this->getHeader($headers, 'content-type');
if (!$type && ($filename === '0' || $filename)) {
if ($type = mimetype_from_filename($filename)) {
if ($type = MimeType::fromFilename($filename)) {
$headers['Content-Type'] = $type;
}
}

View File

@@ -1,10 +1,13 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface;
/**
* Stream decorator that prevents a stream from being seeked
* Stream decorator that prevents a stream from being seeked.
*
* @final
*/
class NoSeekStream implements StreamInterface
{

View File

@@ -1,4 +1,5 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface;
@@ -12,6 +13,8 @@ use Psr\Http\Message\StreamInterface;
* returned by the provided callable is buffered internally until drained using
* the read() function of the PumpStream. The provided callable MUST return
* false when there is no more data to read.
*
* @final
*/
class PumpStream implements StreamInterface
{
@@ -31,14 +34,14 @@ class PumpStream implements StreamInterface
private $buffer;
/**
* @param callable $source Source of the stream data. The callable MAY
* accept an integer argument used to control the
* amount of data to return. The callable MUST
* return a string when called, or false on error
* or EOF.
* @param array $options Stream options:
* - metadata: Hash of metadata to use with stream.
* - size: Size of the stream, if known.
* @param callable $source Source of the stream data. The callable MAY
* accept an integer argument used to control the
* amount of data to return. The callable MUST
* return a string when called, or false on error
* or EOF.
* @param array $options Stream options:
* - metadata: Hash of metadata to use with stream.
* - size: Size of the stream, if known.
*/
public function __construct(callable $source, array $options = [])
{
@@ -51,7 +54,7 @@ class PumpStream implements StreamInterface
public function __toString()
{
try {
return copy_to_string($this);
return Utils::copyToString($this);
} catch (\Exception $e) {
return '';
}
@@ -66,6 +69,8 @@ class PumpStream implements StreamInterface
{
$this->tellPos = false;
$this->source = null;
return null;
}
public function getSize()

113
vendor/guzzlehttp/psr7/src/Query.php vendored Normal file
View File

@@ -0,0 +1,113 @@
<?php
namespace GuzzleHttp\Psr7;
final class Query
{
/**
* Parse a query string into an associative array.
*
* If multiple values are found for the same key, the value of that key
* value pair will become an array. This function does not parse nested
* PHP style arrays into an associative array (e.g., `foo[a]=1&foo[b]=2`
* will be parsed into `['foo[a]' => '1', 'foo[b]' => '2'])`.
*
* @param string $str Query string to parse
* @param int|bool $urlEncoding How the query string is encoded
*
* @return array
*/
public static function parse($str, $urlEncoding = true)
{
$result = [];
if ($str === '') {
return $result;
}
if ($urlEncoding === true) {
$decoder = function ($value) {
return rawurldecode(str_replace('+', ' ', $value));
};
} elseif ($urlEncoding === PHP_QUERY_RFC3986) {
$decoder = 'rawurldecode';
} elseif ($urlEncoding === PHP_QUERY_RFC1738) {
$decoder = 'urldecode';
} else {
$decoder = function ($str) {
return $str;
};
}
foreach (explode('&', $str) as $kvp) {
$parts = explode('=', $kvp, 2);
$key = $decoder($parts[0]);
$value = isset($parts[1]) ? $decoder($parts[1]) : null;
if (!isset($result[$key])) {
$result[$key] = $value;
} else {
if (!is_array($result[$key])) {
$result[$key] = [$result[$key]];
}
$result[$key][] = $value;
}
}
return $result;
}
/**
* Build a query string from an array of key value pairs.
*
* This function can use the return value of `parse()` to build a query
* string. This function does not modify the provided keys when an array is
* encountered (like `http_build_query()` would).
*
* @param array $params Query string parameters.
* @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986
* to encode using RFC3986, or PHP_QUERY_RFC1738
* to encode using RFC1738.
*
* @return string
*/
public static function build(array $params, $encoding = PHP_QUERY_RFC3986)
{
if (!$params) {
return '';
}
if ($encoding === false) {
$encoder = function ($str) {
return $str;
};
} elseif ($encoding === PHP_QUERY_RFC3986) {
$encoder = 'rawurlencode';
} elseif ($encoding === PHP_QUERY_RFC1738) {
$encoder = 'urlencode';
} else {
throw new \InvalidArgumentException('Invalid type');
}
$qs = '';
foreach ($params as $k => $v) {
$k = $encoder($k);
if (!is_array($v)) {
$qs .= $k;
if ($v !== null) {
$qs .= '=' . $encoder($v);
}
$qs .= '&';
} else {
foreach ($v as $vv) {
$qs .= $k;
if ($vv !== null) {
$qs .= '=' . $encoder($vv);
}
$qs .= '&';
}
}
}
return $qs ? (string) substr($qs, 0, -1) : '';
}
}

View File

@@ -1,4 +1,5 @@
<?php
namespace GuzzleHttp\Psr7;
use InvalidArgumentException;
@@ -16,7 +17,7 @@ class Request implements RequestInterface
/** @var string */
private $method;
/** @var null|string */
/** @var string|null */
private $requestTarget;
/** @var UriInterface */
@@ -26,7 +27,7 @@ class Request implements RequestInterface
* @param string $method HTTP method
* @param string|UriInterface $uri URI
* @param array $headers Request headers
* @param string|null|resource|StreamInterface $body Request body
* @param string|resource|StreamInterface|null $body Request body
* @param string $version Protocol version
*/
public function __construct(
@@ -36,6 +37,7 @@ class Request implements RequestInterface
$body = null,
$version = '1.1'
) {
$this->assertMethod($method);
if (!($uri instanceof UriInterface)) {
$uri = new Uri($uri);
}
@@ -50,7 +52,7 @@ class Request implements RequestInterface
}
if ($body !== '' && $body !== null) {
$this->stream = stream_for($body);
$this->stream = Utils::streamFor($body);
}
}
@@ -91,6 +93,7 @@ class Request implements RequestInterface
public function withMethod($method)
{
$this->assertMethod($method);
$new = clone $this;
$new->method = strtoupper($method);
return $new;
@@ -139,4 +142,11 @@ class Request implements RequestInterface
// See: http://tools.ietf.org/html/rfc7230#section-5.4
$this->headers = [$header => [$host]] + $this->headers;
}
private function assertMethod($method)
{
if (!is_string($method) || $method === '') {
throw new \InvalidArgumentException('Method must be a non-empty string.');
}
}
}

View File

@@ -1,4 +1,5 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\ResponseInterface;
@@ -82,7 +83,7 @@ class Response implements ResponseInterface
/**
* @param int $status Status code
* @param array $headers Response headers
* @param string|null|resource|StreamInterface $body Response body
* @param string|resource|StreamInterface|null $body Response body
* @param string $version Protocol version
* @param string|null $reason Reason phrase (when empty a default will be used based on the status code)
*/
@@ -93,14 +94,14 @@ class Response implements ResponseInterface
$version = '1.1',
$reason = null
) {
if (filter_var($status, FILTER_VALIDATE_INT) === false) {
throw new \InvalidArgumentException('Status code must be an integer value.');
}
$this->assertStatusCodeIsInteger($status);
$status = (int) $status;
$this->assertStatusCodeRange($status);
$this->statusCode = (int) $status;
$this->statusCode = $status;
if ($body !== '' && $body !== null) {
$this->stream = stream_for($body);
$this->stream = Utils::streamFor($body);
}
$this->setHeaders($headers);
@@ -125,12 +126,30 @@ class Response implements ResponseInterface
public function withStatus($code, $reasonPhrase = '')
{
$this->assertStatusCodeIsInteger($code);
$code = (int) $code;
$this->assertStatusCodeRange($code);
$new = clone $this;
$new->statusCode = (int) $code;
$new->statusCode = $code;
if ($reasonPhrase == '' && isset(self::$phrases[$new->statusCode])) {
$reasonPhrase = self::$phrases[$new->statusCode];
}
$new->reasonPhrase = $reasonPhrase;
$new->reasonPhrase = (string) $reasonPhrase;
return $new;
}
private function assertStatusCodeIsInteger($statusCode)
{
if (filter_var($statusCode, FILTER_VALIDATE_INT) === false) {
throw new \InvalidArgumentException('Status code must be an integer value.');
}
}
private function assertStatusCodeRange($statusCode)
{
if ($statusCode < 100 || $statusCode >= 600) {
throw new \InvalidArgumentException('Status code must be an integer value between 1xx and 5xx.');
}
}
}

View File

@@ -11,6 +11,7 @@ final class Rfc7230
* Note: header delimiter (\r\n) is modified to \r?\n to accept line feed only delimiters for BC reasons.
*
* @link https://github.com/amphp/http/blob/v1.0.1/src/Rfc7230.php#L12-L15
*
* @license https://github.com/amphp/http/blob/v1.0.1/LICENSE
*/
const HEADER_REGEX = "(^([^()<>@,;:\\\"/[\]?={}\x01-\x20\x7F]++):[ \t]*+((?:[ \t]*+[\x21-\x7E\x80-\xFF]++)*+)[ \t]*+\r?\n)m";

View File

@@ -4,9 +4,9 @@ namespace GuzzleHttp\Psr7;
use InvalidArgumentException;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UriInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UploadedFileInterface;
use Psr\Http\Message\UriInterface;
/**
* Server-side HTTP request
@@ -35,7 +35,7 @@ class ServerRequest extends Request implements ServerRequestInterface
private $cookieParams = [];
/**
* @var null|array|object
* @var array|object|null
*/
private $parsedBody;
@@ -58,7 +58,7 @@ class ServerRequest extends Request implements ServerRequestInterface
* @param string $method HTTP method
* @param string|UriInterface $uri URI
* @param array $headers Request headers
* @param string|null|resource|StreamInterface $body Request body
* @param string|resource|StreamInterface|null $body Request body
* @param string $version Protocol version
* @param array $serverParams Typically the $_SERVER superglobal
*/
@@ -79,8 +79,10 @@ class ServerRequest extends Request implements ServerRequestInterface
* Return an UploadedFile instance array.
*
* @param array $files A array which respect $_FILES structure
* @throws InvalidArgumentException for unrecognized values
*
* @return array
*
* @throws InvalidArgumentException for unrecognized values
*/
public static function normalizeFiles(array $files)
{
@@ -109,6 +111,7 @@ class ServerRequest extends Request implements ServerRequestInterface
* delegate to normalizeNestedFileSpec() and return that return value.
*
* @param array $value $_FILES struct
*
* @return array|UploadedFileInterface
*/
private static function createUploadedFileFromSpec(array $value)
@@ -133,6 +136,7 @@ class ServerRequest extends Request implements ServerRequestInterface
* UploadedFileInterface instances.
*
* @param array $files
*
* @return UploadedFileInterface[]
*/
private static function normalizeNestedFileSpec(array $files = [])
@@ -168,7 +172,7 @@ class ServerRequest extends Request implements ServerRequestInterface
$method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
$headers = getallheaders();
$uri = self::getUriFromGlobals();
$body = new LazyOpenStream('php://input', 'r+');
$body = new CachingStream(new LazyOpenStream('php://input', 'r+'));
$protocol = isset($_SERVER['SERVER_PROTOCOL']) ? str_replace('HTTP/', '', $_SERVER['SERVER_PROTOCOL']) : '1.1';
$serverRequest = new ServerRequest($method, $uri, $headers, $body, $protocol, $_SERVER);
@@ -182,7 +186,7 @@ class ServerRequest extends Request implements ServerRequestInterface
private static function extractHostAndPortFromAuthority($authority)
{
$uri = 'http://'.$authority;
$uri = 'http://' . $authority;
$parts = parse_url($uri);
if (false === $parts) {
return [null, null];
@@ -243,7 +247,6 @@ class ServerRequest extends Request implements ServerRequestInterface
return $uri;
}
/**
* {@inheritdoc}
*/

View File

@@ -1,4 +1,5 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface;
@@ -10,6 +11,17 @@ use Psr\Http\Message\StreamInterface;
*/
class Stream implements StreamInterface
{
/**
* Resource modes.
*
* @var string
*
* @see http://php.net/manual/function.fopen.php
* @see http://php.net/manual/en/function.gzopen.php
*/
const READABLE_MODES = '/r|a\+|ab\+|w\+|wb\+|x\+|xb\+|c\+|cb\+/';
const WRITABLE_MODES = '/a|w|r\+|rb\+|rw|x|c/';
private $stream;
private $size;
private $seekable;
@@ -18,22 +30,6 @@ class Stream implements StreamInterface
private $uri;
private $customMetadata;
/** @var array Hash of readable and writable stream types */
private static $readWriteHash = [
'read' => [
'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true,
'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true,
'c+b' => true, 'rt' => true, 'w+t' => true, 'r+t' => true,
'x+t' => true, 'c+t' => true, 'a+' => true, 'rb+' => true,
],
'write' => [
'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true,
'c+' => true, 'wb' => true, 'w+b' => true, 'r+b' => true, 'rb+' => true,
'x+b' => true, 'c+b' => true, 'w+t' => true, 'r+t' => true,
'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true
]
];
/**
* This constructor accepts an associative array of options.
*
@@ -65,8 +61,8 @@ class Stream implements StreamInterface
$this->stream = $stream;
$meta = stream_get_meta_data($this->stream);
$this->seekable = $meta['seekable'];
$this->readable = isset(self::$readWriteHash['read'][$meta['mode']]);
$this->writable = isset(self::$readWriteHash['write'][$meta['mode']]);
$this->readable = (bool)preg_match(self::READABLE_MODES, $meta['mode']);
$this->writable = (bool)preg_match(self::WRITABLE_MODES, $meta['mode']);
$this->uri = $this->getMetadata('uri');
}
@@ -81,8 +77,10 @@ class Stream implements StreamInterface
public function __toString()
{
try {
$this->seek(0);
return (string) stream_get_contents($this->stream);
if ($this->isSeekable()) {
$this->seek(0);
}
return $this->getContents();
} catch (\Exception $e) {
return '';
}
@@ -197,6 +195,8 @@ class Stream implements StreamInterface
public function seek($offset, $whence = SEEK_SET)
{
$whence = (int) $whence;
if (!isset($this->stream)) {
throw new \RuntimeException('Stream is detached');
}

View File

@@ -1,10 +1,12 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface;
/**
* Stream decorator trait
*
* @property StreamInterface stream
*/
trait StreamDecoratorTrait
@@ -52,7 +54,7 @@ trait StreamDecoratorTrait
public function getContents()
{
return copy_to_string($this);
return Utils::copyToString($this);
}
/**
@@ -140,6 +142,7 @@ trait StreamDecoratorTrait
* Implement in subclasses to dynamically create streams when requested.
*
* @return StreamInterface
*
* @throws \BadMethodCallException
*/
protected function createStream()

View File

@@ -1,10 +1,13 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface;
/**
* Converts Guzzle streams into PHP stream resources.
*
* @final
*/
class StreamWrapper
{
@@ -23,6 +26,7 @@ class StreamWrapper
* @param StreamInterface $stream The stream to get a resource for
*
* @return resource
*
* @throws \InvalidArgumentException if stream is not readable or writable
*/
public static function getResource(StreamInterface $stream)

View File

@@ -1,4 +1,5 @@
<?php
namespace GuzzleHttp\Psr7;
use InvalidArgumentException;
@@ -38,7 +39,7 @@ class UploadedFile implements UploadedFileInterface
private $error;
/**
* @var null|string
* @var string|null
*/
private $file;
@@ -59,10 +60,10 @@ class UploadedFile implements UploadedFileInterface
/**
* @param StreamInterface|string|resource $streamOrFile
* @param int $size
* @param int $errorStatus
* @param string|null $clientFilename
* @param string|null $clientMediaType
* @param int $size
* @param int $errorStatus
* @param string|null $clientFilename
* @param string|null $clientMediaType
*/
public function __construct(
$streamOrFile,
@@ -85,6 +86,7 @@ class UploadedFile implements UploadedFileInterface
* Depending on the value set file or stream variable
*
* @param mixed $streamOrFile
*
* @throws InvalidArgumentException
*/
private function setStreamOrFile($streamOrFile)
@@ -104,6 +106,7 @@ class UploadedFile implements UploadedFileInterface
/**
* @param int $error
*
* @throws InvalidArgumentException
*/
private function setError($error)
@@ -125,6 +128,7 @@ class UploadedFile implements UploadedFileInterface
/**
* @param int $size
*
* @throws InvalidArgumentException
*/
private function setSize($size)
@@ -140,7 +144,8 @@ class UploadedFile implements UploadedFileInterface
/**
* @param mixed $param
* @return boolean
*
* @return bool
*/
private function isStringOrNull($param)
{
@@ -149,7 +154,8 @@ class UploadedFile implements UploadedFileInterface
/**
* @param mixed $param
* @return boolean
*
* @return bool
*/
private function isStringNotEmpty($param)
{
@@ -158,6 +164,7 @@ class UploadedFile implements UploadedFileInterface
/**
* @param string|null $clientFilename
*
* @throws InvalidArgumentException
*/
private function setClientFilename($clientFilename)
@@ -173,6 +180,7 @@ class UploadedFile implements UploadedFileInterface
/**
* @param string|null $clientMediaType
*
* @throws InvalidArgumentException
*/
private function setClientMediaType($clientMediaType)
@@ -189,7 +197,7 @@ class UploadedFile implements UploadedFileInterface
/**
* Return true if there is no upload error
*
* @return boolean
* @return bool
*/
private function isOk()
{
@@ -197,7 +205,7 @@ class UploadedFile implements UploadedFileInterface
}
/**
* @return boolean
* @return bool
*/
public function isMoved()
{
@@ -220,6 +228,7 @@ class UploadedFile implements UploadedFileInterface
/**
* {@inheritdoc}
*
* @throws RuntimeException if the upload was not successful.
*/
public function getStream()
@@ -238,11 +247,13 @@ class UploadedFile implements UploadedFileInterface
*
* @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 RuntimeException if the upload was not successful.
*
* @throws RuntimeException if the upload was not successful.
* @throws InvalidArgumentException if the $path specified is invalid.
* @throws RuntimeException on any error during the move operation, or on
* the second or subsequent call to the method.
* @throws RuntimeException on any error during the move operation, or on
* the second or subsequent call to the method.
*/
public function moveTo($targetPath)
{
@@ -259,7 +270,7 @@ class UploadedFile implements UploadedFileInterface
? rename($this->file, $targetPath)
: move_uploaded_file($this->file, $targetPath);
} else {
copy_to_stream(
Utils::copyToStream(
$this->getStream(),
new LazyOpenStream($targetPath, 'w')
);
@@ -288,6 +299,7 @@ class UploadedFile implements UploadedFileInterface
* {@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()
@@ -299,7 +311,7 @@ class UploadedFile implements UploadedFileInterface
* {@inheritdoc}
*
* @return string|null The filename sent by the client or null if none
* was provided.
* was provided.
*/
public function getClientFilename()
{

View File

@@ -1,4 +1,5 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\UriInterface;
@@ -66,7 +67,7 @@ class Uri implements UriInterface
{
// weak type check to also accept null until we can add scalar type hints
if ($uri != '') {
$parts = parse_url($uri);
$parts = self::parse($uri);
if ($parts === false) {
throw new \InvalidArgumentException("Unable to parse URI: $uri");
}
@@ -74,6 +75,49 @@ class Uri implements UriInterface
}
}
/**
* UTF-8 aware \parse_url() replacement.
*
* The internal function produces broken output for non ASCII domain names
* (IDN) when used with locales other than "C".
*
* On the other hand, cURL understands IDN correctly only when UTF-8 locale
* is configured ("C.UTF-8", "en_US.UTF-8", etc.).
*
* @see https://bugs.php.net/bug.php?id=52923
* @see https://www.php.net/manual/en/function.parse-url.php#114817
* @see https://curl.haxx.se/libcurl/c/CURLOPT_URL.html#ENCODING
*
* @param string $url
*
* @return array|false
*/
private static function parse($url)
{
// If IPv6
$prefix = '';
if (preg_match('%^(.*://\[[0-9:a-f]+\])(.*?)$%', $url, $matches)) {
$prefix = $matches[1];
$url = $matches[2];
}
$encodedUrl = preg_replace_callback(
'%[^:/@?&=#]+%usD',
static function ($matches) {
return urlencode($matches[0]);
},
$url
);
$result = parse_url($prefix . $encodedUrl);
if ($result === false) {
return false;
}
return array_map('urldecode', $result);
}
public function __toString()
{
return self::composeComponents(
@@ -166,6 +210,7 @@ class Uri implements UriInterface
* @param UriInterface $uri
*
* @return bool
*
* @see Uri::isNetworkPathReference
* @see Uri::isAbsolutePathReference
* @see Uri::isRelativePathReference
@@ -184,6 +229,7 @@ class Uri implements UriInterface
* @param UriInterface $uri
*
* @return bool
*
* @link https://tools.ietf.org/html/rfc3986#section-4.2
*/
public static function isNetworkPathReference(UriInterface $uri)
@@ -199,6 +245,7 @@ class Uri implements UriInterface
* @param UriInterface $uri
*
* @return bool
*
* @link https://tools.ietf.org/html/rfc3986#section-4.2
*/
public static function isAbsolutePathReference(UriInterface $uri)
@@ -217,6 +264,7 @@ class Uri implements UriInterface
* @param UriInterface $uri
*
* @return bool
*
* @link https://tools.ietf.org/html/rfc3986#section-4.2
*/
public static function isRelativePathReference(UriInterface $uri)
@@ -237,6 +285,7 @@ class Uri implements UriInterface
* @param UriInterface|null $base An optional base URI to compare against
*
* @return bool
*
* @link https://tools.ietf.org/html/rfc3986#section-4.4
*/
public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null)
@@ -357,6 +406,7 @@ class Uri implements UriInterface
* @param array $parts
*
* @return UriInterface
*
* @link http://php.net/manual/en/function.parse-url.php
*
* @throws \InvalidArgumentException If the components do not form a valid URI.
@@ -437,9 +487,9 @@ class Uri implements UriInterface
public function withUserInfo($user, $password = null)
{
$info = $user;
if ($password != '') {
$info .= ':' . $password;
$info = $this->filterUserInfoComponent($user);
if ($password !== null) {
$info .= ':' . $this->filterUserInfoComponent($password);
}
if ($this->userInfo === $info) {
@@ -537,7 +587,9 @@ class Uri implements UriInterface
$this->scheme = isset($parts['scheme'])
? $this->filterScheme($parts['scheme'])
: '';
$this->userInfo = isset($parts['user']) ? $parts['user'] : '';
$this->userInfo = isset($parts['user'])
? $this->filterUserInfoComponent($parts['user'])
: '';
$this->host = isset($parts['host'])
? $this->filterHost($parts['host'])
: '';
@@ -554,7 +606,7 @@ class Uri implements UriInterface
? $this->filterQueryAndFragment($parts['fragment'])
: '';
if (isset($parts['pass'])) {
$this->userInfo .= ':' . $parts['pass'];
$this->userInfo .= ':' . $this->filterUserInfoComponent($parts['pass']);
}
$this->removeDefaultPort();
@@ -573,7 +625,27 @@ class Uri implements UriInterface
throw new \InvalidArgumentException('Scheme must be a string');
}
return strtolower($scheme);
return \strtr($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
}
/**
* @param string $component
*
* @return string
*
* @throws \InvalidArgumentException If the user info is invalid.
*/
private function filterUserInfoComponent($component)
{
if (!is_string($component)) {
throw new \InvalidArgumentException('User info must be a string');
}
return preg_replace_callback(
'/(?:[^%' . self::$charUnreserved . self::$charSubDelims . ']+|%(?![A-Fa-f0-9]{2}))/',
[$this, 'rawurlencodeMatchZero'],
$component
);
}
/**
@@ -589,7 +661,7 @@ class Uri implements UriInterface
throw new \InvalidArgumentException('Host must be a string');
}
return strtolower($host);
return \strtr($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
}
/**
@@ -606,9 +678,9 @@ class Uri implements UriInterface
}
$port = (int) $port;
if (1 > $port || 0xffff < $port) {
if (0 > $port || 0xffff < $port) {
throw new \InvalidArgumentException(
sprintf('Invalid port: %d. Must be between 1 and 65535', $port)
sprintf('Invalid port: %d. Must be between 0 and 65535', $port)
);
}
@@ -618,7 +690,7 @@ class Uri implements UriInterface
/**
* @param UriInterface $uri
* @param array $keys
*
*
* @return array
*/
private static function getFilteredQueryString(UriInterface $uri, array $keys)
@@ -639,7 +711,7 @@ class Uri implements UriInterface
/**
* @param string $key
* @param string|null $value
*
*
* @return string
*/
private static function generateQueryString($key, $value)
@@ -731,7 +803,7 @@ class Uri implements UriInterface
'by adding a leading slash to the path is deprecated since version 1.4 and will throw an exception instead.',
E_USER_DEPRECATED
);
$this->path = '/'. $this->path;
$this->path = '/' . $this->path;
//throw new \InvalidArgumentException('The path of a URI with an authority must start with a slash "/" or be empty');
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\UriInterface;
/**
* Provides methods to determine if a modified URL should be considered cross-origin.
*
* @author Graham Campbell
*/
final class UriComparator
{
/**
* Determines if a modified URL should be considered cross-origin with
* respect to an original URL.
*
* @return bool
*/
public static function isCrossOrigin(UriInterface $original, UriInterface $modified)
{
if (\strcasecmp($original->getHost(), $modified->getHost()) !== 0) {
return true;
}
if ($original->getScheme() !== $modified->getScheme()) {
return true;
}
if (self::computePort($original) !== self::computePort($modified)) {
return true;
}
return false;
}
/**
* @return int
*/
private static function computePort(UriInterface $uri)
{
$port = $uri->getPort();
if (null !== $port) {
return $port;
}
return 'https' === $uri->getScheme() ? 443 : 80;
}
private function __construct()
{
// cannot be instantiated
}
}

View File

@@ -1,4 +1,5 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\UriInterface;
@@ -114,6 +115,7 @@ final class UriNormalizer
* @param int $flags A bitmask of normalizations to apply, see constants
*
* @return UriInterface The normalized URI
*
* @link https://tools.ietf.org/html/rfc3986#section-6.2
*/
public static function normalize(UriInterface $uri, $flags = self::PRESERVING_NORMALIZATIONS)
@@ -170,6 +172,7 @@ final class UriNormalizer
* @param int $normalizations A bitmask of normalizations to apply, see constants
*
* @return bool
*
* @link https://tools.ietf.org/html/rfc3986#section-6.1
*/
public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, $normalizations = self::PRESERVING_NORMALIZATIONS)

View File

@@ -1,4 +1,5 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\UriInterface;
@@ -18,6 +19,7 @@ final class UriResolver
* @param string $path
*
* @return string
*
* @link http://tools.ietf.org/html/rfc3986#section-5.2.4
*/
public static function removeDotSegments($path)
@@ -57,6 +59,7 @@ final class UriResolver
* @param UriInterface $rel Relative URI
*
* @return UriInterface
*
* @link http://tools.ietf.org/html/rfc3986#section-5.2
*/
public static function resolve(UriInterface $base, UriInterface $rel)

428
vendor/guzzlehttp/psr7/src/Utils.php vendored Normal file
View File

@@ -0,0 +1,428 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;
final class Utils
{
/**
* Remove the items given by the keys, case insensitively from the data.
*
* @param iterable<string> $keys
*
* @return array
*/
public static function caselessRemove($keys, array $data)
{
$result = [];
foreach ($keys as &$key) {
$key = strtolower($key);
}
foreach ($data as $k => $v) {
if (!in_array(strtolower($k), $keys)) {
$result[$k] = $v;
}
}
return $result;
}
/**
* Copy the contents of a stream into another stream until the given number
* of bytes have been read.
*
* @param StreamInterface $source Stream to read from
* @param StreamInterface $dest Stream to write to
* @param int $maxLen Maximum number of bytes to read. Pass -1
* to read the entire stream.
*
* @throws \RuntimeException on error.
*/
public static function copyToStream(StreamInterface $source, StreamInterface $dest, $maxLen = -1)
{
$bufferSize = 8192;
if ($maxLen === -1) {
while (!$source->eof()) {
if (!$dest->write($source->read($bufferSize))) {
break;
}
}
} else {
$remaining = $maxLen;
while ($remaining > 0 && !$source->eof()) {
$buf = $source->read(min($bufferSize, $remaining));
$len = strlen($buf);
if (!$len) {
break;
}
$remaining -= $len;
$dest->write($buf);
}
}
}
/**
* Copy the contents of a stream into a string until the given number of
* bytes have been read.
*
* @param StreamInterface $stream Stream to read
* @param int $maxLen Maximum number of bytes to read. Pass -1
* to read the entire stream.
*
* @return string
*
* @throws \RuntimeException on error.
*/
public static function copyToString(StreamInterface $stream, $maxLen = -1)
{
$buffer = '';
if ($maxLen === -1) {
while (!$stream->eof()) {
$buf = $stream->read(1048576);
// Using a loose equality here to match on '' and false.
if ($buf == null) {
break;
}
$buffer .= $buf;
}
return $buffer;
}
$len = 0;
while (!$stream->eof() && $len < $maxLen) {
$buf = $stream->read($maxLen - $len);
// Using a loose equality here to match on '' and false.
if ($buf == null) {
break;
}
$buffer .= $buf;
$len = strlen($buffer);
}
return $buffer;
}
/**
* Calculate a hash of a stream.
*
* This method reads the entire stream to calculate a rolling hash, based
* on PHP's `hash_init` functions.
*
* @param StreamInterface $stream Stream to calculate the hash for
* @param string $algo Hash algorithm (e.g. md5, crc32, etc)
* @param bool $rawOutput Whether or not to use raw output
*
* @return string Returns the hash of the stream
*
* @throws \RuntimeException on error.
*/
public static function hash(StreamInterface $stream, $algo, $rawOutput = false)
{
$pos = $stream->tell();
if ($pos > 0) {
$stream->rewind();
}
$ctx = hash_init($algo);
while (!$stream->eof()) {
hash_update($ctx, $stream->read(1048576));
}
$out = hash_final($ctx, (bool) $rawOutput);
$stream->seek($pos);
return $out;
}
/**
* Clone and modify a request with the given changes.
*
* This method is useful for reducing the number of clones needed to mutate
* a message.
*
* The changes can be one of:
* - method: (string) Changes the HTTP method.
* - set_headers: (array) Sets the given headers.
* - remove_headers: (array) Remove the given headers.
* - body: (mixed) Sets the given body.
* - uri: (UriInterface) Set the URI.
* - query: (string) Set the query string value of the URI.
* - version: (string) Set the protocol version.
*
* @param RequestInterface $request Request to clone and modify.
* @param array $changes Changes to apply.
*
* @return RequestInterface
*/
public static function modifyRequest(RequestInterface $request, array $changes)
{
if (!$changes) {
return $request;
}
$headers = $request->getHeaders();
if (!isset($changes['uri'])) {
$uri = $request->getUri();
} else {
// Remove the host header if one is on the URI
if ($host = $changes['uri']->getHost()) {
$changes['set_headers']['Host'] = $host;
if ($port = $changes['uri']->getPort()) {
$standardPorts = ['http' => 80, 'https' => 443];
$scheme = $changes['uri']->getScheme();
if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) {
$changes['set_headers']['Host'] .= ':' . $port;
}
}
}
$uri = $changes['uri'];
}
if (!empty($changes['remove_headers'])) {
$headers = self::caselessRemove($changes['remove_headers'], $headers);
}
if (!empty($changes['set_headers'])) {
$headers = self::caselessRemove(array_keys($changes['set_headers']), $headers);
$headers = $changes['set_headers'] + $headers;
}
if (isset($changes['query'])) {
$uri = $uri->withQuery($changes['query']);
}
if ($request instanceof ServerRequestInterface) {
$new = (new ServerRequest(
isset($changes['method']) ? $changes['method'] : $request->getMethod(),
$uri,
$headers,
isset($changes['body']) ? $changes['body'] : $request->getBody(),
isset($changes['version'])
? $changes['version']
: $request->getProtocolVersion(),
$request->getServerParams()
))
->withParsedBody($request->getParsedBody())
->withQueryParams($request->getQueryParams())
->withCookieParams($request->getCookieParams())
->withUploadedFiles($request->getUploadedFiles());
foreach ($request->getAttributes() as $key => $value) {
$new = $new->withAttribute($key, $value);
}
return $new;
}
return new Request(
isset($changes['method']) ? $changes['method'] : $request->getMethod(),
$uri,
$headers,
isset($changes['body']) ? $changes['body'] : $request->getBody(),
isset($changes['version'])
? $changes['version']
: $request->getProtocolVersion()
);
}
/**
* Read a line from the stream up to the maximum allowed buffer length.
*
* @param StreamInterface $stream Stream to read from
* @param int|null $maxLength Maximum buffer length
*
* @return string
*/
public static function readLine(StreamInterface $stream, $maxLength = null)
{
$buffer = '';
$size = 0;
while (!$stream->eof()) {
// Using a loose equality here to match on '' and false.
if (null == ($byte = $stream->read(1))) {
return $buffer;
}
$buffer .= $byte;
// Break when a new line is found or the max length - 1 is reached
if ($byte === "\n" || ++$size === $maxLength - 1) {
break;
}
}
return $buffer;
}
/**
* Create a new stream based on the input type.
*
* Options is an associative array that can contain the following keys:
* - metadata: Array of custom metadata.
* - size: Size of the stream.
*
* This method accepts the following `$resource` types:
* - `Psr\Http\Message\StreamInterface`: Returns the value as-is.
* - `string`: Creates a stream object that uses the given string as the contents.
* - `resource`: Creates a stream object that wraps the given PHP stream resource.
* - `Iterator`: If the provided value implements `Iterator`, then a read-only
* stream object will be created that wraps the given iterable. Each time the
* stream is read from, data from the iterator will fill a buffer and will be
* continuously called until the buffer is equal to the requested read size.
* Subsequent read calls will first read from the buffer and then call `next`
* on the underlying iterator until it is exhausted.
* - `object` with `__toString()`: If the object has the `__toString()` method,
* the object will be cast to a string and then a stream will be returned that
* uses the string value.
* - `NULL`: When `null` is passed, an empty stream object is returned.
* - `callable` When a callable is passed, a read-only stream object will be
* created that invokes the given callable. The callable is invoked with the
* number of suggested bytes to read. The callable can return any number of
* bytes, but MUST return `false` when there is no more data to return. The
* stream object that wraps the callable will invoke the callable until the
* number of requested bytes are available. Any additional bytes will be
* buffered and used in subsequent reads.
*
* @param resource|string|int|float|bool|StreamInterface|callable|\Iterator|null $resource Entity body data
* @param array $options Additional options
*
* @return StreamInterface
*
* @throws \InvalidArgumentException if the $resource arg is not valid.
*/
public static function streamFor($resource = '', array $options = [])
{
if (is_scalar($resource)) {
$stream = self::tryFopen('php://temp', 'r+');
if ($resource !== '') {
fwrite($stream, $resource);
fseek($stream, 0);
}
return new Stream($stream, $options);
}
switch (gettype($resource)) {
case 'resource':
/*
* The 'php://input' is a special stream with quirks and inconsistencies.
* We avoid using that stream by reading it into php://temp
*/
$metaData = \stream_get_meta_data($resource);
if (isset($metaData['uri']) && $metaData['uri'] === 'php://input') {
$stream = self::tryFopen('php://temp', 'w+');
fwrite($stream, stream_get_contents($resource));
fseek($stream, 0);
$resource = $stream;
}
return new Stream($resource, $options);
case 'object':
if ($resource instanceof StreamInterface) {
return $resource;
} elseif ($resource instanceof \Iterator) {
return new PumpStream(function () use ($resource) {
if (!$resource->valid()) {
return false;
}
$result = $resource->current();
$resource->next();
return $result;
}, $options);
} elseif (method_exists($resource, '__toString')) {
return Utils::streamFor((string) $resource, $options);
}
break;
case 'NULL':
return new Stream(self::tryFopen('php://temp', 'r+'), $options);
}
if (is_callable($resource)) {
return new PumpStream($resource, $options);
}
throw new \InvalidArgumentException('Invalid resource type: ' . gettype($resource));
}
/**
* Safely opens a PHP stream resource using a filename.
*
* When fopen fails, PHP normally raises a warning. This function adds an
* error handler that checks for errors and throws an exception instead.
*
* @param string $filename File to open
* @param string $mode Mode used to open the file
*
* @return resource
*
* @throws \RuntimeException if the file cannot be opened
*/
public static function tryFopen($filename, $mode)
{
$ex = null;
set_error_handler(function () use ($filename, $mode, &$ex) {
$ex = new \RuntimeException(sprintf(
'Unable to open "%s" using mode "%s": %s',
$filename,
$mode,
func_get_args()[1]
));
return true;
});
try {
$handle = fopen($filename, $mode);
} catch (\Throwable $e) {
$ex = new \RuntimeException(sprintf(
'Unable to open "%s" using mode "%s": %s',
$filename,
$mode,
$e->getMessage()
), 0, $e);
}
restore_error_handler();
if ($ex) {
/** @var $ex \RuntimeException */
throw $ex;
}
return $handle;
}
/**
* Returns a UriInterface for the given value.
*
* This function accepts a string or UriInterface and returns a
* UriInterface for the given value. If the value is already a
* UriInterface, it is returned as-is.
*
* @param string|UriInterface $uri
*
* @return UriInterface
*
* @throws \InvalidArgumentException
*/
public static function uriFor($uri)
{
if ($uri instanceof UriInterface) {
return $uri;
}
if (is_string($uri)) {
return new Uri($uri);
}
throw new \InvalidArgumentException('URI must be a string or UriInterface');
}
}

View File

@@ -1,10 +1,9 @@
<?php
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;
@@ -14,52 +13,32 @@ use Psr\Http\Message\UriInterface;
* @param MessageInterface $message Message to convert to a string.
*
* @return string
*
* @deprecated str will be removed in guzzlehttp/psr7:2.0. Use Message::toString instead.
*/
function str(MessageInterface $message)
{
if ($message instanceof RequestInterface) {
$msg = trim($message->getMethod() . ' '
. $message->getRequestTarget())
. ' HTTP/' . $message->getProtocolVersion();
if (!$message->hasHeader('host')) {
$msg .= "\r\nHost: " . $message->getUri()->getHost();
}
} elseif ($message instanceof ResponseInterface) {
$msg = 'HTTP/' . $message->getProtocolVersion() . ' '
. $message->getStatusCode() . ' '
. $message->getReasonPhrase();
} else {
throw new \InvalidArgumentException('Unknown message type');
}
foreach ($message->getHeaders() as $name => $values) {
$msg .= "\r\n{$name}: " . implode(', ', $values);
}
return "{$msg}\r\n\r\n" . $message->getBody();
return Message::toString($message);
}
/**
* Returns a UriInterface for the given value.
*
* This function accepts a string or {@see Psr\Http\Message\UriInterface} and
* returns a UriInterface for the given value. If the value is already a
* `UriInterface`, it is returned as-is.
* This function accepts a string or UriInterface and returns a
* UriInterface for the given value. If the value is already a
* UriInterface, it is returned as-is.
*
* @param string|UriInterface $uri
*
* @return UriInterface
*
* @throws \InvalidArgumentException
*
* @deprecated uri_for will be removed in guzzlehttp/psr7:2.0. Use Utils::uriFor instead.
*/
function uri_for($uri)
{
if ($uri instanceof UriInterface) {
return $uri;
} elseif (is_string($uri)) {
return new Uri($uri);
}
throw new \InvalidArgumentException('URI must be a string or UriInterface');
return Utils::uriFor($uri);
}
/**
@@ -69,86 +48,57 @@ function uri_for($uri)
* - metadata: Array of custom metadata.
* - size: Size of the stream.
*
* @param resource|string|null|int|float|bool|StreamInterface|callable|\Iterator $resource Entity body data
* This method accepts the following `$resource` types:
* - `Psr\Http\Message\StreamInterface`: Returns the value as-is.
* - `string`: Creates a stream object that uses the given string as the contents.
* - `resource`: Creates a stream object that wraps the given PHP stream resource.
* - `Iterator`: If the provided value implements `Iterator`, then a read-only
* stream object will be created that wraps the given iterable. Each time the
* stream is read from, data from the iterator will fill a buffer and will be
* continuously called until the buffer is equal to the requested read size.
* Subsequent read calls will first read from the buffer and then call `next`
* on the underlying iterator until it is exhausted.
* - `object` with `__toString()`: If the object has the `__toString()` method,
* the object will be cast to a string and then a stream will be returned that
* uses the string value.
* - `NULL`: When `null` is passed, an empty stream object is returned.
* - `callable` When a callable is passed, a read-only stream object will be
* created that invokes the given callable. The callable is invoked with the
* number of suggested bytes to read. The callable can return any number of
* bytes, but MUST return `false` when there is no more data to return. The
* stream object that wraps the callable will invoke the callable until the
* number of requested bytes are available. Any additional bytes will be
* buffered and used in subsequent reads.
*
* @param resource|string|int|float|bool|StreamInterface|callable|\Iterator|null $resource Entity body data
* @param array $options Additional options
*
* @return StreamInterface
*
* @throws \InvalidArgumentException if the $resource arg is not valid.
*
* @deprecated stream_for will be removed in guzzlehttp/psr7:2.0. Use Utils::streamFor instead.
*/
function stream_for($resource = '', array $options = [])
{
if (is_scalar($resource)) {
$stream = fopen('php://temp', 'r+');
if ($resource !== '') {
fwrite($stream, $resource);
fseek($stream, 0);
}
return new Stream($stream, $options);
}
switch (gettype($resource)) {
case 'resource':
return new Stream($resource, $options);
case 'object':
if ($resource instanceof StreamInterface) {
return $resource;
} elseif ($resource instanceof \Iterator) {
return new PumpStream(function () use ($resource) {
if (!$resource->valid()) {
return false;
}
$result = $resource->current();
$resource->next();
return $result;
}, $options);
} elseif (method_exists($resource, '__toString')) {
return stream_for((string) $resource, $options);
}
break;
case 'NULL':
return new Stream(fopen('php://temp', 'r+'), $options);
}
if (is_callable($resource)) {
return new PumpStream($resource, $options);
}
throw new \InvalidArgumentException('Invalid resource type: ' . gettype($resource));
return Utils::streamFor($resource, $options);
}
/**
* Parse an array of header values containing ";" separated data into an
* array of associative arrays representing the header key value pair
* data of the header. When a parameter does not contain a value, but just
* array of associative arrays representing the header key value pair data
* of the header. When a parameter does not contain a value, but just
* contains a key, this function will inject a key with a '' string value.
*
* @param string|array $header Header to parse into components.
*
* @return array Returns the parsed header values.
*
* @deprecated parse_header will be removed in guzzlehttp/psr7:2.0. Use Header::parse instead.
*/
function parse_header($header)
{
static $trimmed = "\"' \n\t\r";
$params = $matches = [];
foreach (normalize_header($header) as $val) {
$part = [];
foreach (preg_split('/;(?=([^"]*"[^"]*")*[^"]*$)/', $val) as $kvp) {
if (preg_match_all('/<[^>]+>|[^=]+/', $kvp, $matches)) {
$m = $matches[0];
if (isset($m[1])) {
$part[trim($m[0], $trimmed)] = trim($m[1], $trimmed);
} else {
$part[] = trim($m[0], $trimmed);
}
}
}
if ($part) {
$params[] = $part;
}
}
return $params;
return Header::parse($header);
}
/**
@@ -158,32 +108,20 @@ function parse_header($header)
* @param string|array $header Header to normalize.
*
* @return array Returns the normalized header field values.
*
* @deprecated normalize_header will be removed in guzzlehttp/psr7:2.0. Use Header::normalize instead.
*/
function normalize_header($header)
{
if (!is_array($header)) {
return array_map('trim', explode(',', $header));
}
$result = [];
foreach ($header as $value) {
foreach ((array) $value as $v) {
if (strpos($v, ',') === false) {
$result[] = $v;
continue;
}
foreach (preg_split('/,(?=([^"]*"[^"]*")*[^"]*$)/', $v) as $vv) {
$result[] = trim($vv);
}
}
}
return $result;
return Header::normalize($header);
}
/**
* Clone and modify a request with the given changes.
*
* This method is useful for reducing the number of clones needed to mutate a
* message.
*
* The changes can be one of:
* - method: (string) Changes the HTTP method.
* - set_headers: (array) Sets the given headers.
@@ -197,72 +135,12 @@ function normalize_header($header)
* @param array $changes Changes to apply.
*
* @return RequestInterface
*
* @deprecated modify_request will be removed in guzzlehttp/psr7:2.0. Use Utils::modifyRequest instead.
*/
function modify_request(RequestInterface $request, array $changes)
{
if (!$changes) {
return $request;
}
$headers = $request->getHeaders();
if (!isset($changes['uri'])) {
$uri = $request->getUri();
} else {
// Remove the host header if one is on the URI
if ($host = $changes['uri']->getHost()) {
$changes['set_headers']['Host'] = $host;
if ($port = $changes['uri']->getPort()) {
$standardPorts = ['http' => 80, 'https' => 443];
$scheme = $changes['uri']->getScheme();
if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) {
$changes['set_headers']['Host'] .= ':'.$port;
}
}
}
$uri = $changes['uri'];
}
if (!empty($changes['remove_headers'])) {
$headers = _caseless_remove($changes['remove_headers'], $headers);
}
if (!empty($changes['set_headers'])) {
$headers = _caseless_remove(array_keys($changes['set_headers']), $headers);
$headers = $changes['set_headers'] + $headers;
}
if (isset($changes['query'])) {
$uri = $uri->withQuery($changes['query']);
}
if ($request instanceof ServerRequestInterface) {
return (new ServerRequest(
isset($changes['method']) ? $changes['method'] : $request->getMethod(),
$uri,
$headers,
isset($changes['body']) ? $changes['body'] : $request->getBody(),
isset($changes['version'])
? $changes['version']
: $request->getProtocolVersion(),
$request->getServerParams()
))
->withParsedBody($request->getParsedBody())
->withQueryParams($request->getQueryParams())
->withCookieParams($request->getCookieParams())
->withUploadedFiles($request->getUploadedFiles());
}
return new Request(
isset($changes['method']) ? $changes['method'] : $request->getMethod(),
$uri,
$headers,
isset($changes['body']) ? $changes['body'] : $request->getBody(),
isset($changes['version'])
? $changes['version']
: $request->getProtocolVersion()
);
return Utils::modifyRequest($request, $changes);
}
/**
@@ -274,14 +152,12 @@ function modify_request(RequestInterface $request, array $changes)
* @param MessageInterface $message Message to rewind
*
* @throws \RuntimeException
*
* @deprecated rewind_body will be removed in guzzlehttp/psr7:2.0. Use Message::rewindBody instead.
*/
function rewind_body(MessageInterface $message)
{
$body = $message->getBody();
if ($body->tell()) {
$body->rewind();
}
Message::rewindBody($message);
}
/**
@@ -294,29 +170,14 @@ function rewind_body(MessageInterface $message)
* @param string $mode Mode used to open the file
*
* @return resource
*
* @throws \RuntimeException if the file cannot be opened
*
* @deprecated try_fopen will be removed in guzzlehttp/psr7:2.0. Use Utils::tryFopen instead.
*/
function try_fopen($filename, $mode)
{
$ex = null;
set_error_handler(function () use ($filename, $mode, &$ex) {
$ex = new \RuntimeException(sprintf(
'Unable to open %s using mode %s: %s',
$filename,
$mode,
func_get_args()[1]
));
});
$handle = fopen($filename, $mode);
restore_error_handler();
if ($ex) {
/** @var $ex \RuntimeException */
throw $ex;
}
return $handle;
return Utils::tryFopen($filename, $mode);
}
/**
@@ -326,37 +187,16 @@ function try_fopen($filename, $mode)
* @param StreamInterface $stream Stream to read
* @param int $maxLen Maximum number of bytes to read. Pass -1
* to read the entire stream.
*
* @return string
*
* @throws \RuntimeException on error.
*
* @deprecated copy_to_string will be removed in guzzlehttp/psr7:2.0. Use Utils::copyToString instead.
*/
function copy_to_string(StreamInterface $stream, $maxLen = -1)
{
$buffer = '';
if ($maxLen === -1) {
while (!$stream->eof()) {
$buf = $stream->read(1048576);
// Using a loose equality here to match on '' and false.
if ($buf == null) {
break;
}
$buffer .= $buf;
}
return $buffer;
}
$len = 0;
while (!$stream->eof() && $len < $maxLen) {
$buf = $stream->read($maxLen - $len);
// Using a loose equality here to match on '' and false.
if ($buf == null) {
break;
}
$buffer .= $buf;
$len = strlen($buffer);
}
return $buffer;
return Utils::copyToString($stream, $maxLen);
}
/**
@@ -369,92 +209,48 @@ function copy_to_string(StreamInterface $stream, $maxLen = -1)
* to read the entire stream.
*
* @throws \RuntimeException on error.
*
* @deprecated copy_to_stream will be removed in guzzlehttp/psr7:2.0. Use Utils::copyToStream instead.
*/
function copy_to_stream(
StreamInterface $source,
StreamInterface $dest,
$maxLen = -1
) {
$bufferSize = 8192;
if ($maxLen === -1) {
while (!$source->eof()) {
if (!$dest->write($source->read($bufferSize))) {
break;
}
}
} else {
$remaining = $maxLen;
while ($remaining > 0 && !$source->eof()) {
$buf = $source->read(min($bufferSize, $remaining));
$len = strlen($buf);
if (!$len) {
break;
}
$remaining -= $len;
$dest->write($buf);
}
}
function copy_to_stream(StreamInterface $source, StreamInterface $dest, $maxLen = -1)
{
return Utils::copyToStream($source, $dest, $maxLen);
}
/**
* Calculate a hash of a Stream
* Calculate a hash of a stream.
*
* This method reads the entire stream to calculate a rolling hash, based on
* PHP's `hash_init` functions.
*
* @param StreamInterface $stream Stream to calculate the hash for
* @param string $algo Hash algorithm (e.g. md5, crc32, etc)
* @param bool $rawOutput Whether or not to use raw output
*
* @return string Returns the hash of the stream
*
* @throws \RuntimeException on error.
*
* @deprecated hash will be removed in guzzlehttp/psr7:2.0. Use Utils::hash instead.
*/
function hash(
StreamInterface $stream,
$algo,
$rawOutput = false
) {
$pos = $stream->tell();
if ($pos > 0) {
$stream->rewind();
}
$ctx = hash_init($algo);
while (!$stream->eof()) {
hash_update($ctx, $stream->read(1048576));
}
$out = hash_final($ctx, (bool) $rawOutput);
$stream->seek($pos);
return $out;
function hash(StreamInterface $stream, $algo, $rawOutput = false)
{
return Utils::hash($stream, $algo, $rawOutput);
}
/**
* Read a line from the stream up to the maximum allowed buffer length
* Read a line from the stream up to the maximum allowed buffer length.
*
* @param StreamInterface $stream Stream to read from
* @param int $maxLength Maximum buffer length
* @param int|null $maxLength Maximum buffer length
*
* @return string
*
* @deprecated readline will be removed in guzzlehttp/psr7:2.0. Use Utils::readLine instead.
*/
function readline(StreamInterface $stream, $maxLength = null)
{
$buffer = '';
$size = 0;
while (!$stream->eof()) {
// Using a loose equality here to match on '' and false.
if (null == ($byte = $stream->read(1))) {
return $buffer;
}
$buffer .= $byte;
// Break when a new line is found or the max length - 1 is reached
if ($byte === "\n" || ++$size === $maxLength - 1) {
break;
}
}
return $buffer;
return Utils::readLine($stream, $maxLength);
}
/**
@@ -463,26 +259,12 @@ function readline(StreamInterface $stream, $maxLength = null)
* @param string $message Request message string.
*
* @return Request
*
* @deprecated parse_request will be removed in guzzlehttp/psr7:2.0. Use Message::parseRequest instead.
*/
function parse_request($message)
{
$data = _parse_message($message);
$matches = [];
if (!preg_match('/^[\S]+\s+([a-zA-Z]+:\/\/|\/).*/', $data['start-line'], $matches)) {
throw new \InvalidArgumentException('Invalid request string');
}
$parts = explode(' ', $data['start-line'], 3);
$version = isset($parts[2]) ? explode('/', $parts[2])[1] : '1.1';
$request = new Request(
$parts[0],
$matches[1] === '/' ? _parse_request_uri($parts[1], $data['headers']) : $parts[1],
$data['headers'],
$data['body'],
$version
);
return $matches[1] === '/' ? $request : $request->withRequestTarget($parts[1]);
return Message::parseRequest($message);
}
/**
@@ -491,139 +273,67 @@ function parse_request($message)
* @param string $message Response message string.
*
* @return Response
*
* @deprecated parse_response will be removed in guzzlehttp/psr7:2.0. Use Message::parseResponse instead.
*/
function parse_response($message)
{
$data = _parse_message($message);
// According to https://tools.ietf.org/html/rfc7230#section-3.1.2 the space
// between status-code and reason-phrase is required. But browsers accept
// responses without space and reason as well.
if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) {
throw new \InvalidArgumentException('Invalid response string: ' . $data['start-line']);
}
$parts = explode(' ', $data['start-line'], 3);
return new Response(
$parts[1],
$data['headers'],
$data['body'],
explode('/', $parts[0])[1],
isset($parts[2]) ? $parts[2] : null
);
return Message::parseResponse($message);
}
/**
* Parse a query string into an associative array.
*
* If multiple values are found for the same key, the value of that key
* value pair will become an array. This function does not parse nested
* PHP style arrays into an associative array (e.g., foo[a]=1&foo[b]=2 will
* be parsed into ['foo[a]' => '1', 'foo[b]' => '2']).
* If multiple values are found for the same key, the value of that key value
* pair will become an array. This function does not parse nested PHP style
* arrays into an associative array (e.g., `foo[a]=1&foo[b]=2` will be parsed
* into `['foo[a]' => '1', 'foo[b]' => '2'])`.
*
* @param string $str Query string to parse
* @param int|bool $urlEncoding How the query string is encoded
*
* @return array
*
* @deprecated parse_query will be removed in guzzlehttp/psr7:2.0. Use Query::parse instead.
*/
function parse_query($str, $urlEncoding = true)
{
$result = [];
if ($str === '') {
return $result;
}
if ($urlEncoding === true) {
$decoder = function ($value) {
return rawurldecode(str_replace('+', ' ', $value));
};
} elseif ($urlEncoding === PHP_QUERY_RFC3986) {
$decoder = 'rawurldecode';
} elseif ($urlEncoding === PHP_QUERY_RFC1738) {
$decoder = 'urldecode';
} else {
$decoder = function ($str) { return $str; };
}
foreach (explode('&', $str) as $kvp) {
$parts = explode('=', $kvp, 2);
$key = $decoder($parts[0]);
$value = isset($parts[1]) ? $decoder($parts[1]) : null;
if (!isset($result[$key])) {
$result[$key] = $value;
} else {
if (!is_array($result[$key])) {
$result[$key] = [$result[$key]];
}
$result[$key][] = $value;
}
}
return $result;
return Query::parse($str, $urlEncoding);
}
/**
* Build a query string from an array of key value pairs.
*
* This function can use the return value of parse_query() to build a query
* This function can use the return value of `parse_query()` to build a query
* string. This function does not modify the provided keys when an array is
* encountered (like http_build_query would).
* encountered (like `http_build_query()` would).
*
* @param array $params Query string parameters.
* @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986
* to encode using RFC3986, or PHP_QUERY_RFC1738
* to encode using RFC1738.
*
* @return string
*
* @deprecated build_query will be removed in guzzlehttp/psr7:2.0. Use Query::build instead.
*/
function build_query(array $params, $encoding = PHP_QUERY_RFC3986)
{
if (!$params) {
return '';
}
if ($encoding === false) {
$encoder = function ($str) { return $str; };
} elseif ($encoding === PHP_QUERY_RFC3986) {
$encoder = 'rawurlencode';
} elseif ($encoding === PHP_QUERY_RFC1738) {
$encoder = 'urlencode';
} else {
throw new \InvalidArgumentException('Invalid type');
}
$qs = '';
foreach ($params as $k => $v) {
$k = $encoder($k);
if (!is_array($v)) {
$qs .= $k;
if ($v !== null) {
$qs .= '=' . $encoder($v);
}
$qs .= '&';
} else {
foreach ($v as $vv) {
$qs .= $k;
if ($vv !== null) {
$qs .= '=' . $encoder($vv);
}
$qs .= '&';
}
}
}
return $qs ? (string) substr($qs, 0, -1) : '';
return Query::build($params, $encoding);
}
/**
* Determines the mimetype of a file by looking at its extension.
*
* @param $filename
* @param string $filename
*
* @return null|string
* @return string|null
*
* @deprecated mimetype_from_filename will be removed in guzzlehttp/psr7:2.0. Use MimeType::fromFilename instead.
*/
function mimetype_from_filename($filename)
{
return mimetype_from_extension(pathinfo($filename, PATHINFO_EXTENSION));
return MimeType::fromFilename($filename);
}
/**
@@ -632,118 +342,13 @@ function mimetype_from_filename($filename)
* @param $extension string The file extension.
*
* @return string|null
*
* @link http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types
* @deprecated mimetype_from_extension will be removed in guzzlehttp/psr7:2.0. Use MimeType::fromExtension instead.
*/
function mimetype_from_extension($extension)
{
static $mimetypes = [
'3gp' => 'video/3gpp',
'7z' => 'application/x-7z-compressed',
'aac' => 'audio/x-aac',
'ai' => 'application/postscript',
'aif' => 'audio/x-aiff',
'asc' => 'text/plain',
'asf' => 'video/x-ms-asf',
'atom' => 'application/atom+xml',
'avi' => 'video/x-msvideo',
'bmp' => 'image/bmp',
'bz2' => 'application/x-bzip2',
'cer' => 'application/pkix-cert',
'crl' => 'application/pkix-crl',
'crt' => 'application/x-x509-ca-cert',
'css' => 'text/css',
'csv' => 'text/csv',
'cu' => 'application/cu-seeme',
'deb' => 'application/x-debian-package',
'doc' => 'application/msword',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'dvi' => 'application/x-dvi',
'eot' => 'application/vnd.ms-fontobject',
'eps' => 'application/postscript',
'epub' => 'application/epub+zip',
'etx' => 'text/x-setext',
'flac' => 'audio/flac',
'flv' => 'video/x-flv',
'gif' => 'image/gif',
'gz' => 'application/gzip',
'htm' => 'text/html',
'html' => 'text/html',
'ico' => 'image/x-icon',
'ics' => 'text/calendar',
'ini' => 'text/plain',
'iso' => 'application/x-iso9660-image',
'jar' => 'application/java-archive',
'jpe' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'js' => 'text/javascript',
'json' => 'application/json',
'latex' => 'application/x-latex',
'log' => 'text/plain',
'm4a' => 'audio/mp4',
'm4v' => 'video/mp4',
'mid' => 'audio/midi',
'midi' => 'audio/midi',
'mov' => 'video/quicktime',
'mkv' => 'video/x-matroska',
'mp3' => 'audio/mpeg',
'mp4' => 'video/mp4',
'mp4a' => 'audio/mp4',
'mp4v' => 'video/mp4',
'mpe' => 'video/mpeg',
'mpeg' => 'video/mpeg',
'mpg' => 'video/mpeg',
'mpg4' => 'video/mp4',
'oga' => 'audio/ogg',
'ogg' => 'audio/ogg',
'ogv' => 'video/ogg',
'ogx' => 'application/ogg',
'pbm' => 'image/x-portable-bitmap',
'pdf' => 'application/pdf',
'pgm' => 'image/x-portable-graymap',
'png' => 'image/png',
'pnm' => 'image/x-portable-anymap',
'ppm' => 'image/x-portable-pixmap',
'ppt' => 'application/vnd.ms-powerpoint',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'ps' => 'application/postscript',
'qt' => 'video/quicktime',
'rar' => 'application/x-rar-compressed',
'ras' => 'image/x-cmu-raster',
'rss' => 'application/rss+xml',
'rtf' => 'application/rtf',
'sgm' => 'text/sgml',
'sgml' => 'text/sgml',
'svg' => 'image/svg+xml',
'swf' => 'application/x-shockwave-flash',
'tar' => 'application/x-tar',
'tif' => 'image/tiff',
'tiff' => 'image/tiff',
'torrent' => 'application/x-bittorrent',
'ttf' => 'application/x-font-ttf',
'txt' => 'text/plain',
'wav' => 'audio/x-wav',
'webm' => 'video/webm',
'wma' => 'audio/x-ms-wma',
'wmv' => 'video/x-ms-wmv',
'woff' => 'application/x-font-woff',
'wsdl' => 'application/wsdl+xml',
'xbm' => 'image/x-xbitmap',
'xls' => 'application/vnd.ms-excel',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'xml' => 'application/xml',
'xpm' => 'image/x-xpixmap',
'xwd' => 'image/x-xwindowdump',
'yaml' => 'text/yaml',
'yml' => 'text/yaml',
'zip' => 'application/zip',
];
$extension = strtolower($extension);
return isset($mimetypes[$extension])
? $mimetypes[$extension]
: null;
return MimeType::fromExtension($extension);
}
/**
@@ -756,61 +361,14 @@ function mimetype_from_extension($extension)
* @param string $message HTTP request or response to parse.
*
* @return array
*
* @internal
*
* @deprecated _parse_message will be removed in guzzlehttp/psr7:2.0. Use Message::parseMessage instead.
*/
function _parse_message($message)
{
if (!$message) {
throw new \InvalidArgumentException('Invalid message');
}
$message = ltrim($message, "\r\n");
$messageParts = preg_split("/\r?\n\r?\n/", $message, 2);
if ($messageParts === false || count($messageParts) !== 2) {
throw new \InvalidArgumentException('Invalid message: Missing header delimiter');
}
list($rawHeaders, $body) = $messageParts;
$rawHeaders .= "\r\n"; // Put back the delimiter we split previously
$headerParts = preg_split("/\r?\n/", $rawHeaders, 2);
if ($headerParts === false || count($headerParts) !== 2) {
throw new \InvalidArgumentException('Invalid message: Missing status line');
}
list($startLine, $rawHeaders) = $headerParts;
if (preg_match("/(?:^HTTP\/|^[A-Z]+ \S+ HTTP\/)(\d+(?:\.\d+)?)/i", $startLine, $matches) && $matches[1] === '1.0') {
// Header folding is deprecated for HTTP/1.1, but allowed in HTTP/1.0
$rawHeaders = preg_replace(Rfc7230::HEADER_FOLD_REGEX, ' ', $rawHeaders);
}
/** @var array[] $headerLines */
$count = preg_match_all(Rfc7230::HEADER_REGEX, $rawHeaders, $headerLines, PREG_SET_ORDER);
// If these aren't the same, then one line didn't match and there's an invalid header.
if ($count !== substr_count($rawHeaders, "\n")) {
// Folding is deprecated, see https://tools.ietf.org/html/rfc7230#section-3.2.4
if (preg_match(Rfc7230::HEADER_FOLD_REGEX, $rawHeaders)) {
throw new \InvalidArgumentException('Invalid header syntax: Obsolete line folding');
}
throw new \InvalidArgumentException('Invalid header syntax');
}
$headers = [];
foreach ($headerLines as $headerLine) {
$headers[$headerLine[1]][] = $headerLine[2];
}
return [
'start-line' => $startLine,
'headers' => $headers,
'body' => $body,
];
return Message::parseMessage($message);
}
/**
@@ -820,79 +378,45 @@ function _parse_message($message)
* @param array $headers Array of headers (each value an array).
*
* @return string
*
* @internal
*
* @deprecated _parse_request_uri will be removed in guzzlehttp/psr7:2.0. Use Message::parseRequestUri instead.
*/
function _parse_request_uri($path, array $headers)
{
$hostKey = array_filter(array_keys($headers), function ($k) {
return strtolower($k) === 'host';
});
// If no host is found, then a full URI cannot be constructed.
if (!$hostKey) {
return $path;
}
$host = $headers[reset($hostKey)][0];
$scheme = substr($host, -4) === ':443' ? 'https' : 'http';
return $scheme . '://' . $host . '/' . ltrim($path, '/');
return Message::parseRequestUri($path, $headers);
}
/**
* Get a short summary of the message body
* Get a short summary of the message body.
*
* Will return `null` if the response is not printable.
*
* @param MessageInterface $message The message to get the body summary
* @param int $truncateAt The maximum allowed size of the summary
*
* @return null|string
* @return string|null
*
* @deprecated get_message_body_summary will be removed in guzzlehttp/psr7:2.0. Use Message::bodySummary instead.
*/
function get_message_body_summary(MessageInterface $message, $truncateAt = 120)
{
$body = $message->getBody();
if (!$body->isSeekable() || !$body->isReadable()) {
return null;
}
$size = $body->getSize();
if ($size === 0) {
return null;
}
$summary = $body->read($truncateAt);
$body->rewind();
if ($size > $truncateAt) {
$summary .= ' (truncated...)';
}
// Matches any printable character, including unicode characters:
// letters, marks, numbers, punctuation, spacing, and separators.
if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/', $summary)) {
return null;
}
return $summary;
return Message::bodySummary($message, $truncateAt);
}
/** @internal */
/**
* Remove the items given by the keys, case insensitively from the data.
*
* @param iterable<string> $keys
*
* @return array
*
* @internal
*
* @deprecated _caseless_remove will be removed in guzzlehttp/psr7:2.0. Use Utils::caselessRemove instead.
*/
function _caseless_remove($keys, array $data)
{
$result = [];
foreach ($keys as &$key) {
$key = strtolower($key);
}
foreach ($data as $k => $v) {
if (!in_array(strtolower($k), $keys)) {
$result[$k] = $v;
}
}
return $result;
return Utils::caselessRemove($keys, $data);
}