Wrong send body PSR-7 POST

This is either not sent or not received correctly. Using curl directly from the command line (using the -d option) or from PHP (using CURLOPT_POSTFIELDS) works.

I start with the PSR-7 request:

 $request = GuzzleHttp\Psr7\Request('POST', $url); 

I am adding an authentication header that correctly validates the API authentication:

 $request = $request->withHeader('Authorization', 'Bearer ' . $accessToken); 

Then I add the request body:

 // The parameter for the API function $body = \GuzzleHttp\Psr7\stream_for('args=dot'); $request = $request->withBody($body); 

I can send a message to the API:

 $client = new \GuzzleHttp\Client(); $response = $client->send($request, ['timeout' => 2]); 

The answer I'm returning indicates that the "args" parameter was simply not being viewed by the API. I tried moving the authentication token to args:

 'args=dot&access_token=123456789' 

This should work and works with curl from the command line ( -d access_token=123456789 ), but the API does not see this parameter when sending cia curl (6.x), as indicated above.

I see that the message contains the body:

 var_dump((string)$request->getBody()); // string(8) "args=dot" // The "=" is NOT URL-encoded in any way. 

So what could be wrong here? Are parameters sent or sent in the wrong format (maybe "=" is encoded?) Or maybe the wrong type of content is being used? It's hard to understand what is sent β€œon the wire” when using Guzzle, as the HTTP message is formatted and sent to many layers.

Edit: By calling a local test script instead of the remote API, I get this detailed information:

 POST CONNECTION: close CONTENT-LENGTH: 62 HOST: acadweb.co.uk USER-AGENT: GuzzleHttp/6.1.1 curl/7.19.7 PHP/5.5.9 args=dot&access_token=5e09d638965288937dfa0ca36366c9f8a44d4f3e 

So, it looks like the body is being sent, so I assume that something else is missing to tell the remote API how to interpret this body.

Edit: a command line curl that works, sent to the same test script, gives me two additional header fields in the request:

 CONTENT-TYPE: application/x-www-form-urlencoded ACCEPT: */* 

I'm going to guess that this is a content type header that is not in the Guzzle request, which is the source of the problem. So is this a terrible mistake? Should he not always send Content-Type based on the assumptions he makes listed in the documentation ?

+7
guzzle psr-7
source share
2 answers

GuzzleHttp\Client provides all the necessary packaging.

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

Documentation Available Guzzle Query Parameters

Edit: However, if your requests are used in GuzzleHttp \ Pool, you can simply do 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, '&') ); 
+6
source share

There was a problem in the Content-Type header. Normally, Guzzle will hold your hand and insert the headings that it deems necessary, and makes a good guess at the Content-Type based on what you gave it and how you gave it.

With the Gzzle PSR-7 messages, none of these hands are executed. It strictly leaves all the headlines for you. Therefore, adding POST parameters to the PSR-7 Request , you must explicitly specify the Content-Type:

 $params = ['Foo' => 'Bar']; $body = new \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 params as an array and leave Guzzle to solve the rest does not apply to the Guzzle PSR-7 implementation. This is a bit awkward, since you need to serialize the POST parameters to the HTTP request string and then paste into the stream, but there you have it. There might be an easier way to handle this (for example, a wrapper class that I don't know about), and I'll wait and see if anyone comes up with this question.

Remember also that when building a multipart/form-data Request message, you need to add a boundary line 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 building a multi-part body.

+9
source share

All Articles