From e46decaa32f833437551c3e7a705679d454b65f9 Mon Sep 17 00:00:00 2001 From: foobar Date: Mon, 3 Sep 2001 02:31:56 +0000 Subject: [PATCH] First step for chunkifying the HTTP uploads. --- main/SAPI.c | 11 ++++++-- main/php_content_types.c | 6 ++-- main/rfc1867.c | 59 ++++++++++++++++++++++++++++++++++++---- 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/main/SAPI.c b/main/SAPI.c index 3201480b32c..160dcb81564 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -157,10 +157,15 @@ static void sapi_read_post_data(TSRMLS_D) if (oldchar) { *(p-1) = oldchar; } - post_reader_func(TSRMLS_C); + SG(request_info).content_type_dup = content_type; - if(PG(always_populate_raw_post_data) && sapi_module.default_post_reader) { - sapi_module.default_post_reader(TSRMLS_C); + + if(post_reader_func) { + post_reader_func(TSRMLS_C); + + if(PG(always_populate_raw_post_data) && sapi_module.default_post_reader) { + sapi_module.default_post_reader(TSRMLS_C); + } } } diff --git a/main/php_content_types.c b/main/php_content_types.c index 5ea60793750..07a53da164a 100644 --- a/main/php_content_types.c +++ b/main/php_content_types.c @@ -27,9 +27,9 @@ /* {{{ php_post_entries[] */ static sapi_post_entry php_post_entries[] = { - { DEFAULT_POST_CONTENT_TYPE, sizeof(DEFAULT_POST_CONTENT_TYPE)-1, sapi_read_standard_form_data, php_std_post_handler }, - { MULTIPART_CONTENT_TYPE, sizeof(MULTIPART_CONTENT_TYPE)-1, sapi_read_standard_form_data, rfc1867_post_handler }, - { NULL, 0, NULL } + { DEFAULT_POST_CONTENT_TYPE, sizeof(DEFAULT_POST_CONTENT_TYPE)-1, sapi_read_standard_form_data, php_std_post_handler }, + { MULTIPART_CONTENT_TYPE, sizeof(MULTIPART_CONTENT_TYPE)-1, NULL, rfc1867_post_handler }, + { NULL, 0, NULL, NULL } }; /* }}} */ diff --git a/main/rfc1867.c b/main/rfc1867.c index de247f655e9..0d6517af5c7 100644 --- a/main/rfc1867.c +++ b/main/rfc1867.c @@ -100,10 +100,10 @@ void destroy_uploaded_files_hash(TSRMLS_D) /* * Split raw mime stream up into appropriate components */ -static void php_mime_split(char *buf, int cnt, char *boundary, zval *array_ptr TSRMLS_DC) +static void php_mime_split(char *buf, int cnt, char *boundary, int len, zval *array_ptr TSRMLS_DC) { char *ptr, *loc, *loc2, *loc3, *s, *name, *filename, *u, *temp_filename; - int len, state = 0, Done = 0, rem, urem; + int state = 0, Done = 0, rem, urem; int eolsize; long bytes, max_file_size = 0; char *namebuf=NULL, *filenamebuf=NULL, *lbuf=NULL, @@ -126,7 +126,7 @@ static void php_mime_split(char *buf, int cnt, char *boundary, zval *array_ptr T ptr = buf; rem = cnt; - len = strlen(boundary); + while ((ptr - buf < cnt) && !Done) { switch (state) { case 0: /* Looking for mime boundary */ @@ -443,6 +443,22 @@ static void php_mime_split(char *buf, int cnt, char *boundary, zval *array_ptr T } +/* + * Reads post data chunk + * + */ +static int read_post_data_chunk(char *buf TSRMLS_DC) +{ + int read_bytes; + + read_bytes = sapi_module.read_post(buf, SAPI_POST_BLOCK_SIZE TSRMLS_CC); + + SG(read_post_bytes) += read_bytes; + + return read_bytes; +} + + SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) { char *boundary; @@ -454,6 +470,11 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) return; } + if (SG(request_info).content_length > SG(post_max_size)) { + sapi_module.sapi_error(E_COMPILE_ERROR, "POST Content-Length of %d bytes exceeds the limit of %d bytes", SG(request_info).content_length, SG(post_max_size)); + return; + } + boundary = strstr(content_type_dup, "boundary"); if (!boundary || !(boundary=strchr(boundary, '='))) { sapi_module.sapi_error(E_COMPILE_ERROR, "Missing boundary in multipart/form-data POST data"); @@ -468,12 +489,40 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) boundary[boundary_len] = '\0'; } + /* Temporary. Should be done same time as parsing. Maybe that Apache stuff.. */ + { + int allocated_bytes=SAPI_POST_BLOCK_SIZE+1, read_bytes; + + SG(request_info).post_data = emalloc(allocated_bytes); + + for (;;) { + read_bytes = read_post_data_chunk(SG(request_info).post_data+SG(read_post_bytes) TSRMLS_CC); + + if(read_bytes <= 0 || read_bytes < SAPI_POST_BLOCK_SIZE) { + break; + } + + if (SG(read_post_bytes) > SG(post_max_size)) { + php_error(E_WARNING, "Actual POST length does not match Content-Length, and exceeds %d bytes", SG(post_max_size)); + return; + } + + if (SG(read_post_bytes) + SAPI_POST_BLOCK_SIZE >= allocated_bytes) { + allocated_bytes = SG(read_post_bytes)+SAPI_POST_BLOCK_SIZE+1; + SG(request_info).post_data = erealloc(SG(request_info).post_data, allocated_bytes); + } + } + + SG(request_info).post_data[SG(read_post_bytes)] = 0; /* terminating NULL */ + SG(request_info).post_data_length = SG(read_post_bytes); + } + /* */ + if (SG(request_info).post_data) { - php_mime_split(SG(request_info).post_data, SG(request_info).post_data_length, boundary, array_ptr TSRMLS_CC); + php_mime_split(SG(request_info).post_data, SG(request_info).post_data_length, boundary, boundary_len, array_ptr TSRMLS_CC); } } - /* * Local variables: * tab-width: 4