ID: 41712
Comment by: top dot quack at freenet dot de
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:
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.
Previous Comments:
------------------------------------------------------------------------
[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 {
------------------------------------------------------------------------
[2007-06-16 12:16:39] sdteffen at gmail dot com
Description:
------------
The current PHP version does not allow to use the CURL progress
function callback (CURL_PROGRESSFUNCTION).
Reproduce code:
---------------
<?php
$ch = curl_init("http://www.php.net");
$fp = fopen("index.html", "w");
function curl_progress_callback($a=0,$b=0,$c=0, $d=0) {
echo "curl_progress_callback($a,$b,$c,$d)\n";
}
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'curl_progress_callback');
curl_exec($ch);
echo curl_close($ch);
fclose($fp);
?>
Expected result:
----------------
curl_progress_callback(0,1054,0,0)
curl_progress_callback(0,35131,0,0)
Actual result:
--------------
% Total % Received % Xferd Average Speed Time Time Time
Current
Dload Upload Total Spent Left
Speed
100 35131 0 35131 0 0 32344 0 --:--:-- 0:00:01
--:--:-- 52105
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=41712&edit=1