ID:               41712
 User updated by:  sdteffen 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:

The last patch is missing the changes to php_curl.h from the previous
patch. A file containing the complete patch with changes for both files
can be found under this URL:

http://sdteffen.de/php/php_curl_progress_callback.patch


Previous Comments:
------------------------------------------------------------------------

[2008-02-06 21:35:33] renatobraga at gmail dot com

Thanks Steffen,
Worked like a charm

------------------------------------------------------------------------

[2008-02-06 18:14:12] sdteffen at gmail dot com

I've updated the patch to pass the return value from the callback
function as Renato suggested:

--- php-5.2.5.orig/ext/curl/interface.c 2007-10-13 13:35:35.000000000
+0200
+++ php-5.2.5.patch/ext/curl/interface.c        2008-02-06 18:43:41.000000000
+0100
@@ -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);
@@ -780,6 +781,87 @@
 }
 /* }}} */
 
+/* {{{ 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;
+       size_t  rval = 0;
+
+#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;
+                       } else if (retval_ptr) {
+                               if (Z_TYPE_P(retval_ptr) != IS_LONG) {
+                                       convert_to_long_ex(&retval_ptr);
+                               }
+                               if(0 != Z_LVAL_P(retval_ptr))
+                                       rval = 1;
+                               zval_ptr_dtor(&retval_ptr);
+                       }
+                       zval_ptr_dtor(argv[0]);
+                       zval_ptr_dtor(argv[1]);
+                       zval_ptr_dtor(argv[2]);
+                       zval_ptr_dtor(argv[3]);
+                       break;
+               }
+       }
+       return rval;
+}
+/* }}} */
+
+
 /* {{{ curl_read
  */
 static size_t curl_read(char *data, size_t size, size_t nmemb, void
*ctx)
@@ -1068,6 +1150,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;
@@ -1422,6 +1505,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);
@@ -1953,6 +2047,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);
        }

------------------------------------------------------------------------

[2008-02-05 15:56:56] renatobraga at gmail dot com

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

------------------------------------------------------------------------

[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  {

------------------------------------------------------------------------

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

Reply via email to