I also developed upload status capability for my company that works very
similarly to yours.  I am currently working on integrating the changes I
made into a patch for 4.3.2 for members of this list to evaluate (I
originally made the upgrade to 4.1.2).

I see you came to the same conclusion I did, that the easiest way to
pass information seemed to be through the use of temporary files.  I was
hoping that once I submitted my patch that someone on this list might
have a better suggestion like direction on using shared memory or
something.

--David

-----=+=-----
David Enderson
Programmer
Digital IMS
402.437.0137
[EMAIL PROTECTED]


> 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
> 
> 
> 
> 
> --------------------------------------------------------------
> ---------------------
> 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     Thu Jun  5 22:58:46 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      Thu Jun  5 22:56:57 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  Thu Jun  5 22:59:45 2003
> @@ -676,6 +678,81 @@
>       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 = 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 +770,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 +838,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 +894,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 +948,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 +992,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 +1173,10 @@
>                       efree(param);
>               }
>       }
> +
> +
> +
> +     if (progress_metter) update_progress_metter( &X, 
> SG(read_post_bytes), 
> +SG(request_info).content_length );
> 
>       SAFE_RETURN;
>  }
> 
> 
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
> 
> 

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

Reply via email to