diff -rubB orig/php-4.3.4/main/main.c php-4.3.4/main/main.c --- orig/php-4.3.4/main/main.c 2003-10-09 05:59:03.000000000 +0300 +++ php-4.3.4/main/main.c 2003-11-19 10:05:00.000000000 +0200 @@ -343,6 +343,7 @@ 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_progress_tracking", "0", PHP_INI_ALL, OnUpdateBool, upload_progress_tracking, 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.4/main/php_globals.h php-4.3.4/main/php_globals.h --- orig/php-4.3.4/main/php_globals.h 2003-05-18 13:22:16.000000000 +0300 +++ php-4.3.4/main/php_globals.h 2003-11-19 09:19:58.000000000 +0200 @@ -133,6 +133,7 @@ zend_bool modules_activated; zend_bool file_uploads; + zend_bool upload_progress_tracking; zend_bool during_request_startup; diff -rubB orig/php-4.3.4/main/rfc1867.c php-4.3.4/main/rfc1867.c --- orig/php-4.3.4/main/rfc1867.c 2003-10-26 09:47:24.000000000 +0200 +++ php-4.3.4/main/rfc1867.c 2003-11-20 09:37:30.000000000 +0200 @@ -61,6 +61,104 @@ #define UPLOAD_ERROR_C 3 /* Partially uploaded */ #define UPLOAD_ERROR_D 4 /* No file uploaded */ + + +/* Defines for upload progress tracking callback */ +#define UPLOAD_UPDATE 0 +#define UPLOAD_DONE -1 +#define UPLOAD_GOT_A_NEW_FILE +1 + +#define UPLOAD_PROGRESS_UPDATE( progress, why ) \ + if (upload_progress_active > 1) { \ + upload_progress_callback( progress, \ + SG(read_post_bytes), SG(request_info).content_length, why ); \ + } + +int upload_progress_init( void**, char*); +int upload_progress_register_callback( void* ); +void (*upload_progress_callback)( void*, int, int, int) = NULL; + +/* +NOTES: + +prototype for the callback: +void upload_progress_callback( void *pointer, int read_bytes, int total_bytes, int what_happened ) + + +1. first time call, to initialize: +upload_progress_callback( &tmp_pointer, 0, total, 0 ) + tmp_pointer is an INPUT/OUTPUT parameter! + on INPUT: tmp_pointer = (char*) UPLOAD_METTER_ID. his value was pre checked for + valid chars ( a..z A..Z 0..9 . and _ ) and valid length (16..32) + on OUTPUT: tmp_pointer will return the value of the 'progress' opaque pointer, that will + be used by the callback to store its data. it is the callback responsability + to alloc any storage space it requires, and to free it at the end. + + on INIT call, read_bytes parameter will have a ZERO value, while total_bytes will + have a greater than zero value. + on any other call read_bytes will have a greater than zero value guaranteed! + +2. regular update data call: +upload_progress_callback( progress, read, total, what_happened ) + progress: the opaque pointer returned by the init call + read: the new number of bytes read so far. this will always be greater than zero, + but might not always be greater than the last value received + total: total number of bytes. this value will not change + what_happened: + - a NEGATIVE value (UPLOAD_DONE) means end-of-upload. this is the last call. + - a POZITIVE value (UPLOAD_GOT_A_NEW_FILE) means we've just seen another file + uploaded, more might come. just ++nr_of_uploaded_files_counter. + - a ZERO value (UPLOAD_UPDATE) means nothing unusual, just the regular update. + + When the upload finish, either because of an error (read= '0' && *c <= '9') || (*c == '.') || (*c == '_') || + (*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z') ) { + }else{ + ok = 0; /* reject anything dubious */ + break; + } + } + + if (v && *v && ok) { + if (strlen(v) > 32) v[32]=0; + if (strlen(v) < 16) ok = 0; + }else{ + ok = 0; + } + + if (ok) { +// snprintf(progress->upload_identifier,32, "%s", v); + void *tmp = v; + upload_progress_callback( &tmp, 0, SG(request_info).content_length, 0); + if (tmp && progress) *progress = tmp; + } + + efree(v); + return (ok ? 2:0); +} + +/* end upload progress stuff */ + + + void php_rfc1867_register_constants(TSRMLS_D) { REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_OK", UPLOAD_ERROR_OK, CONST_CS | CONST_PERSISTENT); @@ -702,6 +800,9 @@ #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) int str_len=0; #endif + void * progress = NULL; + int upload_progress_active = PG(upload_progress_tracking) ? 1:0; + /* 0=inactive, 1=active, 2=actualy tracking something */ 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)); @@ -762,6 +863,7 @@ zend_llist_clean(&header); if (!multipart_buffer_headers(mbuff, &header TSRMLS_CC)) { + UPLOAD_PROGRESS_UPDATE( progress, UPLOAD_DONE ); SAFE_RETURN; } @@ -823,6 +925,10 @@ max_file_size = atol(value); } + if (upload_progress_active && !strcmp(param, "UPLOAD_IDENTIFIER")) { + upload_progress_active = upload_progress_init( &progress, value ); + } + efree(param); efree(value); continue; @@ -845,9 +951,12 @@ if (filename) { efree(filename); } + UPLOAD_PROGRESS_UPDATE( progress, UPLOAD_DONE ); SAFE_RETURN; } + UPLOAD_PROGRESS_UPDATE( progress, UPLOAD_GOT_A_NEW_FILE ); + if (!skip_upload) { /* Handle file */ fp = php_open_temporary_file(PG(upload_tmp_dir), "php", &temp_filename TSRMLS_CC); @@ -874,6 +983,8 @@ while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff) TSRMLS_CC))) { + UPLOAD_PROGRESS_UPDATE( progress, UPLOAD_UPDATE ); + if (PG(upload_max_filesize) > 0 && total_bytes > PG(upload_max_filesize)) { sapi_module.sapi_error(E_WARNING, "upload_max_filesize of %ld bytes exceeded - file [%s=%s] not saved", PG(upload_max_filesize), param, filename); cancel_upload = UPLOAD_ERROR_A; @@ -1069,6 +1180,7 @@ } } + UPLOAD_PROGRESS_UPDATE( progress, UPLOAD_DONE ); SAFE_RETURN; }