Guzzle not sending PSR-7 POST body correctly

The Content-Type header was the issue. Normally, Guzzle will hold your hand and insert headers it deems necessary, and makes a good guess at the Content-Type based on what you have given it, and how you have given it.

With Guzzle's PSR-7 messages, none of that hand-holding is done. It strictly leaves all the headers for you to handle. So when adding POST parameters to a PSR-7 Request, you must explicitly set the Content-Type:

$params = ['Foo' => 'Bar'];
$body = \GuzzleHttp\Psr7\stream_for(http_build_query($params));
$request = $request->withBody($body);
$request = $request->withHeader('Content-Type', 'application/x-www-form-urlencoded');

The ability to pass in the params as an array and to leave Guzzle to work out the rest, does not apply to Guzzle's PSR-7 implementation. It's a bit clumsy, as you need to serialise the POST parameters into a HTTP query string, and then stick that into a stream, but there you have it. There may be an easier way to handle this (e.g. a wrapper class I'm not aware of), and I'll wait and see if any come up before accepting this answer.

Be aware also that if constructing a multipart/form-data Request message, you need to add the boundary string to the Content-Type:

$request = $request->withHeader('Content-Type', 'multipart/form-data; boundary=' . $boundary);

Where $boundary can be something like uniq() and is used in construction the multipart body.


The GuzzleHttp\Client provides all necessary wrapping.

$response = $client->post(
    $uri,
    [
        'auth' => [null, 'Bearer ' . $token],
        'form_params' => $parameters,
]);

Documentation available Guzzle Request Options

Edit: However, if your requests are being used within GuzzleHttp\Pool then, you can simply everything into the following:

$request = new GuzzleHttp\Psr7\Request(
    'POST',
    $uri,
    [
       'Authorization' => 'Bearer ' . $token,
       'Content-Type' => 'application/x-www-form-urlencoded'

    ],
    http_build_query($form_params, null, '&')
);

Tags:

Guzzle

Psr 7