ID: 50078 Comment by: nishantkumar05 at gmail dot com Reported By: nishantkumar05 at gmail dot com Status: Open Bug Type: Other web server Operating System: ubuntu 8.10 PHP Version: 5.3.0 New Comment:
This is the patch available. ============================================================= diff -Nur php-5.3.0/sapi/thttpd/thttpd.c php- 5.3.0_mod/sapi/thttpd/thttpd.c --- php-5.3.0/sapi/thttpd/thttpd.c 2008-12-31 03:15:49.000000000 -0800 +++ php-5.3.0_mod/sapi/thttpd/thttpd.c 2009-11-02 19:02:28.000000000 -0800 @@ -64,6 +64,9 @@ #define TG(v) (thttpd_globals.v) #endif + +int read_pending_content( void ); + static int sapi_thttpd_ub_write(const char *str, uint str_length TSRMLS_DC) { int n; @@ -247,16 +250,77 @@ static int sapi_thttpd_read_post(char *buffer, uint count_bytes TSRMLS_DC) { - size_t read_bytes = 0; + size_t read_bytes = 0, send2php_bytes = 0 ; + size_t buff_bytes = TG(hc)->read_idx - TG(hc)->checked_idx ; - if (TG(unconsumed_length) > 0) { - read_bytes = MIN(TG(unconsumed_length), count_bytes); - memcpy(buffer, TG(hc)->read_buf + TG(hc)->checked_idx, read_bytes); - TG(unconsumed_length) -= read_bytes; - CONSUME_BYTES(read_bytes); + + if ( buff_bytes > 0 ) { + /*we might already have some bytes in read_buf to be sent to php module*/ + read_bytes = buff_bytes; + }else if ( TG(hc)->contentlength > 0 ){ + read_bytes=read_pending_content(); + } + + if ( read_bytes ) { + send2php_bytes = MIN ( read_bytes, count_bytes); + memcpy(buffer, TG(hc)->read_buf + TG(hc)- >checked_idx, send2php_bytes); + TG(hc)->contentlength -= send2php_bytes; + /*bringing the read_idx back to checked_idx, so we have more room to read + the pending bytes from connection*/ + if ( send2php_bytes == read_bytes ) { + TG(hc)->read_idx = TG(hc)->checked_idx ; + } else { + /*memmove is costly: but for small devices we cant increase the buffer + size substantially. presuming that memmove doesnt use extra buffer + internally*/ + memmove(TG(hc)->read_buf + TG(hc)- >checked_idx, + TG(hc)- >read_buf + TG(hc)->checked_idx + send2php_bytes , + read_bytes- count_bytes); + TG(hc)->read_idx = TG(hc)->checked_idx + ( read_bytes - count_bytes ) ; + } + + TG(unconsumed_length) -= send2php_bytes; } - - return read_bytes; + + return send2php_bytes; +} + + +/* + * Read the max possible (limited by the available buffer ) pending data + * from the network. hc->contenlength has been used to tell about the + * pending data to be read from the network, hence onus is on the caller + * to modify it accordingly. + * It starts reading from checked_idx and updates the read_idx after reading. + * -nishant + * */ +int read_pending_content( void ) +{ + int avail_buf= TG(hc)->read_size - TG(hc)->read_idx; + int act_to_read=0,total_read=0,ctr=0; + + + if ( TG(hc)->contentlength < avail_buf ){ + act_to_read = TG(hc)->contentlength; + } else { + act_to_read = avail_buf - 2; + } + + while(total_read != act_to_read) + { + ctr = read(TG(hc)->conn_fd, &(TG(hc)->read_buf[TG(hc)- >checked_idx]), act_to_read ); + if(ctr < 0){ + if( ( errno == EINTR ) || ( errno == EAGAIN ) ){ + continue; + }else{ + break; + } + } + total_read += ctr; + } + + TG(hc)->read_idx += total_read; + return total_read; } static char *sapi_thttpd_read_cookies(TSRMLS_D) @@ -663,12 +727,14 @@ hc->do_keep_alive = 0; } +#if 0 + /*Its ok to have unconsumed bytes. We will consum in read_post function*/ if (hc->contentlength != -1 && SIZEOF_UNCONSUMED_BYTES() < hc- >contentlength) { hc->read_body_into_mem = 1; return 0; } - +#endif thttpd_request_ctor(TSRMLS_C); thttpd_module_main(show_source TSRMLS_CC); ============================================================= thanks Nishant Previous Comments: ------------------------------------------------------------------------ [2009-11-04 15:27:21] nishantkumar05 at gmail dot com Description: ------------ I have thttpd 2.1b patched with php-5.3.0. Try to upload file using POST request to this web server. Small files ( max of 600 bytes or so ) can be transferred, but big files, for which POST request will span multiple packets fails. Reproduce code: --------------- .php web page that reproduces this bug is: (upload.php) <form enctype="multipart/form-data" action="uploader.php" method="POST"> <input type="hidden" name="MAX_FILE_SIZE" value="2000000" /> Choose a file to upload: <input name="uploadedfile" type="file" /><br /> <input type="submit" value="Upload File" /> </form> Expected result: ---------------- It should be able to upload file of any size successfully. ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=50078&edit=1