Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Posting a file to a web service with Guzzle

I've been trying for several hours to make a POST request that sends a file.

First tried a simple file_get_contents() with stream context, doesn't seem to work. I never get a response back while the GET on a different URL works.

I searched on the web for an HTTP client and found Guzzle which was downloaded 400k times on Packagist; I decided to try out this technology. Well documented but, alas, getting an error also when posting that damn file.

$request = $client
    ->post('/files/')
    ->addPostFields(array('comments' => 'no value'))
    ->addPostFile('file', 'test.doc')
    ->setAuth($this->username, $this->password);

It took me hours of reading and scouring the web to find out that I had a "417 Expectation Failed" issue.

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>417 Expectation Failed</title>
</head><body>
<h1>Expectation Failed</h1>
<p>The expectation given in the Expect request-header
field could not be met by this server.
The client sent<pre>
    Expect: 100-Continue, 100-Continue
</pre>
</p><p>Only the 100-continue expectation is supported.</p>
</body></html>

After more searching on the web, I ended up reading on the "Expect: 100-continue" header that was sent automatically by Guzzle, so I tried:

$request->removeHeader('expect');

I now end up with a bad request:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
Request header field is missing ':' separator.<br />
<pre>
zzle/3.7.3 curl/7.15.5 PHP/5.3.27</pre>
</p>
</body></html>

Printing the request headers to find that : missing, i get:

var_dump($request->__toString());

POST /files/ HTTP/1.1
Host: nunc57.qc.bell.ca
User-Agent: Guzzle/3.7.3 curl/7.15.5 PHP/5.3.27
Content-Type: multipart/form-data
Authorization: Basic bm92YTpzeW5hcHNl

Now I'm really stumped, I hope someone has already found a solution to this issue. I'm getting really tired of all this :(

like image 370
Mathieu Dumoulin Avatar asked Oct 03 '22 23:10

Mathieu Dumoulin


1 Answers

I wonder whether POSTing to /files/ (with a trailing slash) might be causing problems. Perhaps this forces an internal redirect and upsets Goutte, but not a web browser? I'd try adjusting your page so that you POST either to /files or /files/something.

If you can POST okay to the target URL using a web browser, I'd also suggest you record the request headers using browser tools, and see if there are any headers that could be added to your Guzzle request.

like image 148
halfer Avatar answered Oct 13 '22 11:10

halfer