GithubHelp home page GithubHelp logo

message's People

Contributors

aaa2000 avatar ajgarlag avatar chris8934 avatar dbu avatar ddeboer avatar driehle avatar fbourigault avatar garypegeot avatar grahamcampbell avatar jdecool avatar joelwurtz avatar llaakkkk avatar localheinz avatar maff- avatar mekras avatar meridius avatar nicolas-grekas avatar nyholm avatar ondram avatar ostrolucky avatar peter279k avatar ro0nl avatar ruudk avatar sagikazarmark avatar shoito avatar staabm avatar ste93cry avatar tuhin18003 avatar tuupola avatar z38 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

message's Issues

Cookie for root path (/) matches only exact match.

Q A
Bug? yes
New Feature? no
Version v1.4.0

Actual Behavior

When having a Cookie with the path set to the domain root (e.g. /), and checking to see if another path matches (i.e. /cookies) it will always fail. (Except when checking an exact match, /).

Expected Behavior

I expect path /cookies to match a Cookie with path /.

Steps to Reproduce

$cookie = new Cookie('foo', 'bar', null, 'example.com', '/');
var_dump($cookie->matchPath('/cookies')); // = false, but should be true
// spec\Http\Message\CookieSpec
function it_matches_the_root_path()
{
    $this->beConstructedWith('name', 'value', null, null, '/');
    $this->matchPath('/')->shouldReturn(true);
    // we should add this line below
    $this->matchPath('/cookies')->shouldReturn(true);
}

Possible Solutions

A solution shouldn't be to hard to find. My guess is that adding a trailing slash isn't completely correct, but reading the linked rfc section doesn't make things easier. 😕

current code. not a solution!:

/**
 * Checks whether this cookie is meant for this path.
 * @see http://tools.ietf.org/html/rfc6265#section-5.1.4
 */
public function matchPath($path)
{
    return $this->path === $path || (strpos($path, $this->path.'/') === 0);
}

Rewind streams in the formatter

Q A
Bug? yes
New Feature? no
Version 1.3.0

Actual Behavior

From: php-http/HttplugBundle#84 (comment)

Just see the formatter and how the request / response is read.

As far as i have see, this formatter mess up with the stream, as __toString is called and the stream is not rewind so the content is retrieve only in the first stream ?

(I may have miss something again ^^)

Expected Behavior

Streams should be rewinded after they are read.

Check if body is empty string in stream factories

Q A
Bug? no
New Feature? yes

Actual Behavior

Currently the stream factories check whether the body is null, and only in that case they don't write to the stream.

Expected Behavior

Empty strings are not written to a stream.

Possible Solutions

Writting an empty string to the stream doesn't make any sense, so we should check that too.

Missing v1.4.0 tag

Q A
Bug? no
New Feature? no
Version b86b453

Actual Behavior

The v1.4.0 tag that corresponds to the version 1.4.0 described in the CHANGELOG does not exist.

Compatibility issue since version 1.14.0

PHP 8.2.4

Description
Compatibility issue since version 1.14.0

PHP Fatal error:  Declaration of Http\Message\Encoding\FilteredStream::close() must be compatible with Psr\Http\Message\StreamInterface::close(): void in /var/www/html/vendor/php-http/message/src/Decorator/StreamDecorator.php on line 30

In StreamDecorator.php line 30:
                                                                                                                                        
  Declaration of Http\Message\Encoding\FilteredStream::close() must be compatible with Psr\Http\Message\StreamInterface::close(): void

Release plans

Hello, are there any plans of making a release? Thanks!

Cookie

Move and finalize php-http/cookie here.

WSSE Authentication

PHP version: 7.2

Description
Cannot authenticate with WSSE Plugin

How to reproduce
Use WSSE REST Api like emarsys rest api

Possible Solution
Change line in Wsse.php

$digest = base64_encode(hash($this->hashAlgorithm, $nonce.$created.$this->password, false));

Additional context
I am trying to auth against a wsse api from emarsys. But the auth does not work correctly with the current implementation.
Current:

$digest = base64_encode(hash($this->hashAlgorithm, base64_decode($nonce).$created.$this->password, true));

The base64_decode is not needed because the nonce creation is using a md5.
The parameter binary should be false instead of true, than the auth works.
Can anybody reproduce this? Thx

CI: Add testrun for "psr/http-message" v2 with slim

in composer.json "psr/http-message" v1 and v2 are allowed.

But if i see this correct, v2 is never tested in the testruns.
Example:
https://github.com/php-http/message/actions/runs/7623563875/job/20763848547

Because of Version 3 of "slim/slim"
https://github.com/php-http/message/blob/1.x/composer.json#L31C10-L31C19

https://packagist.org/packages/slim/slim#3.12.5

Only the dev-version supports v1 and v2
https://packagist.org/packages/slim/slim#4.x-dev

Expose request to resonse formatter

Hi,

Would you consider passing the request to formatResponse() in Formatter? Introducing "format response for request" effectively.

We could use it to redact sensitve responses for certain URLs.

We could use it to hide response bodies for certain URLs that we don't care about.

The alternative route is to create a formatter per usecase, thus a plugin client per usecase ... which is really overhead :)

WDYT?

Tag version 1.3

The new formatter is needed in next version of HttplugBundle

GuzzleStreamFactory and guzzle/psr7:^2.0

PHP version: 8.0.6

Description
updating a already working project setup to guzzle/psr7:^2.0 leads to confusion in combination with phppro/soap-client.

we see the php-soap client picking up the GuzzleStreamFactory and this one is not compatible with guzzle/psr7:^2.0.

see more details in phpro/soap-client#385

any pointers in any direction would be helpful. stacking all these psr/http-plug etc. packages together is pretty confusing.

How to reproduce

our (simplified) composer.json looks like

    "require" : {
        "ext-json": "*",
        "ext-soap": "*",
        "ext-gettext": "*",
        "phpro/soap-client": "^1.4",
        "guzzlehttp/guzzle": "^7.2.0",
        "guzzlehttp/promises": "^1.4.0",
        "guzzlehttp/psr7": "2.0.0"
    },

and we are creating the soap client with this code:

    public static function getEngine(string $wsdl, ExtSoapOptions $options): Engine
    {

        $httpClient = new Client([
            'verify' => false /*disable ssl cert validation*/,
            'auth' => [SoapConfig::WEBCONNECTOR_USER, SoapConfig::WEBCONNECTOR_PW, 'ntlm'],
        ]);

        $handler = HttPlugHandle::createForClient($httpClient);
        $handler->addMiddleware(new \WebconnectorMiddleware());
        $handler->addMiddleware(new WsaMiddleware2005(WsaMiddleware2005::WSA_ADDRESS2005_ANONYMOUS));

        $wsdlProvider = new CachedWsdlProvider(new HttpWsdlLoader(
            $httpClient,
            Psr17FactoryDiscovery::findRequestFactory()
        ), new Filesystem(),sys_get_temp_dir().DIRECTORY_SEPARATOR.'soap-test-');

        $options->withWsdlProvider($wsdlProvider);
        return ExtSoapEngineFactory::fromOptionsWithHandler($options, $handler);
    }

and we get a exception:

Error thrown with message "Call to undefined function GuzzleHttp\Psr7\stream_for()"

Stacktrace:
#18 Error in /cluster/www/www/www/philipp/vendor/php-http/message/src/StreamFactory/GuzzleStreamFactory.php:23
#17 Http\Message\StreamFactory\GuzzleStreamFactory:createStream in /cluster/www/www/www/philipp/vendor/phpro/soap-client/src/Phpro/SoapClient/Soap/HttpBinding/Builder/Psr7RequestBuilder.php:130
#16 Phpro\SoapClient\Soap\HttpBinding\Builder\Psr7RequestBuilder:setSoapMessage in /cluster/www/www/www/philipp/vendor/phpro/soap-client/src/Phpro/SoapClient/Soap/HttpBinding/Converter/Psr7Converter.php:52
#15 Phpro\SoapClient\Soap\HttpBinding\Converter\Psr7Converter:convertSoapRequest in /cluster/www/www/www/philipp/vendor/phpro/soap-client/src/Phpro/SoapClient/Soap/Handler/HttPlugHandle.php:84
#14 Phpro\SoapClient\Soap\Handler\HttPlugHandle:request in /cluster/www/www/www/philipp/vendor/phpro/soap-client/src/Phpro/SoapClient/Soap/Engine/Engine.php:39
#13 Phpro\SoapClient\Soap\Engine\Engine:request in /cluster/www/www/www/philipp/vendor/phpro/soap-client/src/Phpro/SoapClient/Client.php:107
#12 Phpro\SoapClient\Client:call in /cluster/www/www/www/philipp/soap/customer/generated/CustomerClient.php:20
...

grafik

Possible Solution

basically I am wondering whether https://github.com/php-http/message/blob/master/src/StreamFactory/GuzzleStreamFactory.php would also needs a separate IF case for guzzle/psr7:^2.0 as was added in https://github.com/php-http/message/pull/139/files for the GuzzleUriFactory ?

Reading GzipDecodeStream causes Uncaught RuntimeException: Unable to perform operation on closed stream

Q A
Bug? yes
New Feature? no
Version 1.0.1

Actual Behavior

What is the actual behavior?

PHP Fatal error: Uncaught RuntimeException: Unable to perform operation on closed stream in /Users/iconnor/Documents/PHP/php-http-message-bug/vendor/clue/stream-filter/src/functions.php:98

Expected Behavior

What is the behavior you expect?

The stream is rewindable. I should be able to read its contents, rewind it, and then read its contents again.

Steps to Reproduce

Checkout this repository https://github.com/iainconnor/php-http-message-bug/blob/master/demo.php run demo.php.

Or,

$streamFactory = new \Http\Message\StreamFactory\GuzzleStreamFactory();
$stream = $streamFactory->createStream(file_get_contents('http://httpbin.org/gzip'));
$gzipStream = new \Http\Message\Encoding\GzipDecodeStream($stream);

echo $gzipStream->getContents() . PHP_EOL;

if ( $gzipStream->isSeekable() ) {
    $gzipStream->rewind();
    echo $gzipStream->getContents();
}

Possible Solutions

If you have already ideas how to solve the issue, add them here.
(remove this section if not needed)

These lines -- https://github.com/php-http/message/blob/master/src/Encoding/FilteredStream.php#L116-L118 -- look to be the cause, though I'm not sure on the solution.

FullHttpMessageFormatter should be smarter about formatting binary request/response bodies

Like most websites, we have some file uploads. We also use Monolog to store logs into Google's Stackdriver. The way how this works is that Google encodes such log record via json_encode. This fails for such requests. Specificially, this is what you get: PHP Warning: InvalidArgumentException: json_encode error: Malformed UTF-8 characters, possibly incorrectly encoded. I can imagine lot of people with different loggers will have problems with your formatters in combination with binary content, not mentioning that it doesn't make much sense to store these messages as binary in traditional log files anyway as well.

What I would suggest is that your FullHttpMessageFormatter detects if content is binary similar as CurlCommandFormatter does and if that's the case, just do bin2hex. I can prepare PR if you are OK with this solution.

Additional implementations of RequestMatcher

Q A
Bug? no
New Feature? yes
Version n/a

Question

In a project we are currently using implementations of the RequestMatcher which allow us to reuse and compose request matchers.

For example

$httpClient->on(
    AllOf::matchers(
        Method::is('GET'),
        Path::is('foo/bar'),
        Uri\QueryParameters::are([
            'baz' => '1',
            'qux' => 'hmm',
        ])
    ),
    new Psr7\Response(Http::OK)
);

Would there be interest in having these pushed upstream, that is, into this repository?

PSR-17 compatibility ?

Q A
Bug? no (not really)
New Feature? yes (kinda ?)
Version latest

Actual Behavior

Seems that this package doesn't implement the psr/http-factory interfaces, and thus does not provide psr/http-factory-implementation.

Expected Behavior

To implement psr-17 interfaces instead of php-http's

Possible Solutions

Use the new interfaces from PSR-17, but as it would probably introduce BC breaks (as the psr are php 7.0+, and uses return typehints), it should be on a new major.

False positive trigger of deprecation notice in FilteredStream

Q A
Bug? yes
New Feature? no
Version 1.4.1

Actual Behavior

When creating my own custom stream to format data into base64 format (are you interested in merging it into core?) I extended the FilteredStream class. The PHP built-in convert.base64-encode stream filter seems to not accept null as value of the $readFilterOptions and $writeFilterOptions arguments. I had to pass an empty array to work around the following error:

Unable to access built-in filter: stream_filter_append(): unable to create or locate filter "convert.base64-encode"

This fixes the problem, but I then get a deprecation notice saying this:

The $writeFilterOptions argument is deprecated since version 1.5 and will be removed in 2.0.

Expected Behavior

As it seems that not all filters accept null as option of the stream_filter_append function, the deprecation notice should not be triggered when passing an empty array

Steps to Reproduce

Just create a class that extends the FilteredStream class and uses the convert.base64-encode stream filter without overriding the constructor. It will throw an exception when using it, and if constructor is overriden to fix the problem a deprecation notice will be triggered

Possible Solutions

The only solution I can think of is to check not only that the $writeFilterOptions argument is not null but also that it's a non-empty array to trigger the deprecation notice. Something like this:

diff --git a/src/Encoding/FilteredStream.php b/src/Encoding/FilteredStream.php
index a32554b..a516f77 100644
--- a/src/Encoding/FilteredStream.php
+++ b/src/Encoding/FilteredStream.php
@@ -60,7 +60,7 @@ abstract class FilteredStream implements StreamInterface
         $this->readFilterCallback = Filter\fun($this->readFilter(), $readFilterOptions);
         $this->writeFilterCallback = Filter\fun($this->writeFilter(), $writeFilterOptions);
 
-        if (null !== $writeFilterOptions) {
+        if (null !== $writeFilterOptions || (is_array($writeFilterOptions) && !empty($writeFilterOptions))) {
             @trigger_error('The $writeFilterOptions argument is deprecated since version 1.5 and will be removed in 2.0.', E_USER_DEPRECATED);
         }

WSSE Authentication allow to change hashing algorithm

Q A
Bug? no
New Feature? yes

Actual Behavior

The authentication uses SHA1 to hash the token.

Expected Behavior

User should be allowed to change hashing mechanism based on the server.

Possible Solutions

Add a new parameter in the constructor with the default value SHA1. The default value should be deprecated right away and be replaced with a mandatory one: check the number of arguments and trigger a deprecated error if we see the default value is used.

Unable to format binary payload as command

Q A
Bug? yes
New Feature? no
Version master (977edb5)

Actual Behavior

Using CurlCommandFormatter to format a HTTP request with a binary payload throws an exception:

Error: escapeshellarg(): Input string contains NULL bytes
  at vendor/php-http/message/src/Formatter/CurlCommandFormatter.php:43

Expected Behavior

The formatter throws a proper exception or outputs a valid (possibly incomplete) command (see below).

Steps to Reproduce

$requestFactory = Http\Discovery\MessageFactoryDiscovery::find();
$request = $requestFactory->createRequest('POST', 'http://example.com', [], "\0");

$formatter = new Http\Message\Formatter\CurlCommandFormatter();
$formatter->formatRequest($request);

Possible Solutions

In case the formatter should output a command at any times, it should either escape null bytes properly or remove the payload completely. Other tools, such as the network monitor of Firefox, only include url-encoded payloads or multipart parts with Content-Disposition: form-data in the command.

CompressStream and DecompressStream really handles deflate content encoding

Q A
Bug? yes
New Feature? no
Version v1.4.0

Actual Behavior

An stream encoded with deflate content-encoding cannot be read by InflateStream, but with DecompressStream.

Expected Behavior

The deflate content-encoding should be managed by InflateStream and DeflateStream while
CompressStream and DecompressStream should handle compress content-encoding.

Steps to Reproduce

<?php

require 'vendor/autoload.php';

$payload = file_get_contents('http://httpbin.org/deflate');

$innerStream1 = new spec\Http\Message\Encoding\MemoryStream($payload);
$inflateStream = new Http\Message\Encoding\InflateStream($innerStream1);
$inflatedContents = $inflateStream->getContents();
var_dump($inflatedContents !== ""); //Should be true

$innerStream2 = new spec\Http\Message\Encoding\MemoryStream($payload);
$decompressStream = new Http\Message\Encoding\DecompressStream($innerStream2);
$decompressedContents = $decompressStream->getContents();
var_dump($decompressedContents === ""); //Should be true

var_dump($inflatedContents);
var_dump($decompressedContents);

$realContents = $decompressedContents;

$innerStream3 = new spec\Http\Message\Encoding\MemoryStream($realContents);
$deflateStream = new Http\Message\Encoding\DeflateStream($innerStream3);
$deflatedContents = $deflateStream->getContents();
var_dump($deflatedContents === $payload); //Should be true

$innerStream4 = new spec\Http\Message\Encoding\MemoryStream($realContents);
$compressStream = new Http\Message\Encoding\CompressStream($innerStream4);
$compressedContents = $compressStream->getContents();
var_dump($compressedContents !== $payload); //Should be true

Possible Solutions

To avoid BC breaks, I think we should add a warning in the documentation and in the class docblocks
and rename them in 2.0.
I'm looking for and HTTP endpoint to test compress content-encoding, but I have not found anyone.

MultipartStreamBuilder uses too much memory when building the stream with a big body

Currently, MultipartStreamBuilder builds the whole content of the stream as a string in memory, even when the original data was built using a Stream wrapping a resource to avoid loading the whole file in memory at this point.

As building a multipart stream only involves appending the different strings with some delimiters, it would be much better to implementing this in a streaming way.

GuzzleHttp\Psr7\AppendStream might help here (which is what GuzzleHttp\Psr7\MultipartStream uses internally)

Base URL message factory

Having to prefix all the calls with a base URL is annoying:

$factory->createRequest('GET', 'http://example.com/foo');

It could be avoided if we implemented something like the following that would include the base url for us:

$factory = new BaseUrlMessageFactory('http://example.com', new GuzzleMessageFactory());
$request = $factory->createRequest('GET', '/foo');

The advantage is that we wouldn't need to deal with base url in the place where the factory is used.

What do you think?

Formatter

We should be able to format Requests/Responses to string.

Basic interface

<?php

namespace Http\Message;

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

/**
 * Formats a request or a response into string.
 *
 * @author Márk Sági-Kazár <[email protected]>
 */
interface Formatter
{
    /**
     * Formats a request.
     *
     * @param RequestInterface $request
     *
     * @return string
     */
    public function formatRequest(RequestInterface $request);

    /**
     * Formats a response.
     *
     * @param ResponseInterface $response
     *
     * @return string
     */
    public function formatResponse(ResponseInterface $response);
}

Some questions

  • Should we separate Request/Response format method into separate interfaces? (Like in case of message factories)

Default implementations

Inconsistent naming

I started to work on the message package and already moved some stuff to it.

I found an inconsistency issue:

We have message factory interfaces in the message-factory package. This is a contract package, and I think it would be better to have it that way. The namespace is Http\Message.

The message factory implementations are moved here from the utils package. The namespace is Http\Message as well, so factories are in Http\Message*Factory namespaces. Eg. Http\Message\MessageFactory\GuzzleMessageFactory.

We also have decorators. Originally they were in the Http\Message namespace as well, but I moved them in this package one level down to Http\Message\Decorator.

So we have an inconsistency here: Http\Message\MessageFactory, but Http\Message\Decorator\RequestDecorator.

The extra thing is that the message factory package is already tagged as 1.0, which does not allow us to change it's namespace without major version change.

So, should we just leave the situation as is, or should we move Decorators back to the Http\Message namespace for consistency?

Tag new version

Master has a few bug fixes. We should tag a new release asap

Missing provides in composer.json file

Q A
Bug? yes and no
New Feature? yes and no
Version Latest

Actual Behavior

This package doesn't say it provides message factories (implementing php-http/message-factory-implementation). So if a package requires this implementation, it will not be installable, even though there are messages factories in this repository.

Expected Behavior

Stating that this package implements php-http/message-factory-implementation

Possible Solutions

Stating that this package implements php-http/message-factory-implementation

Even though it is also not technically correct as if one of these 3 factories can't be accessed (because their main vendor is not installed). Another solution would be to decouple these implementations into their own repositories (and stating then that it can implement said interface), or putting these in their client package (e.g for guzzle, putting its classes into the guzzle5 and guzzle6 adapters)

Bug: Call to undefined function GuzzleHttp\\Psr7\\uri_for()

PHP version: 7.4.3

Description
After update of GuzzleHttp lib (via composer) , I had this issue:

PHP Fatal error:  Uncaught Error: Call to undefined function GuzzleHttp\\Psr7\\uri_for() 
php-http/message/src/UriFactory/GuzzleUriFactory.php

How to reproduce
Since upgrade (in my case) v2.1.7 dependency lib GuzzleHttp\Psr7 to v2.1.7

Possible Solution
it seems coming from deprecated use of function :
php-http\message\src\UriFactory\GuzzleUriFactory.php

original
return Psr7\uri_for($uri);

correction :
return Psr7\Utils::uriFor($uri);

I only fast edit this fix. I didn't check all deprecated functions used.

Invalid value returned by GzipEncodeStream::getSize

Q A
Bug? yes
New Feature? no
Version b86b453

Actual Behavior

The GzipEncodeStream::getSize returns the size of the inner stream content.

Expected Behavior

The GzipEncodeStream::getSize should return the size of the gzipped body.

Steps to Reproduce

<?php
require 'vendor/autoload.php';

$payload = 'This is a test stream';

$innerStream = new spec\Http\Message\Encoding\MemoryStream($payload);
$gzipEncodedStream = new Http\Message\Encoding\GzipEncodeStream($innerStream);

var_dump($gzipEncodedStream->getContents() === gzencode($payload)); //It is true
var_dump($gzipEncodedStream->getSize() === strlen(gzencode($payload))); //Should be true

Implicit vs explicit dependencies

Currently there are a few implicit dependencies declared:

  • Guzzle PSR7 and Diactoros which are fine that way
  • clue/stream-filter and ext-zlib which are required by the Encoding part of the package

Question: should the latter to be implicitly or explicitly required?

Response builder broke header value

Q A
Bug? yes
New Feature? no
Version 1.2.0

Actual Behavior

Curl client (and maybe more) using Http\Message\Builder\ResponseBuilder. When client adds Content-Type: application/hal+json header using addHeader method, created response contains Content-Type: application/hal json

Expected Behavior

Created response should contains valid header value as it's in raw response.

Steps to Reproduce

Send request to get response with header contains + eg. Content-Type: application/hal+json

Possible Solutions

Remove / fix decoding in https://github.com/php-http/message/blob/master/src/Builder/ResponseBuilder.php#L139

DiactorosMessageFactory createResponse does not rewind strem if created with string body

Q A
Bug? yes
New Feature? no
Version 1.7.2

Actual Behavior

$contents = (new DiactorosMessageFactory())->createResponse(200, null, [], "Hello")->getBody()->getContents();

$contents should be 'Hello', instead it is empty, it only works when a rewind is performed

$stream = (new DiactorosMessageFactory())->createResponse(200, null, [], "Hello")->getBody();
$stream->rewind();
$contents = $stream->getContents();

this is actually really hard to do in some situations when the response is used inside a framework wich uses php-http/message

Expected Behavior

$contents = (new DiactorosMessageFactory())->createResponse(200, null, [], "Hello")->getBody()->getContents();

$contents should be 'Hello'

Steps to Reproduce

simpliest way to reproduce is to use the one liner shown above.

actually i am facing this problem together with geocoder-php so when i create the HttpClient in the code i must add this plugin to the chain like

    $rewind = new class implements Plugin
    {
        /**
         * @inheritdoc
         */
        public function handleRequest(RequestInterface $request, callable $next, callable $first): Promise
        {
            return $next($request)->then(function (ResponseInterface $response) {
                $response->getBody()->rewind();
                return $response;
            }, function (\Exception $exception) {
                throw $exception;
            });
        }
    };
    $decoderPlugin = new DecoderPlugin(['use_content_encoding' => true]);
    return new PluginClient(HttpClientDiscovery::find(), [$rewind, $decoderPlugin]);

removing the $rewind from the plugin list the client will no longer work

Possible Solutions

see above

Binary string detection is broken (introduced with 1.9.0)

PHP version: all versions

Description
With #126 and #128 a change was introduced that is supposed to prevent binary messages from being dumped. In FullHttpMessageFormatter line 89 the following code is used to detect binary strings:

        if (preg_match('/([\x00-\x1F\x7F])/', $data)) {
            return $message.'[binary stream omitted]';
        }

Unfortunatly, this regex includes common whitespaces like \t, \r and \n as well. In consequence, all output is hidden and replaced with [binary stream omitted], even if the document is a simple HTML or XML document. I doubt that this is the intentioned behaviour, since linebreaks a by far an indicator for a binary string and moreover very common in HTML or XML documents.

Possible Solution
The code could be changed as follows, see https://stackoverflow.com/questions/25343508/detect-if-string-is-binary:

        if (preg_match('~[^\x20-\x7E\t\r\n]~', $data)) {
            return $message.'[binary stream omitted]';
        }

However, this would still be problematic regarding non-English languages, i.e. special characters in French, Spanish, Italian or German would still trigger falsely the binary detection. Therefore, I would suggest to check for all non-prinable ASCII characters as well as <del> (\x7F) and explicitly exclude <cr> (\x0D), <lf> (\x0A) and <tab> (\x0B).

        // all non-printable ASCII characters and <DEL> except for \t, \r, \n
        if (preg_match('/([\x00-\x09\x0C\x0E-\x1F\x7F])/', $data)) {
            return $message.'[binary stream omitted]';
        }

The same change should probably be applied to CurlCommandFormatter as well.

What do you think?

Optional cookie validation

Q A
Bug? yes
New Feature? no
Version 69e4723

Actual Behavior

I'm writing a proxy script where I have to parse the set-cookie headers sent back by the upstream servers. Sometimes the upstream server (out of my control) send a cookie with invalid characters in name and/or value and when I try to parse it the library throws an \InvalidArgumentException

Expected Behavior

I'd like to make this validation optional

Steps to Reproduce

use Http\Discovery\HttpClientDiscovery;
use Http\Message\CookieJar;
use Http\Client\Common\PluginClient;
use Http\Client\Common\Plugin\CookiePlugin;
use Http\Client\Curl\Client;
use Http\Message\MessageFactory\DiactorosMessageFactory;
use Http\Message\StreamFactory\DiactorosStreamFactory;

$messageFactory = new DiactorosMessageFactory();

$pluginClient = new PluginClient(
    new Client($messageFactory, new DiactorosStreamFactory()),
    [new CookiePlugin(new CookieJar())]
);

$response = $pluginClient->sendRequest(
    $messageFactory->createRequest('GET', 'http://www.micromedexsolutions.com/home/dispatch')
);

Stream verification

Utilize stream filters to verify the content of stream.

For example an md5 verification:

class MD5 extends \php_user_filter
{
    private $context;

    public function onCreate()
    {
        $this->context = hash_init('md5');

        return true;
    }

    public function onClose()
    {
        $hash = hash_final($this->context);

        if (false === hash_equals($this->params, $hash)) {
            throw new VerificationException('The stream integrity cannot be verified');
        }

        return true;
    }

    public function filter($in, $out, &$consumed, $closing)
    {
        while ($bucket = stream_bucket_make_writeable($in)) {
            hash_update($this->context, $bucket->data);

            $consumed += $bucket->datalen;

            stream_bucket_append($out, $bucket);
        }

        return PSFS_PASS_ON;
    }
}

This would be useful when downloading files (PHARs for example, when a hash is likely available)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.