add some more tests; fix leak in php_http_env_get_response_header(); honor content...
authorMichael Wallner <mike@php.net>
Tue, 13 Mar 2012 22:02:13 +0000 (22:02 +0000)
committerMichael Wallner <mike@php.net>
Tue, 13 Mar 2012 22:02:13 +0000 (22:02 +0000)
13 files changed:
php_http_env.c
php_http_message.c
php_http_message_body.c
phpunit/MessageBodyTest.php
tests/data/message_r_multipart_put.txt [new file with mode: 0644]
tests/envrequestbody001.phpt [new file with mode: 0644]
tests/envrequestheader001.phpt [new file with mode: 0644]
tests/envresponseheader001.phpt
tests/envresponseranges001.phpt [new file with mode: 0644]
tests/message002.phpt
tests/message003.phpt [new file with mode: 0644]
tests/negotiate001.phpt
tests/response003.phpt [new file with mode: 0644]

index d2fe620a75a6336e544fe8e0d4eb63ee8c431ea9..96c757be07463be4fa3a3ec9d4b390e5ea3fed42 100644 (file)
@@ -52,7 +52,7 @@ PHP_HTTP_API void php_http_env_get_request_headers(HashTable *headers TSRMLS_DC)
 
                if (SUCCESS == zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void *) &hsv) && Z_TYPE_PP(hsv) == IS_ARRAY) {
                        FOREACH_KEY(pos, *hsv, key) {
-                               if (key.type == HASH_KEY_IS_STRING && key.len > 6 && !strncmp(key.str, "HTTP_", 5)) {
+                               if (key.type == HASH_KEY_IS_STRING && key.len > 6 && *key.str == 'H' && !strncmp(key.str, "HTTP_", 5)) {
                                        key.len -= 5;
                                        key.str = php_http_pretty_key(estrndup(key.str + 5, key.len - 1), key.len - 1, 1, 1);
 
@@ -60,6 +60,14 @@ PHP_HTTP_API void php_http_env_get_request_headers(HashTable *headers TSRMLS_DC)
                                        Z_ADDREF_P(*header);
                                        zend_symtable_update(PHP_HTTP_G->env.request.headers, key.str, key.len, (void *) header, sizeof(zval *), NULL);
 
+                                       efree(key.str);
+                               } else if (key.type == HASH_KEY_IS_STRING && key.len > 9 && *key.str == 'C' && !strncmp(key.str, "CONTENT_", 8)) {
+                                       key.str = php_http_pretty_key(estrndup(key.str, key.len - 1), key.len - 1, 1, 1);
+
+                                       zend_hash_get_current_data_ex(Z_ARRVAL_PP(hsv), (void *) &header, &pos);
+                                       Z_ADDREF_P(*header);
+                                       zend_symtable_update(PHP_HTTP_G->env.request.headers, key.str, key.len, (void *) header, sizeof(zval *), NULL);
+
                                        efree(key.str);
                                }
                        }
@@ -360,7 +368,7 @@ PHP_HTTP_API char *php_http_env_get_response_header(const char *name_str, size_t
        char *val = NULL;
        HashTable headers;
 
-       zend_hash_init(&headers, 0, NULL, NULL, 0);
+       zend_hash_init(&headers, 0, NULL, ZVAL_PTR_DTOR, 0);
        if (SUCCESS == php_http_env_get_response_headers(&headers TSRMLS_CC)) {
                zval **zvalue;
                char *key = php_http_pretty_key(estrndup(name_str, name_len), name_len, 1, 1);
@@ -661,7 +669,7 @@ PHP_METHOD(HttpEnv, getRequestBody)
                        php_http_message_body_t *body = php_http_env_get_request_body(TSRMLS_C);
 
                        if (SUCCESS == php_http_new(&ov, class_entry, (php_http_new_t) php_http_message_body_object_new_ex, php_http_message_body_class_entry, php_http_message_body_copy(body, NULL, 0), NULL TSRMLS_CC)) {
-                               RETURN_OBJVAL(ov, 0);
+                               RETVAL_OBJVAL(ov, 0);
                        }
                }
        } end_error_handling();
index 7dbf6085eb2b49004505ac5b1cbf413d66c66e12..58d8ee9d05c785cb46494e9eaefbd0d60cd4a530 100644 (file)
@@ -69,14 +69,6 @@ PHP_HTTP_API php_http_message_t *php_http_message_init_env(php_http_message_t *m
                        if ((sval = php_http_env_get_server_var(ZEND_STRL("REQUEST_URI"), 1 TSRMLS_CC))) {
                                message->http.info.request.url = estrdup(Z_STRVAL_P(sval));
                        }
-                       if ((sval = php_http_env_get_server_var(ZEND_STRL("CONTENT_TYPE"), 1 TSRMLS_CC))) {
-                               Z_ADDREF_P(sval);
-                               zend_hash_update(&message->hdrs, "Content-Type", sizeof("Content-Type"), (void *) &sval, sizeof(zval *), NULL);
-                       }
-                       if ((sval = php_http_env_get_server_var(ZEND_STRL("CONTENT_LENGTH"), 1 TSRMLS_CC))) {
-                               Z_ADDREF_P(sval);
-                               zend_hash_update(&message->hdrs, "Content-Length", sizeof("Content-Length"), (void *) &sval, sizeof(zval *), NULL);
-                       }
                        
                        php_http_env_get_request_headers(&message->hdrs TSRMLS_CC);
 
index 34b44f898b91c7935226298720148caf8cdb6580..e02c2e4377c30de80ac678d32a3e7f5b845de776 100644 (file)
@@ -425,6 +425,7 @@ static size_t splitbody(void *opaque, char *buf, size_t len TSRMLS_DC)
                if ((boundary = php_http_locate_str(buf, len, arg->boundary_str + first_boundary, arg->boundary_len - first_boundary))) {
                        size_t real_boundary_len = arg->boundary_len - 1, cut;
                        const char *real_boundary = boundary + !first_boundary;
+                       int eol_len = 0;
 
                        if (buf + len <= real_boundary + real_boundary_len) {
                                /* if we just have enough data for the boundary, it's just a byte too less */
@@ -444,7 +445,12 @@ static size_t splitbody(void *opaque, char *buf, size_t len TSRMLS_DC)
                        len -= cut;
                        consumed += cut;
 
-                       if (buf == php_http_locate_bin_eol(buf, len, NULL)) {
+                       if (buf == php_http_locate_bin_eol(buf, len, &eol_len)) {
+                               /* skip CRLF */
+                               buf += eol_len;
+                               len -= eol_len;
+                               consumed += eol_len;
+
                                if (!first_boundary) {
                                        /* advance messages */
                                        php_http_message_t *msg;
index 708d3174863d545028f9f3279817fcafd04e7374..0218af1bc3550908f333bca3d461f9b8d06bce72 100644 (file)
@@ -106,4 +106,8 @@ class MessageBodyTest extends PHPUnit_Framework_TestCase {
         );
         $this->assertEquals($s, (string) $this->file);
     }
+
+    function testClone() {
+        $this->assertEquals((string) $this->file, (string) clone $this->file);
+    }
 }
diff --git a/tests/data/message_r_multipart_put.txt b/tests/data/message_r_multipart_put.txt
new file mode 100644 (file)
index 0000000..52776d4
--- /dev/null
@@ -0,0 +1,65 @@
+PUT /docs/ HTTP/1.1
+User-Agent: curl/7.24.0 (x86_64-unknown-linux-gnu) libcurl/7.24.0 OpenSSL/1.0.0g zlib/1.2.6 libssh2/1.3.0
+Host: drop
+Accept: */*
+Content-Length: 2284
+Expect: 100-continue
+Content-Type: multipart/form-data; boundary=----------------------------6e182425881c
+
+------------------------------6e182425881c
+Content-Disposition: form-data; name="LICENSE"; filename="LICENSE"
+Content-Type: application/octet-stream
+
+Copyright (c) 2011-2012, Michael Wallner <mike@iworks.at>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without 
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, 
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright 
+      notice, this list of conditions and the following disclaimer in the 
+      documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+------------------------------6e182425881c
+Content-Disposition: form-data; name="composer"; filename="composer.json"
+Content-Type: application/octet-stream
+
+{
+    "name": "mike_php_net/autocracy",
+    "type": "library",
+    "description": "http\\Controller preserves your autocracy",
+    "keywords": ["http", "controller", "pecl", "pecl_http"],
+    "homepage": "http://github.com/mike-php-net/autocracy",
+    "license": "BSD-2",
+    "authors": [
+        {
+            "name": "Michael Wallner",
+            "email": "mike@php.net"
+        }
+    ],
+    "require": {
+        "php": ">=5.4.0",
+        "pecl/pecl_http": "2.*"
+    },
+    "autoload": {
+        "psr-0": {
+            "http\\Controller": "lib"
+        }
+    }
+}
+
+------------------------------6e182425881c--
diff --git a/tests/envrequestbody001.phpt b/tests/envrequestbody001.phpt
new file mode 100644 (file)
index 0000000..2351186
--- /dev/null
@@ -0,0 +1,15 @@
+--TEST--
+env request body
+--SKIPIF--
+<? include "skipif.inc";
+--PUT--
+Content-Type: skip/me
+foo
+--FILE--
+<?
+var_dump((string) \http\Env::getRequestBody());
+?>
+DONE
+--EXPECT--
+string(3) "foo"
+DONE
diff --git a/tests/envrequestheader001.phpt b/tests/envrequestheader001.phpt
new file mode 100644 (file)
index 0000000..2a6a940
--- /dev/null
@@ -0,0 +1,30 @@
+--TEST--
+request header
+--SKIPIF--
+<? include "skipif.inc";
+--POST--
+a=b
+--ENV--
+HTTP_HOST=foo.bar
+HTTP_ACCEPT=*/*
+--FILE--
+<?
+
+var_dump(http\Env::getRequestHeader("nono"));
+var_dump(http\Env::getRequestHeader("Host"));
+var_dump(http\Env::getRequestHeader("content-type"));
+var_dump(http\Env::getRequestHeader());
+--EXPECTF--
+NULL
+string(%d) "foo.bar"
+string(%d) "application/x-www-form-urlencoded"
+array(4) {
+  ["Host"]=>
+  string(7) "foo.bar"
+  ["Accept"]=>
+  string(3) "*/*"
+  ["Content-Length"]=>
+  string(1) "3"
+  ["Content-Type"]=>
+  string(33) "application/x-www-form-urlencoded"
+}
index fe7fc75cb1a8d985aefbfcef858fadfe3a980ddc..194f7d78f811928b4440eb55d94320c2835caebe 100644 (file)
@@ -5,17 +5,35 @@ env response header
 --FILE--
 <?php
 
+http\Env::setResponseCode(201);
+
 http\Env::setResponseHeader("No", "way");
 http\Env::setResponseHeader("Foo", "bar");
 http\Env::setResponseHeader("No", null);
+http\Env::setResponseHeader("More", array("than", "what's", "good"));
+
 
+print_r(http\Env::getResponseCode()); echo "\n";
+print_r(http\Env::getResponseHeader("Foo")); echo "\n";
 print_r(http\Env::getResponseHeader());
+print_r(http\Env::getResponseStatusForCode(201));
 
 --EXPECTHEADERS--
 Foo: bar
 --EXPECTF--
+201
+bar
 Array
 (
     [X-Powered-By] => %s
     [Foo] => bar
+    [More] => Array
+        (
+            [0] => than
+            [1] => what's
+            [2] => good
+        )
+
+    [Content-Type] => text/html
 )
+Created
diff --git a/tests/envresponseranges001.phpt b/tests/envresponseranges001.phpt
new file mode 100644 (file)
index 0000000..ec8fe2f
--- /dev/null
@@ -0,0 +1,49 @@
+--TEST--
+ranges
+--SKIPIF--
+<? include "skipif.php";
+--XFAIL--
+line endings
+--GET--
+a=b
+--ENV--
+HTTP_RANGE=bytes=-3,000-001,1-1,0-0,100-
+--FILE--
+<?php
+
+$r = new http\Env\Response;
+$r->setBody(new http\Message\Body(fopen(__FILE__, "rb")));
+$r->send();
+
+?>
+--EXPECTF--
+--%s\r
+Content-Type: application/octet-stream\r
+Content-Range: bytes 107-109/110\r
+\r
+?>
+\r
+--%s\r
+Content-Type: application/octet-stream\r
+Content-Range: bytes 0-1/110\r
+\r
+<?\r
+--%s\r
+Content-Type: application/octet-stream\r
+Content-Range: bytes 1-1/110\r
+\r
+?\r
+--%s\r
+Content-Type: application/octet-stream\r
+Content-Range: bytes 0-0/110\r
+\r
+<\r
+--%s\r
+Content-Type: application/octet-stream\r
+Content-Range: bytes 100-109/110\r
+\r
+nd();
+
+?>
+\r
+--%s--
\ No newline at end of file
index bb19875844411b0bfc810c884329f5b04a358338..005f09898201e2c6d04b1d11654db26dc8a9e4b7 100644 (file)
@@ -47,12 +47,12 @@ object(%s)#%d (13) {
   string(3) "1.1"
   ["headers":protected]=>
   array(4) {
-    ["Content-Type"]=>
-    string(14) "test/something"
-    ["Content-Length"]=>
-    string(1) "3"
     ["X-Test"]=>
     string(4) "test"
+    ["Content-Length"]=>
+    string(1) "3"
+    ["Content-Type"]=>
+    string(14) "test/something"
     ["Cookie"]=>
     string(7) "foo=bar"
   }
diff --git a/tests/message003.phpt b/tests/message003.phpt
new file mode 100644 (file)
index 0000000..0ce10b2
--- /dev/null
@@ -0,0 +1,81 @@
+--TEST--
+multipart message
+--SKIPIF--
+<? include "skipif.inc";
+--FILE--
+<?
+$m = new http\Message(fopen(__DIR__."/data/message_r_multipart_put.txt","rb"));
+if ($m->isMultipart($boundary)) {
+    var_dump($boundary);
+
+    foreach ($m->splitMultipartBody() as $mm) {
+        echo "===\n",$mm,"===\n";
+    }
+}
+?>
+DONE
+--EXPECTF--
+string(40) "----------------------------6e182425881c"
+===
+Content-Disposition: form-data; name="composer"; filename="composer.json"
+Content-Type: application/octet-stream
+Content-Length: 567
+
+{
+    "name": "mike_php_net/autocracy",
+    "type": "library",
+    "description": "http\\Controller preserves your autocracy",
+    "keywords": ["http", "controller", "pecl", "pecl_http"],
+    "homepage": "http://github.com/mike-php-net/autocracy",
+    "license": "BSD-2",
+    "authors": [
+        {
+            "name": "Michael Wallner",
+            "email": "mike@php.net"
+        }
+    ],
+    "require": {
+        "php": ">=5.4.0",
+        "pecl/pecl_http": "2.*"
+    },
+    "autoload": {
+        "psr-0": {
+            "http\\Controller": "lib"
+        }
+    }
+}
+
+
+===
+===
+Content-Disposition: form-data; name="LICENSE"; filename="LICENSE"
+Content-Type: application/octet-stream
+Content-Length: 1354
+
+Copyright (c) 2011-2012, Michael Wallner <mike@iworks.at>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without 
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, 
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright 
+      notice, this list of conditions and the following disclaimer in the 
+      documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+===
+DONE
index d7bd755d300733b245c26168e8a06feacf758aed..d384b87f06cb14da76e538e40f8d7669d6c99b90 100644 (file)
@@ -49,6 +49,14 @@ echo "$ln: "; print_r($lnr);
 $ln = http\Env::negotiateLanguage(array("nl", "fr", "en"), $lnr);
 echo "$ln: "; print_r($lnr);
 ?>
+
+CUSTOM
+
+<?
+$cc = http\Env::negotiate("a, a.b;q=0.9, c.d;q=0, *.* ; q=0.1",
+    array("a.x", "c.d", "c.e", "a.b"), ".", $ccr);
+echo "$cc: "; print_r($ccr);
+?>
 DONE
 --EXPECT--
 CONTENT TYPE
@@ -108,4 +116,13 @@ en: Array
 (
     [en] => 0.8
 )
+
+CUSTOM
+
+a.b: Array
+(
+    [a.b] => 0.9
+    [c.e] => 0.1
+    [a.x] => 0.1
+)
 DONE
diff --git a/tests/response003.phpt b/tests/response003.phpt
new file mode 100644 (file)
index 0000000..1e9e0ab
--- /dev/null
@@ -0,0 +1,25 @@
+--TEST--
+response ranges
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--ENV--
+HTTP_RANGE=bytes=2-4
+--GET--
+a=b
+--FILE--
+<?php
+
+$r = new http\Env\Response;
+$r->setContentType("text/plain");
+$r->setContentDisposition(
+    http\Env\Response::CONTENT_DISPOSITION_ATTACHMENT,
+    basename(__FILE__)
+);
+$r->setBody(new http\Message\Body(fopen(__FILE__, "rb")));
+$r->send();
+
+?>
+--EXPECTHEADERS--
+Content-Type: text/plain
+--EXPECTF--
+php