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