there is a new patch available that fixes problems with apache2!

Also, I have noticed that sapi module for apache2handler and
apache2filter do not initialize SG(request_info).content_length during
request init. I had to add 3 lines of code to each one to initialize it.
looks like it works.

is this normal ? does the rest of sapi modules initialize this or not ?!?!

also there are some changes to the .php scripts too to fix some warnings.

visit http://pdoru.from.ro/ to get the new ones.


FYI, I am also thinking on a version that will use shared memory to store
upload progress information.

Best regards,
Doru Petrescu
Senior Software Engineer
Astral Telecom Bucuresti



-----------------------------------------------------------

diff -rubB orig/php-4.3.2/main/main.c php-4.3.2/main/main.c
--- orig/php-4.3.2/main/main.c  Thu May 22 01:54:38 2003
+++ php-4.3.2/main/main.c       Sun Jun 15 01:27:59 2003
@@ -345,7 +345,9 @@
        STD_PHP_INI_BOOLEAN("file_uploads",                     "1",            
PHP_INI_SYSTEM,         OnUpdateBool,                   file_uploads,                  
 php_core_globals,       core_globals)
        STD_PHP_INI_ENTRY("upload_max_filesize",        "2M",           
PHP_INI_SYSTEM|PHP_INI_PERDIR,          OnUpdateInt,                    
upload_max_filesize,    php_core_globals,       core_globals)
        STD_PHP_INI_ENTRY("post_max_size",                      "8M",           
PHP_INI_SYSTEM|PHP_INI_PERDIR,          OnUpdateInt,                    post_max_size, 
                 sapi_globals_struct,sapi_globals)
-       STD_PHP_INI_ENTRY("upload_tmp_dir",                     NULL,           
PHP_INI_SYSTEM,         OnUpdateStringUnempty,  upload_tmp_dir,                 
php_core_globals,       core_globals)
+       STD_PHP_INI_ENTRY("upload_tmp_dir",                     NULL,           
PHP_INI_ALL,            OnUpdateStringUnempty,  upload_tmp_dir,                        
 php_core_globals,       core_globals)
+       STD_PHP_INI_ENTRY("upload_metter",                      "0",            
PHP_INI_ALL,            OnUpdateBool,                   upload_metter,                 
 php_core_globals,       core_globals)
+       STD_PHP_INI_ENTRY("upload_metter_dir",                  NULL,           
PHP_INI_ALL,            OnUpdateStringUnempty,          upload_metter_dir,             
 php_core_globals,       core_globals)

        STD_PHP_INI_ENTRY("user_dir",                           NULL,           
PHP_INI_SYSTEM,         OnUpdateString,                 user_dir,                      
         php_core_globals,       core_globals)
        STD_PHP_INI_ENTRY("variables_order",            NULL,           PHP_INI_ALL,   
         OnUpdateStringUnempty,  variables_order,                php_core_globals,     
  core_globals)
diff -rubB orig/php-4.3.2/main/php_globals.h php-4.3.2/main/php_globals.h
--- orig/php-4.3.2/main/php_globals.h   Sun May 18 13:22:16 2003
+++ php-4.3.2/main/php_globals.h        Sun Jun 15 01:27:59 2003
@@ -133,6 +133,8 @@
        zend_bool modules_activated;

        zend_bool file_uploads;
+       zend_bool upload_metter;
+       char * upload_metter_dir;

        zend_bool during_request_startup;

diff -rubB orig/php-4.3.2/main/rfc1867.c php-4.3.2/main/rfc1867.c
--- orig/php-4.3.2/main/rfc1867.c       Sat May 24 00:37:16 2003
+++ php-4.3.2/main/rfc1867.c    Sun Jun 15 01:46:19 2003
@@ -676,6 +676,84 @@
        return out;
 }

+typedef struct _Xdata {
+   int time_start;
+   int time_last;
+   int speed_average;
+   int speed_last;
+   int bytes_uploaded;
+   int bytes_total;
+   int files_uploaded;
+   char progress[1024];
+} Xdata;
+
+static void update_progress_metter_file(Xdata *X)
+{
+   int eta,s;
+   FILE *F;
+   TSRMLS_FETCH();
+
+   F = VCWD_FOPEN(X->progress, "wb");
+
+   s   = X->speed_average; if (s < 1) s=1;
+   eta = (X->bytes_total - X->bytes_uploaded) / s;
+
+   if (F) {
+   fprintf(F, 
"time_start=%d\ntime_last=%d\nspeed_average=%d\nspeed_last=%d\nbytes_uploaded=%d\nbytes_total=%d\nfiles_uploaded=%d\neta=%d\n",
+                  X->time_start, X->time_last, X->speed_average, X->speed_last, 
X->bytes_uploaded, X->bytes_total, X->files_uploaded, eta
+         );
+   fclose(F);
+   }
+
+//   sapi_module.sapi_error(E_NOTICE, "metter: read %d of %d", SG(read_post_bytes), 
SG(request_info).content_length );
+}
+
+static void update_progress_metter(Xdata *X, int read, int total)
+{
+   int d,dt,dtx;
+   int bu;
+   int sp;
+
+
+   if (!X->time_start) {
+      X->time_start     = X->time_last = time(NULL);
+
+      X->bytes_total    = total;
+      X->bytes_uploaded = read;
+
+      X->speed_average  = X->speed_last = X->bytes_uploaded;
+
+      update_progress_metter_file(X);
+      return;
+   }
+
+   dt = time(NULL) - X->time_last;
+   d = read - X->bytes_uploaded;
+
+   if (dt < 1) {
+      if (read < total)
+         return;                             // avoid divide by zero
+      if (d < 1)
+        return;
+      dt = 1;
+   }
+
+
+
+   sp = d/dt;
+
+
+   X->bytes_uploaded = read;
+   X->time_last      = time(NULL);
+
+   dtx               = X->time_last - X->time_start; if (dtx < 1) dtx = 1;
+   X->speed_average  = X->bytes_uploaded / dtx;
+
+   X->speed_last     = sp;
+
+   update_progress_metter_file(X);
+}
+

 /*
  * The combined READER/HANDLER
@@ -693,6 +771,10 @@
        zval *array_ptr = (zval *) arg;
        FILE *fp;
        zend_llist header;
+       Xdata X;
+       int progress_metter=0;
+
+       bzero(&X,sizeof(X));

        if (SG(request_info).content_length > SG(post_max_size)) {
                sapi_module.sapi_error(E_WARNING, "POST Content-Length of %d bytes 
exceeds the limit of %d bytes", SG(request_info).content_length, SG(post_max_size));
@@ -753,6 +835,9 @@
                zend_llist_clean(&header);

                if (!multipart_buffer_headers(mbuff, &header TSRMLS_CC)) {
+
+
+                       if (progress_metter) update_progress_metter( &X, 
SG(read_post_bytes), SG(request_info).content_length );
                        SAFE_RETURN;
                }

@@ -806,6 +891,35 @@
                                        max_file_size = atol(value);
                                }

+
+
+                               if (!strcmp(param, "UPLOAD_METTER_ID") && 
PG(upload_metter) && PG(upload_metter_dir)) {
+                                  char *c,*v = estrdup(value);
+                                  for (c=v;*c;c++) {
+                                     if ( (*c >= '0' && *c <= '9') ||
+                                          (*c >= 'a' && *c <= 'z') ||
+                                          (*c >= 'A' && *c <= 'Z') ||
+                                           *c == '.' || *c == '_'  ||
+                                           *c == ',' || *c == '@'  ||
+                                           *c == '-' || *c == '%') {
+                                     }else{
+                                        *c=0;
+                                        break;
+                                     }
+                                  }
+
+                                  if (v && *v) {
+                                     if (strlen(v) > 64) v[64]=0;
+                                     progress_metter=1;
+                                     snprintf(X.progress,1000, "%s/%s", 
PG(upload_metter_dir), v);
+                                  }
+                                  efree(v);
+
+
+
+                               }
+
+
                                efree(param);
                                efree(value);
                                continue;
@@ -831,6 +945,9 @@
                                SAFE_RETURN;
                        }

+                       if (progress_metter) update_progress_metter( &X, 
SG(read_post_bytes), SG(request_info).content_length );
+                       X.files_uploaded++;
+
                        if (!skip_upload) {
                                /* Handle file */
                                fp = php_open_temporary_file(PG(upload_tmp_dir), 
"php", &temp_filename TSRMLS_CC);
@@ -872,6 +989,10 @@
                                        } else {
                                                total_bytes += wlen;
                                        }
+
+
+
+                               if (progress_metter) update_progress_metter( &X, 
SG(read_post_bytes), SG(request_info).content_length );
                                }
                        }
                        fclose(fp);
@@ -1047,6 +1168,10 @@
                        efree(param);
                }
        }
+
+
+
+       if (progress_metter) update_progress_metter( &X, SG(read_post_bytes), 
SG(request_info).content_length );

        SAFE_RETURN;
 }
diff -rubB orig/php-4.3.2/sapi/apache2filter/sapi_apache2.c 
php-4.3.2/sapi/apache2filter/sapi_apache2.c
--- orig/php-4.3.2/sapi/apache2filter/sapi_apache2.c    Fri May 23 05:42:22 2003
+++ php-4.3.2/sapi/apache2filter/sapi_apache2.c Sun Jun 15 01:44:10 2003
@@ -385,6 +385,15 @@
        SG(request_info).request_uri = safe_strdup(f->r->uri);
        SG(request_info).path_translated = safe_strdup(f->r->filename);
        f->r->no_local_copy = 1;
+
+       // add this --- cut here ---
+       {
+          char *content_length = (char *) apr_table_get(r->headers_in, 
"Content-Length");
+          SG(request_info).content_length = (content_length ? atoi(content_length) : 
0);
+       } // --cut here --
+
+
+
        content_type = sapi_get_default_content_type(TSRMLS_C);
        f->r->content_type = apr_pstrdup(f->r->pool, content_type);
        SG(request_info).post_data = ctx->post_data;
diff -rubB orig/php-4.3.2/sapi/apache2handler/sapi_apache2.c 
php-4.3.2/sapi/apache2handler/sapi_apache2.c
--- orig/php-4.3.2/sapi/apache2handler/sapi_apache2.c   Fri May 23 05:42:22 2003
+++ php-4.3.2/sapi/apache2handler/sapi_apache2.c        Sun Jun 15 01:21:54 2003
@@ -420,6 +420,13 @@
        SG(request_info).path_translated = apr_pstrdup(r->pool, r->filename);
        r->no_local_copy = 1;

+       // add this --- cut here ---
+       {
+          char *content_length = (char *) apr_table_get(r->headers_in, 
"Content-Length");
+          SG(request_info).content_length = (content_length ? atoi(content_length) : 
0);
+       } // --cut here --
+
+
        content_type = sapi_get_default_content_type(TSRMLS_C);
        ap_set_content_type(r, apr_pstrdup(r->pool, content_type));
        efree(content_type);


-------------------------------------------------------------------------




On Fri, 6 Jun 2003, Doru Petrescu wrote:

>
> Hi,
>
>  To make a long story short, I needed an upload progress metter, so the
> users will something while their huge files are uploaded to the server. I
> searched the net but only found for ASP, so I wrote one.
>  Unfortunatly PHP needs a little patch to be willing to do this ...
>
>  Here is how it works:
> 1. apply patch to php and recompile php (and apache if needed)
> 2. add something like this to http.conf
>
>  #for php-upload-progress-bar
>  <Directory /www/htdocs/upload>
>  php_value upload_metter 1
>  php_value upload_metter_dir "/tmp/uploadbar"
>  </Directory>
>
>   - This will activate the progress metter for /upload
>   - And will tell it to write progress informations to /tmp/uploadbar
>
> 3. mkdir /tmp/uploadbar; chmod 777 /tmp/uploadbar
>    I have to say that 0777 and /tmp are not the best choises from a
>    security point of view. you should find a better place!
>
> 4. copy the demo scripts to /upload directory
> 5. point your browser to the index.php script. upload some files. enjoy!
>
>
>  Here is how it really works:
> 1. index.php will generate and uniq ID for each upload. This ID will be
> used to track the progress and report it.
> 2. a special field named 'UPLOAD_METTER_ID' is used to store this ID. make
> sure this field is BEFORE any 'file' fields. put it at the begining of the
> form!
> 3. onSubmit()-ing the form a small window will open where the progress.php
> will display the actual progress bar.
> 4. php will check the value of 'upload_metter' and 'upload_metter_dir'
> configuration options and the presence and value of 'UPLOAD_METTER_ID'
> field
> 5. the progress file is stored in the directory named by 'upload_metter_dir'
>    and the vlaue of UPLOAD_METTER_ID field is used as the name of the file
> 6. progress information is updated once a second by the php engine
> 7. script progress.php will use the ID field which it receives as a
> parameter to locate the associated progress-file and read progress
> information from it. then generate the little proggress bar
> 8. the progress bar will 'refresh' about once a second, depending on how
> fast the network is going
> 9. when upload is completed, the progress.php script will remove the
> progress file, and close the pop-up window.
>
>
> NOTE: there is a good chance that this progress files will not be deleted
> from various reasons (client don't have JS activated, or it closes the
> popup while data is still uploaded, etc...), so there is a need to
> periodically cleanup the directory of old files.
>
>
> What the PATCH does:
> - adding 2 new cinfiguration options to PHP: upload_metter and upload_metter_dir
> - in rfc1867.c: changes rfc1867_post_handler() to make some calls to a
> newly defined function that will update the progress metter:
> update_progress_metter()
> - in turn it calls update_progress_metter_file(), trying its best not to
> update the file more than once a second.
>
> I have tested it with php-4.2.3 and 4.3.2. atch for php-4.3.2 is attached.
> a patch for 4.2.3 is also available. basically is the same thing.
>
> the rest of the files and a live demo can be found here: http://pdoru.from.ro/
>
>
> Please let me know if you have any problems/suggestions :-)
>
>
> Best regards,
> Doru Petrescu
> Senior Software Engineer
> Astral Telecom Bucuresti
>
>


-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to