title: Guzzle not sending PSR-7 POST body correctly
body: <p>It is either not being sent, or not being received correctly. Using <code>curl</code> direct from the command line (using the -d option) or from PHP (using CURLOPT_POSTFIELDS) does work.</p>
  
  <p>I start with a PSR-7 request:</p>
  
  <pre><code>$request = GuzzleHttp\Psr7\Request('POST', $url);
  </code></pre>
  
  <p>I add authentication header, which authenticates against the API correctly:</p>
  
  <pre><code>$request = $request-&gt;withHeader('Authorization', 'Bearer ' . $accessToken);
  </code></pre>
  
  <p>Then I add the request body:</p>
  
  <pre><code>// The parameter for the API function
  $body = \GuzzleHttp\Psr7\stream_for('args=dot');
  $request = $request-&gt;withBody($body);
  </code></pre>
  
  <p>I can send the message to the API:</p>
  
  <pre><code>$client = new \GuzzleHttp\Client();
  $response = $client-&gt;send($request, ['timeout' =&gt; 2]);
  </code></pre>
  
  <p>The response I get back indicates that the "args" parameter was simply not seen by the API. I have tried moving the authentication token to the args:</p>
  
  <pre><code>'args=dot&amp;access_token=123456789'
  </code></pre>
  
  <p>This should work, and <em>does</em> work with curl from the command line (<code>-d access_token=123456789</code>) but the API fails to see that parameter also when sending cia curl (6.x) as above.</p>
  
  <p>I can see the message <em>does</em> contain the body:</p>
  
  <pre><code>var_dump((string)$request-&gt;getBody());
  // string(8) "args=dot"
  // The "=" is NOT URL-encoded in any way.
  </code></pre>
  
  <p>So what could be going wrong here? Are the parameters not being sent, or are they being sent in the wrong format (maybe '=' is being encoded?), or is perhaps the wrong content-type being used? It is difficult to see what is being sent "on the wire" when using Guzzle, since the HTTP message is formatted and sent many layer deep.</p>
  
  <p>Edit: Calling up a <a href="https://www.daniweb.com/programming/web-development/code/216846/get-http-request-headers-and-body">local test script</a> instead of the remote API, I get this raw message detail:</p>
  
  <pre><code>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&amp;access_token=5e09d638965288937dfa0ca36366c9f8a44d4f3e
  </code></pre>
  
  <p>So it looks like the body <em>is</em> being sent, so I guess something else is missing to tell the remote API how to interpret that body.</p>
  
  <p>Edit: the command-line curl that does work, sent to the same test script, gives me two additional header fields in the request:</p>
  
  <pre><code>CONTENT-TYPE: application/x-www-form-urlencoded
  ACCEPT: */*
  </code></pre>
  
  <p>I'm going to guess it is the content-type header which is missing from the Guzzle request which is the source of the problem. So is this a Guzzle bug? Should it not always sent a Content-Type, based on the assumptions it makes that are <a href="http://guzzle3.readthedocs.org/http-client/request.html#content-type-header">listed in the documentation</a>?</p>