sesser Sat Jul 22 16:38:29 2006 UTC Modified files: (Branch: PHP_5_2) /php-src NEWS /php-src/main rfc1867.c rfc1867.h Log: Added RFC1867 fileupload processing hook.
http://cvs.php.net/viewvc.cgi/php-src/NEWS?r1=1.2027.2.547.2.136&r2=1.2027.2.547.2.137&diff_format=u Index: php-src/NEWS diff -u php-src/NEWS:1.2027.2.547.2.136 php-src/NEWS:1.2027.2.547.2.137 --- php-src/NEWS:1.2027.2.547.2.136 Sat Jul 22 15:41:41 2006 +++ php-src/NEWS Sat Jul 22 16:38:29 2006 @@ -65,6 +65,7 @@ . Added readInnerXML(), readOuterXML(), readString(), setSchema(). (2.6.20+) . Changed to passing libxml options when loading reader. +- Added RFC1867 fileupload processing hook. (Stefan E.) - Added JSON and Filter extensions. (Derick, Rasmus) - Added error messages to disk_free_space() and disk_total_space() functions. FR #37971 (Tony) http://cvs.php.net/viewvc.cgi/php-src/main/rfc1867.c?r1=1.173.2.1&r2=1.173.2.1.2.1&diff_format=u Index: php-src/main/rfc1867.c diff -u php-src/main/rfc1867.c:1.173.2.1 php-src/main/rfc1867.c:1.173.2.1.2.1 --- php-src/main/rfc1867.c:1.173.2.1 Sun Jan 1 12:50:17 2006 +++ php-src/main/rfc1867.c Sat Jul 22 16:38:29 2006 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: rfc1867.c,v 1.173.2.1 2006/01/01 12:50:17 sniper Exp $ */ +/* $Id: rfc1867.c,v 1.173.2.1.2.1 2006/07/22 16:38:29 sesser Exp $ */ /* * This product includes software developed by the Apache Group @@ -35,6 +35,8 @@ #define DEBUG_FILE_UPLOAD ZEND_DEBUG +PHPAPI int (*php_rfc1867_callback)(unsigned int event, void *event_data, void **extra TSRMLS_DC) = NULL; + #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) #include "ext/mbstring/mbstring.h" @@ -132,6 +134,7 @@ #define UPLOAD_ERROR_D 4 /* No file uploaded */ #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */ #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */ +#define UPLOAD_ERROR_X 8 /* File upload stopped by extension */ void php_rfc1867_register_constants(TSRMLS_D) { @@ -142,6 +145,7 @@ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT); REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT); REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT); + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_EXTENSION", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT); } static void normalize_protected_variable(char *varname TSRMLS_DC) @@ -791,6 +795,7 @@ zval *array_ptr = (zval *) arg; int fd=-1; zend_llist header; + void *event_extra_data = NULL; if (SG(request_info).content_length > SG(post_max_size)) { sapi_module.sapi_error(E_WARNING, "POST Content-Length of %ld bytes exceeds the limit of %ld bytes", SG(request_info).content_length, SG(post_max_size)); @@ -849,16 +854,26 @@ #endif zend_llist_init(&header, sizeof(mime_header_entry), (llist_dtor_func_t) php_free_hdr_entry, 0); + if (php_rfc1867_callback != NULL) { + multipart_event_start event_start; + + event_start.content_length = SG(request_info).content_length; + if (php_rfc1867_callback(MULTIPART_EVENT_START, &event_start, &event_extra_data TSRMLS_CC) == FAILURE) { + goto fileupload_done; + } + } + while (!multipart_buffer_eof(mbuff TSRMLS_CC)) { char buff[FILLUNIT]; char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL; - int blen=0, wlen=0; + size_t blen=0, wlen=0; + off_t offset; zend_llist_clean(&header); if (!multipart_buffer_headers(mbuff, &header TSRMLS_CC)) { - SAFE_RETURN; + goto fileupload_done; } if ((cd = php_mime_get_hdr_value(header, "Content-Disposition"))) { @@ -909,6 +924,23 @@ } if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) { + if (php_rfc1867_callback != NULL) { + multipart_event_formdata event_formdata; + size_t newlength = 0; + + event_formdata.post_bytes_processed = SG(read_post_bytes); + event_formdata.name = param; + event_formdata.value = &value; + event_formdata.length = new_val_len; + event_formdata.newlength = &newlength; + if (php_rfc1867_callback(MULTIPART_EVENT_FORMDATA, &event_formdata, &event_extra_data TSRMLS_CC) == FAILURE) { + efree(param); + efree(value); + continue; + } + new_val_len = newlength; + } + #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) if (php_mb_encoding_translation(TSRMLS_C)) { php_mb_gpc_stack_variable(param, value, &val_list, &len_list, @@ -937,7 +969,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"); - SAFE_RETURN; + goto fileupload_done; } if (!param) { @@ -981,11 +1013,24 @@ cancel_upload = UPLOAD_ERROR_E; } } + + if (php_rfc1867_callback != NULL) { + multipart_event_file_start event_file_start; + + event_file_start.post_bytes_processed = SG(read_post_bytes); + event_file_start.name = param; + event_file_start.filename = &filename; + if (php_rfc1867_callback(MULTIPART_EVENT_FILE_START, &event_file_start, &event_extra_data TSRMLS_CC) == FAILURE) { + skip_upload = 1; + } + } + + if (skip_upload) { efree(param); efree(filename); continue; - } + } if(strlen(filename) == 0) { #if DEBUG_FILE_UPLOAD @@ -994,9 +1039,25 @@ cancel_upload = UPLOAD_ERROR_D; } + offset = 0; end = 0; while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC))) { + if (php_rfc1867_callback != NULL) { + multipart_event_file_data event_file_data; + + event_file_data.post_bytes_processed = SG(read_post_bytes); + event_file_data.offset = offset; + event_file_data.data = buff; + event_file_data.length = blen; + event_file_data.newlength = &blen; + if (php_rfc1867_callback(MULTIPART_EVENT_FILE_DATA, &event_file_data, &event_extra_data TSRMLS_CC) == FAILURE) { + cancel_upload = UPLOAD_ERROR_X; + continue; + } + } + + 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); @@ -1008,6 +1069,7 @@ #endif cancel_upload = UPLOAD_ERROR_B; } else if (blen > 0) { + wlen = write(fd, buff, blen); if (wlen < blen) { @@ -1018,6 +1080,8 @@ } else { total_bytes += wlen; } + + offset += wlen; } } if (fd!=-1) { /* may not be initialized if file could not be created */ @@ -1036,6 +1100,17 @@ } #endif + if (php_rfc1867_callback != NULL) { + multipart_event_file_end event_file_end; + + event_file_end.post_bytes_processed = SG(read_post_bytes); + event_file_end.temp_filename = temp_filename; + event_file_end.cancel_upload = cancel_upload; + if (php_rfc1867_callback(MULTIPART_EVENT_FILE_END, &event_file_end, &event_extra_data TSRMLS_CC) == FAILURE) { + cancel_upload = UPLOAD_ERROR_X; + } + } + if (cancel_upload) { if (temp_filename) { if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */ @@ -1242,7 +1317,14 @@ efree(param); } } - +fileupload_done: + if (php_rfc1867_callback != NULL) { + multipart_event_end event_end; + + event_end.post_bytes_processed = SG(read_post_bytes); + php_rfc1867_callback(MULTIPART_EVENT_END, &event_end, &event_extra_data TSRMLS_CC); + } + SAFE_RETURN; } http://cvs.php.net/viewvc.cgi/php-src/main/rfc1867.h?r1=1.13.2.1&r2=1.13.2.1.2.1&diff_format=u Index: php-src/main/rfc1867.h diff -u php-src/main/rfc1867.h:1.13.2.1 php-src/main/rfc1867.h:1.13.2.1.2.1 --- php-src/main/rfc1867.h:1.13.2.1 Sun Jan 1 12:50:17 2006 +++ php-src/main/rfc1867.h Sat Jul 22 16:38:29 2006 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: rfc1867.h,v 1.13.2.1 2006/01/01 12:50:17 sniper Exp $ */ +/* $Id: rfc1867.h,v 1.13.2.1.2.1 2006/07/22 16:38:29 sesser Exp $ */ #ifndef RFC1867_H #define RFC1867_H @@ -24,10 +24,53 @@ #include "SAPI.h" #define MULTIPART_CONTENT_TYPE "multipart/form-data" +#define MULTIPART_EVENT_START 0 +#define MULTIPART_EVENT_FORMDATA 1 +#define MULTIPART_EVENT_FILE_START 2 +#define MULTIPART_EVENT_FILE_DATA 3 +#define MULTIPART_EVENT_FILE_END 4 +#define MULTIPART_EVENT_END 5 + +typedef struct _multipart_event_start { + size_t content_length; +} multipart_event_start; + +typedef struct _multipart_event_formdata { + size_t post_bytes_processed; + char *name; + char **value; + size_t length; + size_t *newlength; +} multipart_event_formdata; + +typedef struct _multipart_event_file_start { + size_t post_bytes_processed; + char *name; + char **filename; +} multipart_event_file_start; + +typedef struct _multipart_event_file_data { + size_t post_bytes_processed; + off_t offset; + char *data; + size_t length; + size_t *newlength; +} multipart_event_file_data; + +typedef struct _multipart_event_file_end { + size_t post_bytes_processed; + char *temp_filename; + int cancel_upload; +} multipart_event_file_end; + +typedef struct _multipart_event_end { + size_t post_bytes_processed; +} multipart_event_end; SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler); void destroy_uploaded_files_hash(TSRMLS_D); void php_rfc1867_register_constants(TSRMLS_D); +PHPAPI int (*php_rfc1867_callback)(unsigned int event, void *event_data, void **extra TSRMLS_DC); #endif /* RFC1867_H */
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php