Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serializing Requests #106

Closed
bpolaszek opened this issue Jul 7, 2016 · 4 comments
Closed

Serializing Requests #106

bpolaszek opened this issue Jul 7, 2016 · 4 comments

Comments

@bpolaszek
Copy link

bpolaszek commented Jul 7, 2016

Hello guys,

I want to serialize requests and responses as well.

I found the solution on #53 - but

The \GuzzleHttp\Psr7\str function does a good job indeed, except it doesn't make a difference between HTTP and HTTPS.

<?php

use GuzzleHttp\Psr7\Request;
use function \GuzzleHttp\Psr7\str;

require_once __DIR__ . '/../vendor/autoload.php';

$secureRequest   = new Request('GET', 'https://example.org');
$unsecureRequest = new Request('GET', 'http://example.org');
var_dump(str($secureRequest) === str($unsecureRequest)); // true

This is quite disturbing because when I store a request as string for further use, the request automatically switches to HTTP...

Any ideas?

Thanks,
Ben

@Tobion
Copy link
Member

Tobion commented Jul 7, 2016

The problem is the scheme is only part of the TCP connection (via port, ssl) and not really part of the request HTTP representation. What you can do, is to set the request target (withRequestTarget) to the absolute-form. See https://tools.ietf.org/html/rfc7230#section-5.3.2
Then the scheme will not get lost and parse_request should be able to identify the URI scheme.

@bpolaszek
Copy link
Author

bpolaszek commented Jul 8, 2016

Hello Tobion,

Thanks for your quick answer. I followed your advice but this breaks "unserializing":

/**
 * @param \Psr\Http\Message\RequestInterface $request
 * @return string
 */
function serializePSRRequest(\Psr\Http\Message\RequestInterface $request) {
    if ($request->getUri()->getScheme() === 'https') {
        $request = $request->withRequestTarget('absolute-form');
    }
    return \GuzzleHttp\Psr7\str($request);
}

/**
 * @param string $string
 * @return GuzzleHttp\Psr7\Request
 */
function unserializePSRRequest(string $string) {
    return \GuzzleHttp\Psr7\parse_request($string);
}

$secureRequest      = new \GuzzleHttp\Psr7\Request('GET', 'https://example.org');
$unsecureRequest    = new \GuzzleHttp\Psr7\Request('GET', 'http://example.org');
$secureRequestStr   = serializePSRRequest($secureRequest);
$unsecureRequestStr = serializePSRRequest($unsecureRequest);
var_dump($secureRequestStr === $unsecureRequestStr); // false
var_dump(unserializePSRRequest($unsecureRequestStr)); // returns \GuzzleHttp\Psr7\Request object
var_dump(unserializePSRRequest($secureRequestStr)); // throws \InvalidArgumentException: Invalid request string

What would be the best practice?

Thanks,
Ben

@Tobion
Copy link
Member

Tobion commented Jul 8, 2016

withRequestTarget('absolute-form')

This is not correct. Absolute-form is just the name. This should do it: $request->withRequestTarget((string) $request->getUri())

@bpolaszek
Copy link
Author

LMAO - #facepalm ^^

Sorry, my skills in raw HTTP messages aren't that good.
Your solution works, wether or not the original URI has an HTTPS scheme.

Thanks! I owe you a beer.
Ben

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants