Issue Type: Bug Created: 2009-05-15T10:39:34.000+0000 Last Updated: 2009-06-12T14:27:51.000+0000 Status: Resolved Fix version(s): - 1.8.4 (23/Jun/09)
Reporter: Jordan Ryan Moore (jordanryanmoore) Assignee: Benjamin Eberlei (beberlei) Tags: - Zend_Http_Client
Related issues: Attachments: - Curl.php.patch
When an HTTP server responds with "HTTP/1.1 100 Continue", it can also contain additional headers before the next "HTTP/1.1 ****". This isn't handled properly by Zend_Http_Client_Adapter_Curl::write(). Near the end of the method, it just strips "HTTP/1.1 100 Continue\r\n\r\n" from the response. Instead, the response should be removed until it finds the next "HTTP/1.1 ****" in the response.
The problem this creates is that the response object contains the second set of headers in the body. I found this problem when trying to use the cURL adapter with UPS web services.
Posted by Matthew Weier O'Phinney (matthew) on 2009-05-15T10:59:11.000+0000
Assigning to Benjamin Eberlei (who authored the curl adapter)
Posted by Benjamin Eberlei (beberlei) on 2009-05-15T12:03:16.000+0000
Hm, that is a hard one.
The API of Zend Http makes it hard to work with Curl 100 states. I see what i can come up with :-)
Posted by Jordan Ryan Moore (jordanryanmoore) on 2009-05-15T14:26:34.000+0000
The attached patch resolves the issue.
Posted by Benjamin Eberlei (beberlei) on 2009-06-01T03:47:06.000+0000
Can you send me an example HTTP ping pong that executes parts of the patched code? I have applied the patch locally and it seems not to interfere with the tests (all still passing). The new code also executes for several tests, but all those worked before also. I need an example of how i get the old code to fail :-)
Posted by Jordan Ryan Moore (jordanryanmoore) on 2009-06-01T08:13:42.000+0000
Here's the HTTP response that was causing the problem:
HTTP/1.1 100 Continue Expires: Mon, 01 Jun 2009 15:10:45 GMT Cache-Control: max-age=0, no-cache, no-store Pragma: no-cache
HTTP/1.1 200 OK Server: Apache/2.0.52 (Red Hat) mod_ssl/2.0.52 OpenSSL/0.9.7a Content-Length: 9226 Content-Type: text/xml Expires: Mon, 01 Jun 2009 15:10:46 GMT Cache-Control: max-age=0, no-cache, no-store Pragma: no-cache Date: Mon, 01 Jun 2009 15:10:46 GMT Connection: keep-alive
The rest of the body goes here...Posted by Derek Gallo (drock) on 2009-06-01T10:36:36.000+0000
This issue is more broad than just the HTTP/1.1 100 Continue case. You can get similar problems when trying to use the curl adapter to perform HTTP Digest Authentication. Curl will make a first request to the server to poll it for the appropriate nonce value to perform that hash. After this it sends another request with the appropriate credentials. Curl returns both sets of headers however, one for the 401 Authorization Required and then a second for the 220 OK response.
Zend_Http_Client is including the second 200 OK response headers as part of the response body since they are after the first double newlines. Additionally Zend_Http_Client is interpreting the first HTTP/1.1 401 as the response and falsely indicating that there was an error.
Here is some code that can reproduce the problem:
$curl_adapter = new Zend_Http_Client_Adapter_Curl();
$curl_adapter->setCurlOption(CURLOPT_HTTPAUTH,CURLAUTH_ANY); $curl_adapter->setCurlOption(CURLOPT_USERPWD,"user:password");
$http_client = new Zend_Http_Client('http://domain.com/digest/auth/url'); $http_client->setAdapter($curl_adapter);
$response = $http_client->request();
The provided path will only fix the HTTP/1.1 100 Continue case since it specifically looks for the 100 code to remove. A more general solution is required as it appears Curl returns the headers for every request it makes.
Posted by Jordan Ryan Moore (jordanryanmoore) on 2009-06-02T11:55:17.000+0000
Attached a more general solution.
Posted by Benjamin Eberlei (beberlei) on 2009-06-12T14:27:51.000+0000
Applied Jordans patchs, fixed in r16035 and merged back into 1.8 release branch. Thank you!