fix bug #69357
authorMichael Wallner <mike@php.net>
Wed, 8 Apr 2015 10:05:59 +0000 (12:05 +0200)
committerMichael Wallner <mike@php.net>
Wed, 8 Apr 2015 10:05:59 +0000 (12:05 +0200)
php_http_client_curl.c
tests/bug69357.phpt [new file with mode: 0644]
tests/helper/upload.inc [new file with mode: 0644]

index 43a93371157f4ecb3b11bc6d307eec8c3c43cdd9..9ebffa395f9da893751b778d60d3f72ea05834c5 100644 (file)
@@ -584,7 +584,14 @@ static php_http_message_t *php_http_curlm_responseparser(php_http_client_curl_ha
 
        response = php_http_message_init(NULL, 0, h->response.body TSRMLS_CC);
        php_http_header_parser_init(&parser TSRMLS_CC);
-       php_http_header_parser_parse(&parser, &h->response.headers, PHP_HTTP_HEADER_PARSER_CLEANUP, &response->hdrs, (php_http_info_callback_t) php_http_message_info_callback, (void *) &response);
+       while (h->response.headers.used) {
+               php_http_header_parser_state_t st = php_http_header_parser_parse(&parser,
+                               &h->response.headers, PHP_HTTP_HEADER_PARSER_CLEANUP, &response->hdrs,
+                               (php_http_info_callback_t) php_http_message_info_callback, (void *) &response);
+               if (PHP_HTTP_HEADER_PARSER_STATE_FAILURE == st) {
+                       break;
+               }
+       }
        php_http_header_parser_dtor(&parser);
 
        /* move body to right message */
@@ -594,6 +601,7 @@ static php_http_message_t *php_http_curlm_responseparser(php_http_client_curl_ha
                while (ptr->parent) {
                        ptr = ptr->parent;
                }
+               php_http_message_body_free(&response->body);
                response->body = ptr->body;
                ptr->body = NULL;
        }
diff --git a/tests/bug69357.phpt b/tests/bug69357.phpt
new file mode 100644 (file)
index 0000000..ac93baf
--- /dev/null
@@ -0,0 +1,41 @@
+--TEST--
+Bug #69357 (HTTP/1.1 100 Continue overriding subsequent 200 response code with PUT request)
+--SKIPIF--
+<?php
+include "skipif.inc";
+skip_client_test();
+?>
+--FILE--
+<?php 
+echo "Test\n";
+
+include "helper/server.inc";
+
+server("upload.inc", function($port) {
+       $r = new \http\Client\Request("PUT", "http://localhost:$port/", [],
+                       (new \http\Message\Body)->append("foo")
+       );
+       $c = new \http\Client;
+       $c->setOptions(["expect_100_timeout" => 0]);
+       $c->enqueue($r)->send();
+       
+       var_dump($c->getResponse($r)->getInfo());
+       var_dump($c->getResponse($r)->getHeaders());
+});
+
+?>
+===DONE===
+--EXPECTF--
+Test
+string(15) "HTTP/1.1 200 OK"
+array(4) {
+  ["Accept-Ranges"]=>
+  string(5) "bytes"
+  ["Etag"]=>
+  string(10) ""%x""
+  ["X-Original-Transfer-Encoding"]=>
+  string(7) "chunked"
+  ["Content-Length"]=>
+  int(%d)
+}
+===DONE===
diff --git a/tests/helper/upload.inc b/tests/helper/upload.inc
new file mode 100644 (file)
index 0000000..9502d2b
--- /dev/null
@@ -0,0 +1,20 @@
+<?php 
+
+include "server.inc";
+
+serve(function($client) {
+       $request = new http\Message($client, false);
+       
+       if ($request->getHeader("Expect") === "100-continue") {
+               $response = new http\Env\Response;
+               $response->setEnvRequest($request);
+               $response->setResponseCode(100);
+               $response->send($client);
+       }
+       
+       /* return the initial message as response body */
+       $response = new http\Env\Response;
+       /* avoid OOM with $response->getBody()->append($request); */
+       $request->toStream($response->getBody()->getResource());
+       $response->send($client);
+});