PUT request adds Content-Length header twice, server returns 400 Bad Request

583 views
Skip to first unread message

Sebastian Schaffert

unread,
Jan 25, 2012, 7:41:54 AM1/25/12
to guz...@googlegroups.com
I am currently building a PHP webservice client for a Java server application that exposes its functionality using REST services. One of the services requires a PUT method with a request body in JSON format. Unfortunately, Guzzle seems to generate the request header "Content-Length" twice, resulting in the server to respond with a "400 Bad Request". 

The PHP code I use looks as follows:

        $client = new Client();
        $request = $client->put($this->getServiceUrl($uri),array(
            "User-Agent"   => "LMF Client Library (PHP)",
            "Content-Type" => "application/json; rel=meta"
        ), $metadata_json);
        $response = $request->send();

Using a HTTP Analyzer (HTTP Scoop), I see that the header "Content-Length" generated by Guzzle is "135,135" while it should have only one value.

Environment: MacOS X Lion, latest Guzzle

Sebastian Schaffert

unread,
Jan 25, 2012, 8:48:23 AM1/25/12
to guz...@googlegroups.com
A workaround that works for me is to modify the file CurlHandle.php in the factory method and uncomment the line where the CURLOPT_INFILESIZE is set:

            case 'PUT':
                $curlOptions[CURLOPT_UPLOAD] = true;
                if ($request->getBody()) {
                    //$curlOptions[CURLOPT_INFILESIZE] = $request->getHeader('Content-Length') ?: -1;
                }
                break;

Afterwards, the Content-Length header is only set by Guzzle and not a second time by cURL.

Michael

unread,
Jan 25, 2012, 12:38:12 PM1/25/12
to guz...@googlegroups.com
Hi Sebastian,

Thanks for reporting this.  I was able to reproduce the issue.  However, removing the CURLOPT_INFILESIZE option did some strange things that caused requests to use chunked transfer encoding even when a Content-Length header was set.  This may have something to do with using the CURLOPT_UPLOAD option.  I changed the code you referenced above to only use a CURLOPT_INFILESIZE rather than the Content-Length header set by Guzzle.  This bug wasn't caught in the tests due to a bug in how the requests are marshaled when sent to the test node.js server and back to the tests for inspection.

Could you try out the latest code from the master branch and confirm that this change fixes your issue?  https://github.com/guzzle/guzzle

Thanks!
Michael

Sebastian Schaffert

unread,
Jan 27, 2012, 12:13:46 PM1/27/12
to guz...@googlegroups.com
Hi Michael,

thanks for fixing the issue. I will test whether it works when I find some time over the weekend or next week. Too busy in the last days ;-)

Greetings,

Sebastian
Reply all
Reply to author
Forward
0 new messages