Commit:    449d4c0b1c6ea0f5dfe7b56c99d9fc4f2033d27c
Author:    Michael Wallner <m...@php.net>         Tue, 10 Sep 2013 13:13:33 
+0200
Parents:   e3e4d1b144a818b68e9332e75a35b2870c7253b8
Branches:  master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=449d4c0b1c6ea0f5dfe7b56c99d9fc4f2033d27c

Log:
make reading php://input JIT if enable_post_data_reading=0

Changed paths:
  M  ext/standard/php_fopen_wrapper.c
  M  main/SAPI.c
  M  main/SAPI.h

diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c
index ca0b92e..aa7924d 100644
--- a/ext/standard/php_fopen_wrapper.c
+++ b/ext/standard/php_fopen_wrapper.c
@@ -63,6 +63,12 @@ php_stream_ops php_stream_output_ops = {
        NULL  /* set_option */
 };
 
+typedef struct php_stream_input { /* {{{ */
+       php_stream **body_ptr;
+       off_t position;
+} php_stream_input_t;
+/* }}} */
+
 static size_t php_stream_input_write(php_stream *stream, const char *buf, 
size_t count TSRMLS_DC) /* {{{ */
 {
        return -1;
@@ -71,20 +77,52 @@ static size_t php_stream_input_write(php_stream *stream, 
const char *buf, size_t
 
 static size_t php_stream_input_read(php_stream *stream, char *buf, size_t 
count TSRMLS_DC) /* {{{ */
 {
-       php_stream *inner = stream->abstract;
+       php_stream_input_t *input = stream->abstract;
+       size_t read;
+       //fprintf(stderr, "Attempt to read %lu bytes (%lu)\n", count, 
SG(read_post_bytes));
+
+       if (!SG(post_read) && SG(read_post_bytes) < input->position + count) {
+               /* read requested data from SAPI */
+               int read_bytes = sapi_read_post_block(buf, count TSRMLS_CC);
+
+               //fprintf(stderr, "Did read %d bytes\n", read_bytes);
+               if (read_bytes > 0) {
+                       php_stream_seek(*input->body_ptr, 0, SEEK_END);
+                       php_stream_write(*input->body_ptr, buf, read_bytes);
+               }
+       }
+
+       php_stream_seek(*input->body_ptr, input->position, SEEK_SET);
+       read = (*input->body_ptr)->ops->read(*input->body_ptr, buf, count 
TSRMLS_CC);
+
+       if (!read || read == (size_t) -1) {
+               stream->eof = 1;
+       } else {
+               input->position += read;
+       }
+
+       return read;
+}
+/* }}} */
+
+static size_t php_stream_input_read_x(php_stream *stream, char *buf, size_t 
count TSRMLS_DC) /* {{{ */
+{
+       php_stream_input_t *input = stream->abstract;
+       php_stream *inner = *input->body_ptr;
 
        if (inner && inner->ops->read) {
                size_t read = inner->ops->read(inner, buf, count TSRMLS_CC);
                stream->eof = inner->eof;
                return read;
        }
-
        return -1;
 }
 /* }}} */
 
 static int php_stream_input_close(php_stream *stream, int close_handle 
TSRMLS_DC) /* {{{ */
 {
+       efree(stream->abstract);
+
        return 0;
 }
 /* }}} */
@@ -193,18 +231,23 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper 
*wrapper, const char *pa
        }
 
        if (!strcasecmp(path, "input")) {
+               php_stream_input_t *input;
+
                if ((options & STREAM_OPEN_FOR_INCLUDE) && 
!PG(allow_url_include) ) {
                        if (options & REPORT_ERRORS) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"URL file-access is disabled in the server configuration");
                        }
                        return NULL;
                }
-               if (SG(request_info).request_body) {
-                       php_stream_rewind(SG(request_info).request_body);
+
+               input = ecalloc(1, sizeof(*input));
+               if (*(input->body_ptr = &SG(request_info).request_body)) {
+                       php_stream_rewind(*input->body_ptr);
                } else {
-                       sapi_read_standard_form_data(TSRMLS_C);
+                       *input->body_ptr = 
php_stream_temp_create(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE);
                }
-               return php_stream_alloc(&php_stream_input_ops, 
SG(request_info).request_body, 0, "rb");
+
+               return php_stream_alloc(&php_stream_input_ops, input, 0, "rb");
        }
 
        if (!strcasecmp(path, "stdin")) {
diff --git a/main/SAPI.c b/main/SAPI.c
index ccfb1e5..9c8bcb1 100644
--- a/main/SAPI.c
+++ b/main/SAPI.c
@@ -180,10 +180,6 @@ SAPI_API void sapi_handle_post(void *arg TSRMLS_DC)
 {
        if (SG(request_info).post_entry && SG(request_info).content_type_dup) {
                
SG(request_info).post_entry->post_handler(SG(request_info).content_type_dup, 
arg TSRMLS_CC);
-               /*if (SG(request_info).request_body) {
-                       php_stream_close(SG(request_info).request_body);
-                       SG(request_info).request_body = NULL;
-               }*/
                efree(SG(request_info).content_type_dup);
                SG(request_info).content_type_dup = NULL;
        }
@@ -249,43 +245,61 @@ static void sapi_read_post_data(TSRMLS_D)
        }
 }
 
-
-SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data)
+SAPI_API int sapi_read_post_block(char *buffer, size_t buflen TSRMLS_DC)
 {
        int read_bytes;
 
+       if (!sapi_module.read_post) {
+               return -1;
+       }
+
+       read_bytes = sapi_module.read_post(buffer, buflen TSRMLS_CC);
+
+       if (read_bytes > 0) {
+               /* gogo */
+               SG(read_post_bytes) += read_bytes;
+       }
+       if (read_bytes < buflen) {
+               /* done */
+               SG(post_read) = 1;
+       }
+
+       return read_bytes;
+}
+
+SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data)
+{
        if ((SG(post_max_size) > 0) && (SG(request_info).content_length > 
SG(post_max_size))) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "POST 
Content-Length of %ld bytes exceeds the limit of %ld bytes",
                                        SG(request_info).content_length, 
SG(post_max_size));
                return;
        }
+
        SG(request_info).request_body = 
php_stream_temp_create(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE);
 
        if (sapi_module.read_post) {
+               int read_bytes;
+
                for (;;) {
                        char buffer[SAPI_POST_BLOCK_SIZE];
 
-                       read_bytes = sapi_module.read_post(buffer, 
SAPI_POST_BLOCK_SIZE TSRMLS_CC);
-                       if (read_bytes<=0) {
-                               /* failure */
-                               break;
+                       read_bytes = sapi_read_post_block(buffer, 
SAPI_POST_BLOCK_SIZE TSRMLS_CC);
+
+                       if (read_bytes > 0) {
+                               php_stream_write(SG(request_info).request_body, 
buffer, read_bytes);
                        }
-                       SG(read_post_bytes) += read_bytes;
 
                        if ((SG(post_max_size) > 0) && (SG(read_post_bytes) > 
SG(post_max_size))) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"Actual POST length does not match Content-Length, and exceeds %ld bytes", 
SG(post_max_size));
                                break;
                        }
 
-                       php_stream_write(SG(request_info).request_body, buffer, 
read_bytes);
-
                        if (read_bytes < SAPI_POST_BLOCK_SIZE) {
                                /* done */
                                break;
                        }
                }
-
-       php_stream_rewind(SG(request_info).request_body);
+               php_stream_rewind(SG(request_info).request_body);
        }
 }
 
@@ -455,21 +469,13 @@ SAPI_API void sapi_activate(TSRMLS_D)
 
        /* Handle request method */
        if (SG(server_context)) {
-               if (SG(request_info).request_method) {
-                       if (PG(enable_post_data_reading)
-                       &&      SG(request_info).content_type
-                       && !strcmp(SG(request_info).request_method, "POST")) {
-                               /* HTTP POST may contain form data to be 
processed into variables
-                                * depending on given content type */
-                               sapi_read_post_data(TSRMLS_C);
-                       } else {
-                               /* Any other method with content payload will 
fill php://input stream.
-                                * It's up to the webserver to decide whether 
to allow a method or not. */
-                               SG(request_info).content_type_dup = NULL;
-                               if (sapi_module.default_post_reader) {
-                                       
sapi_module.default_post_reader(TSRMLS_C);
-                               }
-                       }
+               if (PG(enable_post_data_reading)
+               &&      SG(request_info).content_type
+               &&  SG(request_info).request_method
+               && !strcmp(SG(request_info).request_method, "POST")) {
+                       /* HTTP POST may contain form data to be processed into 
variables
+                        * depending on given content type */
+                       sapi_read_post_data(TSRMLS_C);
                } else {
                        SG(request_info).content_type_dup = NULL;
                }
@@ -500,15 +506,15 @@ SAPI_API void sapi_deactivate(TSRMLS_D)
        zend_llist_destroy(&SG(sapi_headers).headers);
        if (SG(request_info).request_body) {
                SG(request_info).request_body = NULL;
-       }  else if (SG(server_context)) {
-               if(sapi_module.read_post) { 
+       } else if (SG(server_context)) {
+               if (!SG(post_read)) {
                        /* make sure we've consumed all request input data */
                        char dummy[SAPI_POST_BLOCK_SIZE];
                        int read_bytes;
 
-                       while((read_bytes = sapi_module.read_post(dummy, 
sizeof(dummy)-1 TSRMLS_CC)) > 0) {
-                               SG(read_post_bytes) += read_bytes;
-                       }
+                       do {
+                               read_bytes = sapi_read_post_block(dummy, 
SAPI_POST_BLOCK_SIZE TSRMLS_CC);
+                       } while (SAPI_POST_BLOCK_SIZE == read_bytes);
                }
        }
        if (SG(request_info).auth_user) {
diff --git a/main/SAPI.h b/main/SAPI.h
index ed6b049..5525a2a 100644
--- a/main/SAPI.h
+++ b/main/SAPI.h
@@ -120,6 +120,7 @@ typedef struct _sapi_globals_struct {
        sapi_request_info request_info;
        sapi_headers_struct sapi_headers;
        int64_t read_post_bytes;
+       unsigned char post_read;
        unsigned char headers_sent;
        struct stat global_stat;
        char *default_mimetype;
@@ -188,7 +189,7 @@ SAPI_API int sapi_add_header_ex(char *header_line, uint 
header_line_len, zend_bo
 SAPI_API int sapi_send_headers(TSRMLS_D);
 SAPI_API void sapi_free_header(sapi_header_struct *sapi_header);
 SAPI_API void sapi_handle_post(void *arg TSRMLS_DC);
-
+SAPI_API int sapi_read_post_block(char *buffer, size_t buflen TSRMLS_DC);
 SAPI_API int sapi_register_post_entries(sapi_post_entry *post_entry TSRMLS_DC);
 SAPI_API int sapi_register_post_entry(sapi_post_entry *post_entry TSRMLS_DC);
 SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry 
TSRMLS_DC);
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to