ID: 41712 Comment by: renatobraga at gmail dot com Reported By: sdteffen at gmail dot com Status: Assigned Bug Type: Feature/Change Request Operating System: SuSE Linux 10.2 PHP Version: 5CVS-2007-06-16 (CVS) Assigned To: iliaa New Comment:
Hi, this patch isn't working for return values as you can see: "Returning a non-zero nonzero value from this callback will cause libcurl to abort the transfer and return CURLE_ABORTED_BY_CALLBACK." Nothing happens if i return a nonzero value. Can you fix it? Regards, Renato Previous Comments: ------------------------------------------------------------------------ [2007-09-25 09:22:29] top dot quack at freenet dot de Thanks to Steffen, the patch is now working properly and displays the upload progress as expected: curl_progress_callback Download: 0 / 0 bytes, Upload: 636 / 1179391 bytes curl_progress_callback Download: 0 / 0 bytes, Upload: 17020 / 1179391 bytes curl_progress_callback Download: 0 / 0 bytes, Upload: 33404 / 1179391 bytes Please include that bugfix as soon as possible into the new php versions. ------------------------------------------------------------------------ [2007-09-24 21:26:20] sdteffen at gmail dot com The progress function only returned 3 values instead of 4. The following revised patch fixes this problem (it completely replaces the previous patch): diff -u php-5.2.3/ext/curl/interface.c php-5.2.3.patched/ext/curl/interface.c --- php-5.2.3/ext/curl/interface.c 2007-05-22 10:39:20.000000000 +0200 +++ php-5.2.3.patched/ext/curl/interface.c 2007-06-16 13:30:05.000000000 +0200 @@ -368,6 +368,7 @@ REGISTER_CURL_CONSTANT(CURLOPT_HEADER); REGISTER_CURL_CONSTANT(CURLOPT_HTTPHEADER); REGISTER_CURL_CONSTANT(CURLOPT_NOPROGRESS); + REGISTER_CURL_CONSTANT(CURLOPT_PROGRESSFUNCTION); REGISTER_CURL_CONSTANT(CURLOPT_NOBODY); REGISTER_CURL_CONSTANT(CURLOPT_FAILONERROR); REGISTER_CURL_CONSTANT(CURLOPT_UPLOAD); @@ -777,6 +778,80 @@ } /* }}} */ +/* {{{ curl_progress + */ +static size_t curl_progress(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow) +{ + php_curl *ch = (php_curl *) clientp; + php_curl_progress *t = ch->handlers->progress; + int length = -1; + +#if PHP_CURL_DEBUG + fprintf(stderr, "curl_progress() called\n"); + fprintf(stderr, "clientp = %x, dltotal = %f, dlnow = %f, ultotal = %f, ulnow = %f\n", clientp, dltotal, dlnow, ultotal, ulnow); +#endif + + switch (t->method) { + case PHP_CURL_USER: { + zval **argv[4]; + zval *zdltotal = NULL; + zval *zdlnow = NULL; + zval *zultotal = NULL; + zval *zulnow = NULL; + zval *retval_ptr; + int error; + zend_fcall_info fci; + TSRMLS_FETCH_FROM_CTX(ch->thread_ctx); + + MAKE_STD_ZVAL(zdltotal); + MAKE_STD_ZVAL(zdlnow); + MAKE_STD_ZVAL(zultotal); + MAKE_STD_ZVAL(zulnow); + + ZVAL_LONG(zdltotal, dltotal); + ZVAL_LONG(zdlnow, dlnow); + ZVAL_LONG(zultotal, ultotal); + ZVAL_LONG(zulnow, ulnow); + + argv[0] = &zdltotal; + argv[1] = &zdlnow; + argv[2] = &zultotal; + argv[3] = &zulnow; + + fci.size = sizeof(fci); + fci.function_table = EG(function_table); + fci.function_name = t->func_name; + fci.object_pp = NULL; + fci.retval_ptr_ptr = &retval_ptr; + fci.param_count = 4; + fci.params = argv; + fci.no_separation = 0; + fci.symbol_table = NULL; + + ch->in_callback = 1; + error = zend_call_function(&fci, &t->fci_cache TSRMLS_CC); + ch->in_callback = 0; + if (error == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot call the CURLOPT_READFUNCTION"); + length = -1; + } + + zval_ptr_dtor(argv[0]); + zval_ptr_dtor(argv[1]); + zval_ptr_dtor(argv[2]); + zval_ptr_dtor(argv[3]); + break; + } + } + return 0; +} +/* }}} */ + + /* {{{ curl_read */ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx) @@ -1065,6 +1140,7 @@ (*ch)->handlers->write = ecalloc(1, sizeof(php_curl_write)); (*ch)->handlers->write_header = ecalloc(1, sizeof(php_curl_write)); (*ch)->handlers->read = ecalloc(1, sizeof(php_curl_read)); + (*ch)->handlers->progress = ecalloc(1, sizeof(php_curl_progress)); (*ch)->in_callback = 0; (*ch)->header.str_len = 0; @@ -1418,6 +1494,17 @@ ch->handlers->read->func_name = *zvalue; ch->handlers->read->method = PHP_CURL_USER; break; + case CURLOPT_PROGRESSFUNCTION: + curl_easy_setopt(ch->cp, CURLOPT_PROGRESSFUNCTION, curl_progress); + curl_easy_setopt(ch->cp, CURLOPT_PROGRESSDATA, ch); + if (ch->handlers->progress->func_name) { + zval_ptr_dtor(&ch->handlers->progress->func_name); + ch->handlers->progress->fci_cache = empty_fcall_info_cache; + } + zval_add_ref(zvalue); + ch->handlers->progress->func_name = *zvalue; + ch->handlers->progress->method = PHP_CURL_USER; + break; case CURLOPT_HEADERFUNCTION: if (ch->handlers->write_header->func_name) { zval_ptr_dtor(&ch->handlers->write_header->func_name); @@ -1948,6 +2035,9 @@ if (ch->handlers->write_header->func_name) { zval_ptr_dtor(&ch->handlers->write_header->func_name); } + if(ch->handlers->progress->func_name) { + zval_ptr_dtor(&ch->handlers->progress->func_name); + } if (ch->handlers->passwd) { zval_ptr_dtor(&ch->handlers->passwd); } diff -u php-5.2.3/ext/curl/php_curl.h php-5.2.3.patched/ext/curl/php_curl.h --- php-5.2.3/ext/curl/php_curl.h 2007-01-01 10:35:48.000000000 +0100 +++ php-5.2.3.patched/ext/curl/php_curl.h 2007-06-16 13:31:07.000000000 +0200 @@ -97,10 +97,17 @@ } php_curl_read; typedef struct { + zval *func_name; + zend_fcall_info_cache fci_cache; + int method; +} php_curl_progress; + +typedef struct { php_curl_write *write; php_curl_write *write_header; php_curl_read *read; zval *passwd; + php_curl_progress *progress; } php_curl_handlers; struct _php_curl_error { ------------------------------------------------------------------------ [2007-06-25 18:08:48] [EMAIL PROTECTED] Assigned to the maintainer. ------------------------------------------------------------------------ [2007-06-16 12:20:04] sdteffen at gmail dot com Patch to implement CURL_PROGRESSFUNCTION (works against today's 5.2 CVS version): diff -u php-5.2.3/ext/curl/interface.c php-5.2.3.patched/ext/curl/interface.c --- php-5.2.3/ext/curl/interface.c 2007-05-22 10:39:20.000000000 +0200 +++ php-5.2.3.patched/ext/curl/interface.c 2007-06-16 13:30:05.000000000 +0200 @@ -368,6 +368,7 @@ REGISTER_CURL_CONSTANT(CURLOPT_HEADER); REGISTER_CURL_CONSTANT(CURLOPT_HTTPHEADER); REGISTER_CURL_CONSTANT(CURLOPT_NOPROGRESS); + REGISTER_CURL_CONSTANT(CURLOPT_PROGRESSFUNCTION); REGISTER_CURL_CONSTANT(CURLOPT_NOBODY); REGISTER_CURL_CONSTANT(CURLOPT_FAILONERROR); REGISTER_CURL_CONSTANT(CURLOPT_UPLOAD); @@ -777,6 +778,80 @@ } /* }}} */ +/* {{{ curl_progress + */ +static size_t curl_progress(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow) +{ + php_curl *ch = (php_curl *) clientp; + php_curl_progress *t = ch->handlers->progress; + int length = -1; + +#if PHP_CURL_DEBUG + fprintf(stderr, "curl_progress() called\n"); + fprintf(stderr, "clientp = %x, dltotal = %f, dlnow = %f, ultotal = %f, ulnow = %f\n", clientp, dltotal, dlnow, ultotal, ulnow); +#endif + + switch (t->method) { + case PHP_CURL_USER: { + zval **argv[4]; + zval *zdltotal = NULL; + zval *zdlnow = NULL; + zval *zultotal = NULL; + zval *zulnow = NULL; + zval *retval_ptr; + int error; + zend_fcall_info fci; + TSRMLS_FETCH_FROM_CTX(ch->thread_ctx); + + MAKE_STD_ZVAL(zdltotal); + MAKE_STD_ZVAL(zdlnow); + MAKE_STD_ZVAL(zultotal); + MAKE_STD_ZVAL(zulnow); + + ZVAL_LONG(zdltotal, dltotal); + ZVAL_LONG(zdlnow, dlnow); + ZVAL_LONG(zultotal, ultotal); + ZVAL_LONG(zulnow, ulnow); + + argv[0] = &zdltotal; + argv[1] = &zdlnow; + argv[2] = &zultotal; + argv[3] = &zulnow; + + fci.size = sizeof(fci); + fci.function_table = EG(function_table); + fci.function_name = t->func_name; + fci.object_pp = NULL; + fci.retval_ptr_ptr = &retval_ptr; + fci.param_count = 3; + fci.params = argv; + fci.no_separation = 0; + fci.symbol_table = NULL; + + ch->in_callback = 1; + error = zend_call_function(&fci, &t->fci_cache TSRMLS_CC); + ch->in_callback = 0; + if (error == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot call the CURLOPT_READFUNCTION"); + length = -1; + } + + zval_ptr_dtor(argv[0]); + zval_ptr_dtor(argv[1]); + zval_ptr_dtor(argv[2]); + zval_ptr_dtor(argv[3]); + break; + } + } + return 0; +} +/* }}} */ + + /* {{{ curl_read */ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx) @@ -1065,6 +1140,7 @@ (*ch)->handlers->write = ecalloc(1, sizeof(php_curl_write)); (*ch)->handlers->write_header = ecalloc(1, sizeof(php_curl_write)); (*ch)->handlers->read = ecalloc(1, sizeof(php_curl_read)); + (*ch)->handlers->progress = ecalloc(1, sizeof(php_curl_progress)); (*ch)->in_callback = 0; (*ch)->header.str_len = 0; @@ -1418,6 +1494,17 @@ ch->handlers->read->func_name = *zvalue; ch->handlers->read->method = PHP_CURL_USER; break; + case CURLOPT_PROGRESSFUNCTION: + curl_easy_setopt(ch->cp, CURLOPT_PROGRESSFUNCTION, curl_progress); + curl_easy_setopt(ch->cp, CURLOPT_PROGRESSDATA, ch); + if (ch->handlers->progress->func_name) { + zval_ptr_dtor(&ch->handlers->progress->func_name); + ch->handlers->progress->fci_cache = empty_fcall_info_cache; + } + zval_add_ref(zvalue); + ch->handlers->progress->func_name = *zvalue; + ch->handlers->progress->method = PHP_CURL_USER; + break; case CURLOPT_HEADERFUNCTION: if (ch->handlers->write_header->func_name) { zval_ptr_dtor(&ch->handlers->write_header->func_name); @@ -1948,6 +2035,9 @@ if (ch->handlers->write_header->func_name) { zval_ptr_dtor(&ch->handlers->write_header->func_name); } + if(ch->handlers->progress->func_name) { + zval_ptr_dtor(&ch->handlers->progress->func_name); + } if (ch->handlers->passwd) { zval_ptr_dtor(&ch->handlers->passwd); } diff -u php-5.2.3/ext/curl/php_curl.h php-5.2.3.patched/ext/curl/php_curl.h --- php-5.2.3/ext/curl/php_curl.h 2007-01-01 10:35:48.000000000 +0100 +++ php-5.2.3.patched/ext/curl/php_curl.h 2007-06-16 13:31:07.000000000 +0200 @@ -97,10 +97,17 @@ } php_curl_read; typedef struct { + zval *func_name; + zend_fcall_info_cache fci_cache; + int method; +} php_curl_progress; + +typedef struct { php_curl_write *write; php_curl_write *write_header; php_curl_read *read; zval *passwd; + php_curl_progress *progress; } php_curl_handlers; struct _php_curl_error { ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/41712 -- Edit this bug report at http://bugs.php.net/?id=41712&edit=1