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