- don't trap into any other transfer encoding than chunked
[m6w6/ext-http] / http_message_api.c
index 42bae1a79f247e3c01c719d07faf5aa97b5fca34..be4d0c33d2740b4b6f2a11fe481d9b05ed07f25a 100644 (file)
@@ -129,7 +129,7 @@ PHP_HTTP_API void _http_message_set_type(http_message *message, http_message_typ
 
 PHP_HTTP_API http_message *_http_message_parse_ex(http_message *msg, const char *message, size_t message_length TSRMLS_DC)
 {
-       char *body = NULL, *cr, *lf;
+       const char *body = NULL;
        zend_bool free_msg = msg ? 0 : 1;
 
        if ((!message) || (message_length < HTTP_MSG_MIN_SIZE)) {
@@ -138,7 +138,7 @@ PHP_HTTP_API http_message *_http_message_parse_ex(http_message *msg, const char
 
        msg = http_message_init(msg);
 
-       if (SUCCESS != http_parse_headers_cb(message, &msg->hdrs, 1, (http_info_callback) http_message_info_callback, &msg)) {
+       if (SUCCESS != http_parse_headers_cb(message, &msg->hdrs, 1, (http_info_callback) http_message_info_callback, (void **) &msg)) {
                if (free_msg) {
                        http_message_free(&msg);
                }
@@ -146,11 +146,33 @@ PHP_HTTP_API http_message *_http_message_parse_ex(http_message *msg, const char
        }
 
        /* header parsing stops at (CR)LF (CR)LF */
-       if (body = strstr(message, HTTP_CRLF HTTP_CRLF)) {
+       if (body = http_locate_body(message)) {
                zval *c;
                const char *continue_at = NULL;
 
-               body += lenof(HTTP_CRLF HTTP_CRLF);
+               /* message has chunked transfer encoding */
+               if ((c = http_message_header(msg, "Transfer-Encoding")) && (!strcasecmp("chunked", Z_STRVAL_P(c)))) {
+                       char *decoded;
+                       size_t decoded_len;
+
+                       /* decode and replace Transfer-Encoding with Content-Length header */
+                       if (continue_at = http_chunked_decode(body, message + message_length - body, &decoded, &decoded_len)) {
+                               phpstr_from_string_ex(PHPSTR(msg), decoded, decoded_len);
+                               efree(decoded);
+                               {
+                                       zval *len;
+                                       char *tmp;
+
+                                       spprintf(&tmp, 0, "%lu", (ulong) decoded_len);
+                                       MAKE_STD_ZVAL(len);
+                                       ZVAL_STRING(len, tmp, 0);
+
+                                       zend_hash_del(&msg->hdrs, "Transfer-Encoding", sizeof("Transfer-Encoding"));
+                                       zend_hash_add(&msg->hdrs, "Content-Length", sizeof("Content-Length"), (void *) &len, sizeof(zval *), NULL);
+                               }
+                       }
+               } else
+
                /* message has content-length header */
                if (c = http_message_header(msg, "Content-Length")) {
                        long len = atol(Z_STRVAL_P(c));
@@ -158,31 +180,6 @@ PHP_HTTP_API http_message *_http_message_parse_ex(http_message *msg, const char
                        continue_at = body + len;
                } else
 
-               /* message has chunked transfer encoding */
-               if (c = http_message_header(msg, "Transfer-Encoding")) {
-                       if (!strcasecmp("chunked", Z_STRVAL_P(c))) {
-                               char *decoded;
-                               size_t decoded_len;
-
-                               /* decode and replace Transfer-Encoding with Content-Length header */
-                               if (continue_at = http_chunked_decode(body, message + message_length - body, &decoded, &decoded_len)) {
-                                       phpstr_from_string_ex(PHPSTR(msg), decoded, decoded_len);
-                                       efree(decoded);
-                                       {
-                                               zval *len;
-                                               char *tmp;
-
-                                               spprintf(&tmp, 0, "%lu", (ulong) decoded_len);
-                                               MAKE_STD_ZVAL(len);
-                                               ZVAL_STRING(len, tmp, 0);
-
-                                               zend_hash_del(&msg->hdrs, "Transfer-Encoding", sizeof("Transfer-Encoding"));
-                                               zend_hash_add(&msg->hdrs, "Content-Length", sizeof("Content-Length"), (void *) &len, sizeof(zval *), NULL);
-                                       }
-                               }
-                       }
-               } else
-
                /* message has content-range header */
                if (c = http_message_header(msg, "Content-Range")) {
                        ulong start = 0, end = 0;
@@ -313,8 +310,7 @@ PHP_HTTP_API void _http_message_tostruct_recursive(http_message *msg, zval *obj
        zval strct;
        zval *headers;
        
-       Z_TYPE(strct) = IS_ARRAY;
-       Z_ARRVAL(strct) = HASH_OF(obj);
+       INIT_ZARR(strct, HASH_OF(obj));
        
        add_assoc_long(&strct, "type", msg->type);
        add_assoc_double(&strct, "httpVersion", msg->http.version);
@@ -335,7 +331,6 @@ PHP_HTTP_API void _http_message_tostruct_recursive(http_message *msg, zval *obj
        array_init(headers);
        zend_hash_copy(Z_ARRVAL_P(headers), &msg->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
        add_assoc_zval(&strct, "headers", headers);
-       zval_ptr_dtor(&headers);
        
        add_assoc_stringl(&strct, "body", PHPSTR_VAL(msg), PHPSTR_LEN(msg), 1);
        
@@ -354,8 +349,6 @@ PHP_HTTP_API void _http_message_tostruct_recursive(http_message *msg, zval *obj
        } else {
                add_assoc_null(&strct, "parentMessage");
        }
-       http_message_dtor(msg);
-       efree(msg);
 }
 
 PHP_HTTP_API STATUS _http_message_send(http_message *message TSRMLS_DC)
@@ -398,6 +391,8 @@ PHP_HTTP_API STATUS _http_message_send(http_message *message TSRMLS_DC)
                        char *uri = NULL;
                        zval **zhost, options, headers;
 
+                       INIT_PZVAL(&options);
+                       INIT_PZVAL(&headers);
                        array_init(&options);
                        array_init(&headers);
                        zend_hash_copy(Z_ARRVAL(headers), &message->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));