Skip to content

Commit e46deca

Browse files
author
foobar
committed
First step for chunkifying the HTTP uploads.
1 parent 0cb6a31 commit e46deca

File tree

3 files changed

+65
-11
lines changed

3 files changed

+65
-11
lines changed

main/SAPI.c

+8-3
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,15 @@ static void sapi_read_post_data(TSRMLS_D)
157157
if (oldchar) {
158158
*(p-1) = oldchar;
159159
}
160-
post_reader_func(TSRMLS_C);
160+
161161
SG(request_info).content_type_dup = content_type;
162-
if(PG(always_populate_raw_post_data) && sapi_module.default_post_reader) {
163-
sapi_module.default_post_reader(TSRMLS_C);
162+
163+
if(post_reader_func) {
164+
post_reader_func(TSRMLS_C);
165+
166+
if(PG(always_populate_raw_post_data) && sapi_module.default_post_reader) {
167+
sapi_module.default_post_reader(TSRMLS_C);
168+
}
164169
}
165170
}
166171

main/php_content_types.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@
2727
/* {{{ php_post_entries[]
2828
*/
2929
static sapi_post_entry php_post_entries[] = {
30-
{ DEFAULT_POST_CONTENT_TYPE, sizeof(DEFAULT_POST_CONTENT_TYPE)-1, sapi_read_standard_form_data, php_std_post_handler },
31-
{ MULTIPART_CONTENT_TYPE, sizeof(MULTIPART_CONTENT_TYPE)-1, sapi_read_standard_form_data, rfc1867_post_handler },
32-
{ NULL, 0, NULL }
30+
{ DEFAULT_POST_CONTENT_TYPE, sizeof(DEFAULT_POST_CONTENT_TYPE)-1, sapi_read_standard_form_data, php_std_post_handler },
31+
{ MULTIPART_CONTENT_TYPE, sizeof(MULTIPART_CONTENT_TYPE)-1, NULL, rfc1867_post_handler },
32+
{ NULL, 0, NULL, NULL }
3333
};
3434
/* }}} */
3535

main/rfc1867.c

+54-5
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@ void destroy_uploaded_files_hash(TSRMLS_D)
100100
/*
101101
* Split raw mime stream up into appropriate components
102102
*/
103-
static void php_mime_split(char *buf, int cnt, char *boundary, zval *array_ptr TSRMLS_DC)
103+
static void php_mime_split(char *buf, int cnt, char *boundary, int len, zval *array_ptr TSRMLS_DC)
104104
{
105105
char *ptr, *loc, *loc2, *loc3, *s, *name, *filename, *u, *temp_filename;
106-
int len, state = 0, Done = 0, rem, urem;
106+
int state = 0, Done = 0, rem, urem;
107107
int eolsize;
108108
long bytes, max_file_size = 0;
109109
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
126126

127127
ptr = buf;
128128
rem = cnt;
129-
len = strlen(boundary);
129+
130130
while ((ptr - buf < cnt) && !Done) {
131131
switch (state) {
132132
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
443443
}
444444

445445

446+
/*
447+
* Reads post data chunk
448+
*
449+
*/
450+
static int read_post_data_chunk(char *buf TSRMLS_DC)
451+
{
452+
int read_bytes;
453+
454+
read_bytes = sapi_module.read_post(buf, SAPI_POST_BLOCK_SIZE TSRMLS_CC);
455+
456+
SG(read_post_bytes) += read_bytes;
457+
458+
return read_bytes;
459+
}
460+
461+
446462
SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler)
447463
{
448464
char *boundary;
@@ -454,6 +470,11 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler)
454470
return;
455471
}
456472

473+
if (SG(request_info).content_length > SG(post_max_size)) {
474+
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));
475+
return;
476+
}
477+
457478
boundary = strstr(content_type_dup, "boundary");
458479
if (!boundary || !(boundary=strchr(boundary, '='))) {
459480
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)
468489
boundary[boundary_len] = '\0';
469490
}
470491

492+
/* <FIXME> Temporary. Should be done same time as parsing. Maybe that Apache stuff.. */
493+
{
494+
int allocated_bytes=SAPI_POST_BLOCK_SIZE+1, read_bytes;
495+
496+
SG(request_info).post_data = emalloc(allocated_bytes);
497+
498+
for (;;) {
499+
read_bytes = read_post_data_chunk(SG(request_info).post_data+SG(read_post_bytes) TSRMLS_CC);
500+
501+
if(read_bytes <= 0 || read_bytes < SAPI_POST_BLOCK_SIZE) {
502+
break;
503+
}
504+
505+
if (SG(read_post_bytes) > SG(post_max_size)) {
506+
php_error(E_WARNING, "Actual POST length does not match Content-Length, and exceeds %d bytes", SG(post_max_size));
507+
return;
508+
}
509+
510+
if (SG(read_post_bytes) + SAPI_POST_BLOCK_SIZE >= allocated_bytes) {
511+
allocated_bytes = SG(read_post_bytes)+SAPI_POST_BLOCK_SIZE+1;
512+
SG(request_info).post_data = erealloc(SG(request_info).post_data, allocated_bytes);
513+
}
514+
}
515+
516+
SG(request_info).post_data[SG(read_post_bytes)] = 0; /* terminating NULL */
517+
SG(request_info).post_data_length = SG(read_post_bytes);
518+
}
519+
/* </FIXME> */
520+
471521
if (SG(request_info).post_data) {
472-
php_mime_split(SG(request_info).post_data, SG(request_info).post_data_length, boundary, array_ptr TSRMLS_CC);
522+
php_mime_split(SG(request_info).post_data, SG(request_info).post_data_length, boundary, boundary_len, array_ptr TSRMLS_CC);
473523
}
474524
}
475525

476-
477526
/*
478527
* Local variables:
479528
* tab-width: 4

0 commit comments

Comments
 (0)