]> granicus.if.org Git - php/commitdiff
Implement request #27814
authorVille Hukkamäki <vhu@iki.fi>
Thu, 28 Jul 2016 19:17:20 +0000 (19:17 +0000)
committerNikita Popov <nikic@php.net>
Thu, 4 Aug 2016 12:20:36 +0000 (14:20 +0200)
Construct HTTP request headers into smart_str and send whole
request in one go.

NEWS
ext/standard/http_fopen_wrapper.c

diff --git a/NEWS b/NEWS
index c20b29910ddd75ce646089bba187f628a6c92259..beed108cc731e39c3a5bbed0583a6696cde36374 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,8 @@ PHP                                                                        NEWS
 - Stream: 
   . Fixed bug #72743 (Out-of-bound read in php_stream_filter_create).
     (Loianhtuan)
+  . Implemented FR #27814 (Multiple small packets send for HTTP request).
+    (vhuk)
 
 04 Aug 2016, PHP 7.1.0beta2
 
index ec57cab2b6847523395ba8efdd968c89c6332334..5dbedb6c75f01425bee8214f832e0d34995f320c 100644 (file)
@@ -145,6 +145,7 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
        php_stream_filter *transfer_encoding = NULL;
        int response_code;
        zend_array *symbol_table;
+       smart_str req_buf = {0};
 
        ZVAL_UNDEF(&response_header);
        tmp_line[0] = '\0';
@@ -423,8 +424,7 @@ finish:
                strlcat(scratch, " HTTP/1.0\r\n", scratch_len);
        }
 
-       /* send it */
-       php_stream_write(stream, scratch, strlen(scratch));
+       smart_str_appends(&req_buf, scratch);
 
        if (context && (tmpzval = php_stream_context_get_option(context, "http", "header")) != NULL) {
                tmp = NULL;
@@ -554,7 +554,7 @@ finish:
                stmp = php_base64_encode((unsigned char*)scratch, strlen(scratch));
 
                if (snprintf(scratch, scratch_len, "Authorization: Basic %s\r\n", ZSTR_VAL(stmp)) > 0) {
-                       php_stream_write(stream, scratch, strlen(scratch));
+                       smart_str_appends(&req_buf, scratch);
                        php_stream_notify_info(context, PHP_STREAM_NOTIFY_AUTH_REQUIRED, NULL, 0);
                }
 
@@ -564,7 +564,7 @@ finish:
        /* if the user has configured who they are, send a From: line */
        if (((have_header & HTTP_HEADER_FROM) == 0) && FG(from_address)) {
                if (snprintf(scratch, scratch_len, "From: %s\r\n", FG(from_address)) > 0)
-                       php_stream_write(stream, scratch, strlen(scratch));
+                       smart_str_appends(&req_buf, scratch);
        }
 
        /* Send Host: header so name-based virtual hosts work */
@@ -572,10 +572,10 @@ finish:
                if ((use_ssl && resource->port != 443 && resource->port != 0) ||
                        (!use_ssl && resource->port != 80 && resource->port != 0)) {
                        if (snprintf(scratch, scratch_len, "Host: %s:%i\r\n", resource->host, resource->port) > 0)
-                               php_stream_write(stream, scratch, strlen(scratch));
+                               smart_str_appends(&req_buf, scratch);
                } else {
                        if (snprintf(scratch, scratch_len, "Host: %s\r\n", resource->host) > 0) {
-                               php_stream_write(stream, scratch, strlen(scratch));
+                               smart_str_appends(&req_buf, scratch);
                        }
                }
        }
@@ -587,7 +587,7 @@ finish:
         * HTTP/1.0 to avoid issues when the server respond with a HTTP/1.1
         * keep-alive response, which is the preferred response type. */
        if ((have_header & HTTP_HEADER_CONNECTION) == 0) {
-               php_stream_write_string(stream, "Connection: close\r\n");
+               smart_str_appends(&req_buf,"Connection: close\r\n");
        }
 
        if (context &&
@@ -610,7 +610,7 @@ finish:
                        ua = emalloc(ua_len + 1);
                        if ((ua_len = slprintf(ua, ua_len, _UA_HEADER, ua_str)) > 0) {
                                ua[ua_len] = 0;
-                               php_stream_write(stream, ua, ua_len);
+                               smart_str_appendl(&req_buf, ua, ua_len);
                        } else {
                                php_error_docref(NULL, E_WARNING, "Cannot construct User-agent header");
                        }
@@ -630,12 +630,12 @@ finish:
                                Z_TYPE_P(tmpzval) == IS_STRING && Z_STRLEN_P(tmpzval) > 0
                ) {
                        scratch_len = slprintf(scratch, scratch_len, "Content-Length: %zd\r\n", Z_STRLEN_P(tmpzval));
-                       php_stream_write(stream, scratch, scratch_len);
+                       smart_str_appendl(&req_buf, scratch, scratch_len);
                        have_header |= HTTP_HEADER_CONTENT_LENGTH;
                }
 
-               php_stream_write(stream, user_headers, strlen(user_headers));
-               php_stream_write(stream, "\r\n", sizeof("\r\n")-1);
+               smart_str_appends(&req_buf, user_headers);
+               smart_str_appends(&req_buf, "\r\n");
                efree(user_headers);
        }
 
@@ -645,19 +645,21 @@ finish:
                Z_TYPE_P(tmpzval) == IS_STRING && Z_STRLEN_P(tmpzval) > 0) {
                if (!(have_header & HTTP_HEADER_CONTENT_LENGTH)) {
                        scratch_len = slprintf(scratch, scratch_len, "Content-Length: %zd\r\n", Z_STRLEN_P(tmpzval));
-                       php_stream_write(stream, scratch, scratch_len);
+                       smart_str_appendl(&req_buf, scratch, scratch_len);
                }
                if (!(have_header & HTTP_HEADER_TYPE)) {
-                       php_stream_write(stream, "Content-Type: application/x-www-form-urlencoded\r\n",
-                               sizeof("Content-Type: application/x-www-form-urlencoded\r\n") - 1);
+                       smart_str_appends(&req_buf, "Content-Type: application/x-www-form-urlencoded\r\n");
                        php_error_docref(NULL, E_NOTICE, "Content-type not specified assuming application/x-www-form-urlencoded");
                }
-               php_stream_write(stream, "\r\n", sizeof("\r\n")-1);
-               php_stream_write(stream, Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval));
+               smart_str_appends(&req_buf, "\r\n");
+               smart_str_appendl(&req_buf, Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval));
        } else {
-               php_stream_write(stream, "\r\n", sizeof("\r\n")-1);
+               smart_str_appends(&req_buf, "\r\n");
        }
 
+       /* send it */
+       php_stream_write(stream, ZSTR_VAL(req_buf.s), ZSTR_LEN(req_buf.s));
+
        location[0] = '\0';
 
        symbol_table = zend_rebuild_symbol_table();
@@ -893,6 +895,9 @@ finish:
                }
        }
 out:
+
+       smart_str_free(&req_buf);
+
        if (protocol_version) {
                efree(protocol_version);
        }