Hi everybody,

Here is an updated patch for PHP 4.3.3 to enable the
upload-progress-meter I wrote some time ago.

For more details, and a live demo, please visit: http://pdoru.from.ro/

Best regards,
Doru Petrescu
Senior Software Engineer
Astral Telecom Bucuresti

diff -ruBb orig/php-4.3.3/main/main.c php-4.3.3/main/main.c
--- orig/php-4.3.3/main/main.c	2003-08-22 23:02:11.000000000 +0300
+++ php-4.3.3/main/main.c	2003-09-09 12:46:11.000000000 +0300
@@ -343,6 +343,8 @@
 	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_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.3/main/php_globals.h php-4.3.3/main/php_globals.h
--- orig/php-4.3.3/main/php_globals.h	2003-05-18 13:22:16.000000000 +0300
+++ php-4.3.3/main/php_globals.h	2003-09-09 12:42:20.000000000 +0300
@@ -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.3/main/rfc1867.c php-4.3.3/main/rfc1867.c
--- orig/php-4.3.3/main/rfc1867.c	2003-08-05 04:01:40.000000000 +0300
+++ php-4.3.3/main/rfc1867.c	2003-09-09 12:49:45.000000000 +0300
@@ -682,6 +684,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
@@ -699,6 +776,9 @@
 	zval *array_ptr = (zval *) arg;
 	FILE *fp;
 	zend_llist header;
+ 	Xdata X;	
+ 	int progress_metter=0;
+ 
 #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
 	int str_len=0;
 #endif
@@ -708,6 +788,8 @@
 		return;
 	}
 
+	bzero(&X,sizeof(X));
+
 	/* Get the boundary */
 	boundary = strstr(content_type_dup, "boundary");
 	if (!boundary || !(boundary=strchr(boundary, '='))) {
@@ -762,6 +844,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;
 		}
 
@@ -823,6 +908,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;
@@ -848,6 +962,11 @@
 				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);
@@ -889,6 +1008,10 @@
 					} else {
 						total_bytes += wlen;
 					}
+
+
+
+				if (progress_metter) update_progress_metter( &X, SG(read_post_bytes), SG(request_info).content_length );
 				} 
 			} 
 			fclose(fp);
@@ -1069,6 +1194,10 @@
 		}
 	}
 
+
+
+	if (progress_metter) update_progress_metter( &X, SG(read_post_bytes), SG(request_info).content_length );
+
 	SAFE_RETURN;
 }
 
diff -ruBb orig/php-4.3.3/sapi/apache2filter/sapi_apache2.c php-4.3.3/sapi/apache2filter/sapi_apache2.c
--- orig/php-4.3.3/sapi/apache2filter/sapi_apache2.c	2003-08-03 22:31:13.000000000 +0300
+++ php-4.3.3/sapi/apache2filter/sapi_apache2.c	2003-09-09 12:54:44.000000000 +0300
@@ -388,6 +388,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.3/sapi/apache2handler/sapi_apache2.c php-4.3.3/sapi/apache2handler/sapi_apache2.c
--- orig/php-4.3.3/sapi/apache2handler/sapi_apache2.c	2003-08-07 01:34:20.000000000 +0300
+++ php-4.3.3/sapi/apache2handler/sapi_apache2.c	2003-09-09 12:54:44.000000000 +0300
@@ -423,6 +423,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);

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

Reply via email to