Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:13724 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 78708 invoked by uid 1010); 5 Nov 2004 09:34:25 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 78645 invoked from network); 5 Nov 2004 09:34:24 -0000 Received: from unknown (HELO malcolm.ailis.de) (217.115.149.166) by pb1.pair.com with SMTP; 5 Nov 2004 09:34:24 -0000 Received: (qmail 17214 invoked by uid 64014); 5 Nov 2004 09:34:31 -0000 Received: from unknown (HELO ?172.16.0.1?) (k@62.206.245.30) by malcolm.ailis.de with SMTP; 5 Nov 2004 09:34:29 -0000 Message-ID: <418B4909.7010203@ailis.de> Date: Fri, 05 Nov 2004 10:34:01 +0100 User-Agent: Mozilla Thunderbird 0.8 (X11/20040926) X-Accept-Language: en-us, en MIME-Version: 1.0 To: internals@lists.php.net X-Enigmail-Version: 0.86.1.0 X-Enigmail-Supports: pgp-inline, pgp-mime Content-Type: multipart/mixed; boundary="------------040603040607070802000202" X-Virus-Scanned: by AMaViS 0.3.12 Subject: Upload Progress Meter Patch From: k-php-dev@ailis.de (Klaus Reimer) --------------040603040607070802000202 Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit Hello, The website "http://pdoru.from.ro/" states that "hopefully the patch will be integrated into PHP". This patch adds some hooks to main/rfc1867.c so PHP modules can implement stuff like reading the current state of a file upload. Such an external PHP module can write the state to disk or shared memory or whatever. A HTML popup shown to the uploader can then view this data as a progress meter bar to the user while he uploads large files. This patch is extremely useful and is working very well. I'm already using it (together with a self-written PHP module) quite successfully in some projects where users can upload large image files. What is the state of considering the integration of this patch into PHP? Or is the statement on the webpage wrong and you have never heard of it? I have attached a version of the patch for PHP 5.0.2. Even it you don't like the way it is written it can still be used as an example to show how it could be done. -- Bye, K (FidoNet: 2:240/2188.18) [A735 47EC D87B 1F15 C1E9 53D3 AA03 6173 A723 E391] (Finger k@ailis.de to get public key) --------------040603040607070802000202 Content-Type: text/plain; name="upm.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="upm.diff" diff -Nur php-5.0.2.orig/main/rfc1867.c php-5.0.2/main/rfc1867.c --- php-5.0.2.orig/main/rfc1867.c 2004-09-13 18:00:37.000000000 +0200 +++ php-5.0.2/main/rfc1867.c 2004-09-28 20:35:35.000000000 +0200 @@ -131,6 +131,29 @@ #define UPLOAD_ERROR_C 3 /* Partially uploaded */ #define UPLOAD_ERROR_D 4 /* No file uploaded */ + + +/* Defines for upload progress callback */ +#define UPLOAD_START 0 +#define UPLOAD_UPDATE 0 +#define UPLOAD_DETECTED_NEW_FILE +1 +#define UPLOAD_DONE -1 + +#define UPLOAD_PROGRESS_UPDATE( progress, why ) \ + if (upload_progress_tracking > 1) { \ + upload_progress_callback( progress, \ + SG(read_post_bytes), SG(request_info).content_length, why ); \ + } + +static void * (*upload_progress_callback)( void*, int, int, int) = NULL; +PHPAPI int upload_progress_register_callback( void* callback) +{ + upload_progress_callback = callback; +} +/* 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); @@ -770,6 +793,11 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) { + void * progress = NULL; + int upload_progress_tracking = /* 0=disabled, 1=active, 2=actualy tracking something */ + SG(request_info).content_length && upload_progress_callback ? 1:0; + + char *boundary, *s=NULL, *boundary_end = NULL, *start_arr=NULL, *array_index=NULL; char *temp_filename=NULL, *lbuf=NULL, *abuf=NULL; int boundary_len=0, total_bytes=0, cancel_upload=0, is_arr_upload=0, array_len=0; @@ -851,6 +879,7 @@ zend_llist_clean(&header); if (!multipart_buffer_headers(mbuff, &header TSRMLS_CC)) { + UPLOAD_PROGRESS_UPDATE( progress, UPLOAD_DONE ); SAFE_RETURN; } @@ -916,6 +945,11 @@ max_file_size = atol(value); } + if (upload_progress_tracking == 1 && (!strcmp(param, "UPLOAD_IDENTIFIER") || !strcmp(param, "UPLOAD_METER_ID") || !strcmp(param, "UPLOAD_METTER_ID")) ) { + progress = upload_progress_callback( value, 0, SG(request_info).content_length, 0); + upload_progress_tracking = progress ? 2:0; + } + efree(param); efree(value); continue; @@ -929,6 +963,7 @@ /* Return with an error if the posted data is garbled */ if (!param && !filename) { sapi_module.sapi_error(E_WARNING, "File Upload Mime headers garbled"); + UPLOAD_PROGRESS_UPDATE( progress, UPLOAD_DONE ); SAFE_RETURN; } @@ -963,6 +998,8 @@ } } + UPLOAD_PROGRESS_UPDATE( progress, UPLOAD_DETECTED_NEW_FILE ); + if (!skip_upload) { /* Handle file */ fp = php_open_temporary_file(PG(upload_tmp_dir), "php", &temp_filename TSRMLS_CC); @@ -989,6 +1026,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)) { #if DEBUG_FILE_UPLOAD sapi_module.sapi_error(E_NOTICE, "upload_max_filesize of %ld bytes exceeded - file [%s=%s] not saved", PG(upload_max_filesize), param, filename); @@ -1211,6 +1250,7 @@ } } + UPLOAD_PROGRESS_UPDATE( progress, UPLOAD_DONE ); SAFE_RETURN; } --------------040603040607070802000202--