Skip to content

ext/curl: Add CURLOPT_DEBUGFUNCTION #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ PHP NEWS
. ext/bcmath: Check for scale overflow. (SakiTakamachi)
. [RFC] ext/bcmath: Added bcdivmod. (SakiTakamachi)

- Curl:
. Added CURLOPT_DEBUGFUNCTION as a Curl option. (Ayesh Karunaratne)

- Debugging:
. Fixed bug GH-15923 (GDB: Python Exception <class 'TypeError'>:
exceptions must derive from BaseException). (nielsdos)
Expand Down
14 changes: 14 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,13 @@ PHP 8.4 UPGRADE NOTES
to allow or abort the request.
. Added CURLOPT_SERVER_RESPONSE_TIMEOUT, which was formerly known as
CURLOPT_FTP_RESPONSE_TIMEOUT. Both constants hold the same value.
. Added CURLOPT_DEBUGFUNCTION support. This Curl option accepts a callable
that gets called during the request lifetime with the CurlHandle object,
an integer containing the debug message type, and a string containing the
debug message. The debug message type is one of CURLINFO_TEXT, CURLINFO_HEADER_IN,
CURLINFO_HEADER_OUT, CURLINFO_DATA_IN, CURLINFO_DATA_OUT, CURLINFO_SSL_DATA_OUT,
CURLINFO_SSL_DATA_IN constants. Once this option is set, CURLINFO_HEADER_OUT
must not be set because it uses the same libcurl functionality.

- Date:
. Added static methods
Expand Down Expand Up @@ -1041,6 +1048,13 @@ PHP 8.4 UPGRADE NOTES
. CURL_PREREQFUNC_OK.
. CURL_PREREQFUNC_ABORT.
. CURLOPT_SERVER_RESPONSE_TIMEOUT.
. CURLOPT_DEBUGFUNCTION.
. CURLINFO_TEXT.
. CURLINFO_HEADER_IN.
. CURLINFO_DATA_IN.
. CURLINFO_DATA_OUT.
. CURLINFO_SSL_DATA_OUT.
. CURLINFO_SSL_DATA_IN.

- Intl:
. The IntlDateFormatter class exposes now the new PATTERN constant
Expand Down
42 changes: 42 additions & 0 deletions ext/curl/curl.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,48 @@
*/
const CURLOPT_XFERINFOFUNCTION = UNKNOWN;

/**
* @var int
* @cvalue CURLOPT_DEBUGFUNCTION
*/
const CURLOPT_DEBUGFUNCTION = UNKNOWN;

/**
* @var int
* @cvalue CURLINFO_TEXT
*/
const CURLINFO_TEXT = UNKNOWN;

/**
* @var int
* @cvalue CURLINFO_HEADER_IN
*/
const CURLINFO_HEADER_IN = UNKNOWN;

/**
* @var int
* @cvalue CURLINFO_DATA_IN
*/
const CURLINFO_DATA_IN = UNKNOWN;

/**
* @var int
* @cvalue CURLINFO_DATA_OUT
*/
const CURLINFO_DATA_OUT = UNKNOWN;

/**
* @var int
* @cvalue CURLINFO_SSL_DATA_OUT
*/
const CURLINFO_SSL_DATA_OUT = UNKNOWN;

/**
* @var int
* @cvalue CURLINFO_SSL_DATA_IN
*/
const CURLINFO_SSL_DATA_IN = UNKNOWN;

/* */
/**
* @var int
Expand Down
9 changes: 8 additions & 1 deletion ext/curl/curl_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions ext/curl/curl_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ typedef struct {
zend_fcall_info_cache progress;
zend_fcall_info_cache xferinfo;
zend_fcall_info_cache fnmatch;
zend_fcall_info_cache debug;
#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */
zend_fcall_info_cache prereq;
#endif
Expand Down
66 changes: 57 additions & 9 deletions ext/curl/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,10 @@ static HashTable *curl_get_gc(zend_object *object, zval **table, int *n)
zend_get_gc_buffer_add_fcc(gc_buffer, &curl->handlers.fnmatch);
}

if (ZEND_FCC_INITIALIZED(curl->handlers.debug)) {
zend_get_gc_buffer_add_fcc(gc_buffer, &curl->handlers.debug);
}

#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */
if (ZEND_FCC_INITIALIZED(curl->handlers.prereq)) {
zend_get_gc_buffer_add_fcc(gc_buffer, &curl->handlers.prereq);
Expand Down Expand Up @@ -915,18 +919,46 @@ static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx
}
/* }}} */

static int curl_debug(CURL *cp, curl_infotype type, char *buf, size_t buf_len, void *ctx) /* {{{ */
static int curl_debug(CURL *handle, curl_infotype type, char *data, size_t size, void *clientp) /* {{{ */
{
php_curl *ch = (php_curl *)ctx;
php_curl *ch = (php_curl *)clientp;

if (type == CURLINFO_HEADER_OUT) {
if (ch->header.str) {
zend_string_release_ex(ch->header.str, 0);
}
ch->header.str = zend_string_init(buf, buf_len, 0);
}
#if PHP_CURL_DEBUG
fprintf(stderr, "curl_debug() called\n");
fprintf(stderr, "type = %d, data = %s\n", type, data);
#endif

// Implicitly store the headers for compatibility with CURLINFO_HEADER_OUT
// used as a Curl option. Previously, setting CURLINFO_HEADER_OUT set curl_debug
// as the CURLOPT_DEBUGFUNCTION and stored the debug data when type is set to
// CURLINFO_HEADER_OUT. For backward compatibility, we now store the headers
// but also call the user-callback function if available.
if (type == CURLINFO_HEADER_OUT) {
if (ch->header.str) {
zend_string_release_ex(ch->header.str, 0);
}
ch->header.str = zend_string_init(data, size, 0);
}

if (!ZEND_FCC_INITIALIZED(ch->handlers.debug)) {
return 0;
}

return 0;
zval args[3];

GC_ADDREF(&ch->std);
ZVAL_OBJ(&args[0], &ch->std);
ZVAL_LONG(&args[1], type);
ZVAL_STRINGL(&args[2], data, size);

ch->in_callback = true;
zend_call_known_fcc(&ch->handlers.debug, NULL, /* param_count */ 3, args, /* named_params */ NULL);
ch->in_callback = false;

zval_ptr_dtor(&args[0]);
zval_ptr_dtor(&args[2]);

return 0;
}
/* }}} */

Expand Down Expand Up @@ -1096,6 +1128,7 @@ void init_curl_handle(php_curl *ch)
ch->handlers.progress = empty_fcall_info_cache;
ch->handlers.xferinfo = empty_fcall_info_cache;
ch->handlers.fnmatch = empty_fcall_info_cache;
ch->handlers.debug = empty_fcall_info_cache;
#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */
ch->handlers.prereq = empty_fcall_info_cache;
#endif
Expand Down Expand Up @@ -1269,6 +1302,7 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source)
php_curl_copy_fcc_with_option(ch, CURLOPT_PROGRESSDATA, &ch->handlers.progress, &source->handlers.progress);
php_curl_copy_fcc_with_option(ch, CURLOPT_XFERINFODATA, &ch->handlers.xferinfo, &source->handlers.xferinfo);
php_curl_copy_fcc_with_option(ch, CURLOPT_FNMATCH_DATA, &ch->handlers.fnmatch, &source->handlers.fnmatch);
php_curl_copy_fcc_with_option(ch, CURLOPT_DEBUGDATA, &ch->handlers.debug, &source->handlers.debug);
#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */
php_curl_copy_fcc_with_option(ch, CURLOPT_PREREQDATA, &ch->handlers.prereq, &source->handlers.prereq);
#endif
Expand Down Expand Up @@ -1632,6 +1666,8 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
HANDLE_CURL_OPTION_CALLABLE(ch, CURLOPT_PROGRESS, handlers.progress, curl_progress);
HANDLE_CURL_OPTION_CALLABLE(ch, CURLOPT_XFERINFO, handlers.xferinfo, curl_xferinfo);
HANDLE_CURL_OPTION_CALLABLE(ch, CURLOPT_FNMATCH_, handlers.fnmatch, curl_fnmatch);
HANDLE_CURL_OPTION_CALLABLE(ch, CURLOPT_DEBUG, handlers.debug, curl_debug);

#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */
HANDLE_CURL_OPTION_CALLABLE(ch, CURLOPT_PREREQ, handlers.prereq, curl_prereqfunction);
#endif
Expand Down Expand Up @@ -2216,6 +2252,11 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
}

case CURLINFO_HEADER_OUT:
if (ZEND_FCC_INITIALIZED(ch->handlers.debug)) {
zend_value_error("CURLINFO_HEADER_OUT option must not be set when the CURLOPT_DEBUGFUNCTION option is set");
return FAILURE;
}

if (zend_is_true(zvalue)) {
curl_easy_setopt(ch->cp, CURLOPT_DEBUGFUNCTION, curl_debug);
curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA, (void *)ch);
Expand Down Expand Up @@ -2795,6 +2836,9 @@ static void curl_free_obj(zend_object *object)
if (ZEND_FCC_INITIALIZED(ch->handlers.fnmatch)) {
zend_fcc_dtor(&ch->handlers.fnmatch);
}
if (ZEND_FCC_INITIALIZED(ch->handlers.debug)) {
zend_fcc_dtor(&ch->handlers.debug);
}
#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */
if (ZEND_FCC_INITIALIZED(ch->handlers.prereq)) {
zend_fcc_dtor(&ch->handlers.prereq);
Expand Down Expand Up @@ -2878,6 +2922,10 @@ static void _php_curl_reset_handlers(php_curl *ch)
if (ZEND_FCC_INITIALIZED(ch->handlers.fnmatch)) {
zend_fcc_dtor(&ch->handlers.fnmatch);
}

if (ZEND_FCC_INITIALIZED(ch->handlers.debug)) {
zend_fcc_dtor(&ch->handlers.debug);
}
#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */
if (ZEND_FCC_INITIALIZED(ch->handlers.prereq)) {
zend_fcc_dtor(&ch->handlers.prereq);
Expand Down
1 change: 1 addition & 0 deletions ext/curl/sync-constants.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
'CURLOPT_PROGRESSDATA',
'CURLOPT_XFERINFODATA',
'CURLOPT_PREREQDATA',
'CURLOPT_DEBUGDATA',
];

const IGNORED_PHP_CONSTANTS = [
Expand Down
5 changes: 3 additions & 2 deletions ext/curl/tests/bug48203_multi.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ Variation of bug #48203 with curl_multi_exec (Crash when file pointers passed to
curl
--SKIPIF--
<?php
if (getenv("GITHUB_ACTIONS") && PHP_OS_FAMILY === "Darwin" && php_uname("m") === "x86_64") {
die("xfail Test fails for unknown reasons");
if (curl_version()['version_number'] === 0x080a00) {
// https://github.com/php/php-src/issues/15997
die('xfail due to a libcurl bug');
}
?>
--FILE--
Expand Down
5 changes: 3 additions & 2 deletions ext/curl/tests/bug71523.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ Bug #71523 (Copied handle with new option CURLOPT_HTTPHEADER crashes while curl_
curl
--SKIPIF--
<?php
if (getenv("GITHUB_ACTIONS") && PHP_OS_FAMILY === "Darwin" && php_uname("m") === "x86_64") {
die("xfail Test fails for unknown reasons");
if (curl_version()['version_number'] === 0x080a00) {
// https://github.com/php/php-src/issues/15997
die('xfail due to a libcurl bug');
}
?>
--FILE--
Expand Down
5 changes: 3 additions & 2 deletions ext/curl/tests/curl_basic_018.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ TestFest 2009 - AFUP - Thomas Rabaix <thomas.rabaix@gmail.com>
curl
--SKIPIF--
<?php
if (getenv("GITHUB_ACTIONS") && PHP_OS_FAMILY === "Darwin" && php_uname("m") === "x86_64") {
die("xfail Test fails for unknown reasons");
if (curl_version()['version_number'] === 0x080a00) {
// https://github.com/php/php-src/issues/15997
die('xfail due to a libcurl bug');
}
?>
--FILE--
Expand Down
5 changes: 3 additions & 2 deletions ext/curl/tests/curl_multi_getcontent_basic3.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ Rein Velt (rein@velt.org)
curl
--SKIPIF--
<?php
if (getenv("GITHUB_ACTIONS") && PHP_OS_FAMILY === "Darwin" && php_uname("m") === "x86_64") {
die("xfail Test fails for unknown reasons");
if (curl_version()['version_number'] === 0x080a00) {
// https://github.com/php/php-src/issues/15997
die('xfail due to a libcurl bug');
}
?>
--FILE--
Expand Down
Loading
Loading