Return to interface.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / curl |
1.1 ! misho 1: /* ! 2: +----------------------------------------------------------------------+ ! 3: | PHP Version 5 | ! 4: +----------------------------------------------------------------------+ ! 5: | Copyright (c) 1997-2012 The PHP Group | ! 6: +----------------------------------------------------------------------+ ! 7: | This source file is subject to version 3.01 of the PHP license, | ! 8: | that is bundled with this package in the file LICENSE, and is | ! 9: | available through the world-wide-web at the following url: | ! 10: | http://www.php.net/license/3_01.txt | ! 11: | If you did not receive a copy of the PHP license and are unable to | ! 12: | obtain it through the world-wide-web, please send a note to | ! 13: | license@php.net so we can mail you a copy immediately. | ! 14: +----------------------------------------------------------------------+ ! 15: | Author: Sterling Hughes <sterling@php.net> | ! 16: +----------------------------------------------------------------------+ ! 17: */ ! 18: ! 19: /* $Id: interface.c 321634 2012-01-01 13:15:04Z felipe $ */ ! 20: ! 21: #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS ! 22: ! 23: #ifdef HAVE_CONFIG_H ! 24: #include "config.h" ! 25: #endif ! 26: ! 27: #include "php.h" ! 28: ! 29: #if HAVE_CURL ! 30: ! 31: #include <stdio.h> ! 32: #include <string.h> ! 33: ! 34: #ifdef PHP_WIN32 ! 35: #include <winsock2.h> ! 36: #include <sys/types.h> ! 37: #endif ! 38: ! 39: #include <curl/curl.h> ! 40: #include <curl/easy.h> ! 41: ! 42: /* As of curl 7.11.1 this is no longer defined inside curl.h */ ! 43: #ifndef HttpPost ! 44: #define HttpPost curl_httppost ! 45: #endif ! 46: ! 47: /* {{{ cruft for thread safe SSL crypto locks */ ! 48: #if defined(ZTS) && defined(HAVE_CURL_SSL) ! 49: # ifdef PHP_WIN32 ! 50: # define PHP_CURL_NEED_OPENSSL_TSL ! 51: # include <openssl/crypto.h> ! 52: # else /* !PHP_WIN32 */ ! 53: # if defined(HAVE_CURL_OPENSSL) ! 54: # if defined(HAVE_OPENSSL_CRYPTO_H) ! 55: # define PHP_CURL_NEED_OPENSSL_TSL ! 56: # include <openssl/crypto.h> ! 57: # else ! 58: # warning \ ! 59: "libcurl was compiled with OpenSSL support, but configure could not find " \ ! 60: "openssl/crypto.h; thus no SSL crypto locking callbacks will be set, which may " \ ! 61: "cause random crashes on SSL requests" ! 62: # endif ! 63: # elif defined(HAVE_CURL_GNUTLS) ! 64: # if defined(HAVE_GCRYPT_H) ! 65: # define PHP_CURL_NEED_GNUTLS_TSL ! 66: # include <gcrypt.h> ! 67: # else ! 68: # warning \ ! 69: "libcurl was compiled with GnuTLS support, but configure could not find " \ ! 70: "gcrypt.h; thus no SSL crypto locking callbacks will be set, which may " \ ! 71: "cause random crashes on SSL requests" ! 72: # endif ! 73: # else ! 74: # warning \ ! 75: "libcurl was compiled with SSL support, but configure could not determine which" \ ! 76: "library was used; thus no SSL crypto locking callbacks will be set, which may " \ ! 77: "cause random crashes on SSL requests" ! 78: # endif /* HAVE_CURL_OPENSSL || HAVE_CURL_GNUTLS */ ! 79: # endif /* PHP_WIN32 */ ! 80: #endif /* ZTS && HAVE_CURL_SSL */ ! 81: /* }}} */ ! 82: ! 83: #define SMART_STR_PREALLOC 4096 ! 84: ! 85: #include "ext/standard/php_smart_str.h" ! 86: #include "ext/standard/info.h" ! 87: #include "ext/standard/file.h" ! 88: #include "ext/standard/url.h" ! 89: #include "php_curl.h" ! 90: ! 91: int le_curl; ! 92: int le_curl_multi_handle; ! 93: ! 94: #ifdef PHP_CURL_NEED_OPENSSL_TSL /* {{{ */ ! 95: static MUTEX_T *php_curl_openssl_tsl = NULL; ! 96: ! 97: static void php_curl_ssl_lock(int mode, int n, const char * file, int line) ! 98: { ! 99: if (mode & CRYPTO_LOCK) { ! 100: tsrm_mutex_lock(php_curl_openssl_tsl[n]); ! 101: } else { ! 102: tsrm_mutex_unlock(php_curl_openssl_tsl[n]); ! 103: } ! 104: } ! 105: ! 106: static unsigned long php_curl_ssl_id(void) ! 107: { ! 108: return (unsigned long) tsrm_thread_id(); ! 109: } ! 110: #endif ! 111: /* }}} */ ! 112: ! 113: #ifdef PHP_CURL_NEED_GNUTLS_TSL /* {{{ */ ! 114: static int php_curl_ssl_mutex_create(void **m) ! 115: { ! 116: if (*((MUTEX_T *) m) = tsrm_mutex_alloc()) { ! 117: return SUCCESS; ! 118: } else { ! 119: return FAILURE; ! 120: } ! 121: } ! 122: ! 123: static int php_curl_ssl_mutex_destroy(void **m) ! 124: { ! 125: tsrm_mutex_free(*((MUTEX_T *) m)); ! 126: return SUCCESS; ! 127: } ! 128: ! 129: static int php_curl_ssl_mutex_lock(void **m) ! 130: { ! 131: return tsrm_mutex_lock(*((MUTEX_T *) m)); ! 132: } ! 133: ! 134: static int php_curl_ssl_mutex_unlock(void **m) ! 135: { ! 136: return tsrm_mutex_unlock(*((MUTEX_T *) m)); ! 137: } ! 138: ! 139: static struct gcry_thread_cbs php_curl_gnutls_tsl = { ! 140: GCRY_THREAD_OPTION_USER, ! 141: NULL, ! 142: php_curl_ssl_mutex_create, ! 143: php_curl_ssl_mutex_destroy, ! 144: php_curl_ssl_mutex_lock, ! 145: php_curl_ssl_mutex_unlock ! 146: }; ! 147: #endif ! 148: /* }}} */ ! 149: ! 150: static void _php_curl_close_ex(php_curl *ch TSRMLS_DC); ! 151: static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC); ! 152: ! 153: ! 154: #define SAVE_CURL_ERROR(__handle, __err) (__handle)->err.no = (int) __err; ! 155: ! 156: #define CAAL(s, v) add_assoc_long_ex(return_value, s, sizeof(s), (long) v); ! 157: #define CAAD(s, v) add_assoc_double_ex(return_value, s, sizeof(s), (double) v); ! 158: #define CAAS(s, v) add_assoc_string_ex(return_value, s, sizeof(s), (char *) (v ? v : ""), 1); ! 159: #define CAAZ(s, v) add_assoc_zval_ex(return_value, s, sizeof(s), (zval *) v); ! 160: ! 161: #if defined(PHP_WIN32) || defined(__GNUC__) ! 162: # define php_curl_ret(__ret) RETVAL_FALSE; return __ret; ! 163: #else ! 164: # define php_curl_ret(__ret) RETVAL_FALSE; return; ! 165: #endif ! 166: ! 167: static int php_curl_option_url(php_curl *ch, const char *url, const int len) /* {{{ */ ! 168: { ! 169: CURLcode error = CURLE_OK; ! 170: #if LIBCURL_VERSION_NUM < 0x071100 ! 171: char *copystr = NULL; ! 172: #endif ! 173: TSRMLS_FETCH(); ! 174: ! 175: /* Disable file:// if open_basedir or safe_mode are used */ ! 176: if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) { ! 177: #if LIBCURL_VERSION_NUM >= 0x071304 ! 178: error = curl_easy_setopt(ch->cp, CURLOPT_PROTOCOLS, CURLPROTO_ALL & ~CURLPROTO_FILE); ! 179: #else ! 180: php_url *uri; ! 181: ! 182: if (!(uri = php_url_parse_ex(url, len))) { ! 183: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid URL '%s'", url); ! 184: return 0; ! 185: } ! 186: ! 187: if (uri->scheme && !strncasecmp("file", uri->scheme, sizeof("file"))) { ! 188: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Protocol 'file' disabled in cURL"); ! 189: php_url_free(uri); ! 190: return 0; ! 191: } ! 192: php_url_free(uri); ! 193: #endif ! 194: } ! 195: /* Strings passed to libcurl as 'char *' arguments, are copied by the library... NOTE: before 7.17.0 strings were not copied. */ ! 196: #if LIBCURL_VERSION_NUM >= 0x071100 ! 197: error = curl_easy_setopt(ch->cp, CURLOPT_URL, url); ! 198: #else ! 199: copystr = estrndup(url, len); ! 200: error = curl_easy_setopt(ch->cp, CURLOPT_URL, copystr); ! 201: zend_llist_add_element(&ch->to_free->str, ©str); ! 202: #endif ! 203: ! 204: return (error == CURLE_OK ? 1 : 0); ! 205: } ! 206: /* }}} */ ! 207: ! 208: int _php_curl_verify_handlers(php_curl *ch, int reporterror TSRMLS_DC) /* {{{ */ ! 209: { ! 210: php_stream *stream; ! 211: if (!ch || !ch->handlers) { ! 212: return 0; ! 213: } ! 214: ! 215: if (ch->handlers->std_err) { ! 216: stream = (php_stream *) zend_fetch_resource(&ch->handlers->std_err TSRMLS_CC, -1, NULL, NULL, 2, php_file_le_stream(), php_file_le_pstream()); ! 217: if (stream == NULL) { ! 218: if (reporterror) { ! 219: php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_STDERR resource has gone away, resetting to stderr"); ! 220: } ! 221: zval_ptr_dtor(&ch->handlers->std_err); ! 222: ch->handlers->std_err = NULL; ! 223: ! 224: curl_easy_setopt(ch->cp, CURLOPT_STDERR, stderr); ! 225: } ! 226: } ! 227: if (ch->handlers->read && ch->handlers->read->stream) { ! 228: stream = (php_stream *) zend_fetch_resource(&ch->handlers->read->stream TSRMLS_CC, -1, NULL, NULL, 2, php_file_le_stream(), php_file_le_pstream()); ! 229: if (stream == NULL) { ! 230: if (reporterror) { ! 231: php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_INFILE resource has gone away, resetting to default"); ! 232: } ! 233: zval_ptr_dtor(&ch->handlers->read->stream); ! 234: ch->handlers->read->fd = 0; ! 235: ch->handlers->read->fp = 0; ! 236: ch->handlers->read->stream = NULL; ! 237: ! 238: curl_easy_setopt(ch->cp, CURLOPT_INFILE, (void *) ch); ! 239: } ! 240: } ! 241: if (ch->handlers->write_header && ch->handlers->write_header->stream) { ! 242: stream = (php_stream *) zend_fetch_resource(&ch->handlers->write_header->stream TSRMLS_CC, -1, NULL, NULL, 2, php_file_le_stream(), php_file_le_pstream()); ! 243: if (stream == NULL) { ! 244: if (reporterror) { ! 245: php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_WRITEHEADER resource has gone away, resetting to default"); ! 246: } ! 247: zval_ptr_dtor(&ch->handlers->write_header->stream); ! 248: ch->handlers->write_header->fp = 0; ! 249: ch->handlers->write_header->stream = NULL; ! 250: ! 251: ch->handlers->write_header->method = PHP_CURL_IGNORE; ! 252: curl_easy_setopt(ch->cp, CURLOPT_WRITEHEADER, (void *) ch); ! 253: } ! 254: } ! 255: if (ch->handlers->write && ch->handlers->write->stream) { ! 256: stream = (php_stream *) zend_fetch_resource(&ch->handlers->write->stream TSRMLS_CC, -1, NULL, NULL, 2, php_file_le_stream(), php_file_le_pstream()); ! 257: if (stream == NULL) { ! 258: if (reporterror) { ! 259: php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_FILE resource has gone away, resetting to default"); ! 260: } ! 261: zval_ptr_dtor(&ch->handlers->write->stream); ! 262: ch->handlers->write->fp = 0; ! 263: ch->handlers->write->stream = NULL; ! 264: ! 265: ch->handlers->write->method = PHP_CURL_STDOUT; ! 266: ch->handlers->write->type = PHP_CURL_ASCII; ! 267: curl_easy_setopt(ch->cp, CURLOPT_FILE, (void *) ch); ! 268: } ! 269: } ! 270: return 1; ! 271: } ! 272: /* }}} */ ! 273: ! 274: /* {{{ arginfo */ ! 275: ZEND_BEGIN_ARG_INFO_EX(arginfo_curl_version, 0, 0, 0) ! 276: ZEND_ARG_INFO(0, version) ! 277: ZEND_END_ARG_INFO() ! 278: ! 279: ZEND_BEGIN_ARG_INFO_EX(arginfo_curl_init, 0, 0, 0) ! 280: ZEND_ARG_INFO(0, url) ! 281: ZEND_END_ARG_INFO() ! 282: ! 283: ZEND_BEGIN_ARG_INFO(arginfo_curl_copy_handle, 0) ! 284: ZEND_ARG_INFO(0, ch) ! 285: ZEND_END_ARG_INFO() ! 286: ! 287: ZEND_BEGIN_ARG_INFO(arginfo_curl_setopt, 0) ! 288: ZEND_ARG_INFO(0, ch) ! 289: ZEND_ARG_INFO(0, option) ! 290: ZEND_ARG_INFO(0, value) ! 291: ZEND_END_ARG_INFO() ! 292: ! 293: ZEND_BEGIN_ARG_INFO(arginfo_curl_setopt_array, 0) ! 294: ZEND_ARG_INFO(0, ch) ! 295: ZEND_ARG_ARRAY_INFO(0, options, 0) ! 296: ZEND_END_ARG_INFO() ! 297: ! 298: ZEND_BEGIN_ARG_INFO(arginfo_curl_exec, 0) ! 299: ZEND_ARG_INFO(0, ch) ! 300: ZEND_END_ARG_INFO() ! 301: ! 302: ZEND_BEGIN_ARG_INFO_EX(arginfo_curl_getinfo, 0, 0, 1) ! 303: ZEND_ARG_INFO(0, ch) ! 304: ZEND_ARG_INFO(0, option) ! 305: ZEND_END_ARG_INFO() ! 306: ! 307: ZEND_BEGIN_ARG_INFO(arginfo_curl_error, 0) ! 308: ZEND_ARG_INFO(0, ch) ! 309: ZEND_END_ARG_INFO() ! 310: ! 311: ZEND_BEGIN_ARG_INFO(arginfo_curl_errno, 0) ! 312: ZEND_ARG_INFO(0, ch) ! 313: ZEND_END_ARG_INFO() ! 314: ! 315: ZEND_BEGIN_ARG_INFO(arginfo_curl_close, 0) ! 316: ZEND_ARG_INFO(0, ch) ! 317: ZEND_END_ARG_INFO() ! 318: ! 319: ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_init, 0) ! 320: ZEND_END_ARG_INFO() ! 321: ! 322: ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_add_handle, 0) ! 323: ZEND_ARG_INFO(0, mh) ! 324: ZEND_ARG_INFO(0, ch) ! 325: ZEND_END_ARG_INFO() ! 326: ! 327: ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_remove_handle, 0) ! 328: ZEND_ARG_INFO(0, mh) ! 329: ZEND_ARG_INFO(0, ch) ! 330: ZEND_END_ARG_INFO() ! 331: ! 332: ZEND_BEGIN_ARG_INFO_EX(arginfo_curl_multi_select, 0, 0, 1) ! 333: ZEND_ARG_INFO(0, mh) ! 334: ZEND_ARG_INFO(0, timeout) ! 335: ZEND_END_ARG_INFO() ! 336: ! 337: ZEND_BEGIN_ARG_INFO_EX(arginfo_curl_multi_exec, 0, 0, 1) ! 338: ZEND_ARG_INFO(0, mh) ! 339: ZEND_ARG_INFO(1, still_running) ! 340: ZEND_END_ARG_INFO() ! 341: ! 342: ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_getcontent, 0) ! 343: ZEND_ARG_INFO(0, ch) ! 344: ZEND_END_ARG_INFO() ! 345: ! 346: ZEND_BEGIN_ARG_INFO_EX(arginfo_curl_multi_info_read, 0, 0, 1) ! 347: ZEND_ARG_INFO(0, mh) ! 348: ZEND_ARG_INFO(1, msgs_in_queue) ! 349: ZEND_END_ARG_INFO() ! 350: ! 351: ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_close, 0) ! 352: ZEND_ARG_INFO(0, mh) ! 353: ZEND_END_ARG_INFO() ! 354: /* }}} */ ! 355: ! 356: /* {{{ curl_functions[] ! 357: */ ! 358: const zend_function_entry curl_functions[] = { ! 359: PHP_FE(curl_init, arginfo_curl_init) ! 360: PHP_FE(curl_copy_handle, arginfo_curl_copy_handle) ! 361: PHP_FE(curl_version, arginfo_curl_version) ! 362: PHP_FE(curl_setopt, arginfo_curl_setopt) ! 363: PHP_FE(curl_setopt_array, arginfo_curl_setopt_array) ! 364: PHP_FE(curl_exec, arginfo_curl_exec) ! 365: PHP_FE(curl_getinfo, arginfo_curl_getinfo) ! 366: PHP_FE(curl_error, arginfo_curl_error) ! 367: PHP_FE(curl_errno, arginfo_curl_errno) ! 368: PHP_FE(curl_close, arginfo_curl_close) ! 369: PHP_FE(curl_multi_init, arginfo_curl_multi_init) ! 370: PHP_FE(curl_multi_add_handle, arginfo_curl_multi_add_handle) ! 371: PHP_FE(curl_multi_remove_handle, arginfo_curl_multi_remove_handle) ! 372: PHP_FE(curl_multi_select, arginfo_curl_multi_select) ! 373: PHP_FE(curl_multi_exec, arginfo_curl_multi_exec) ! 374: PHP_FE(curl_multi_getcontent, arginfo_curl_multi_getcontent) ! 375: PHP_FE(curl_multi_info_read, arginfo_curl_multi_info_read) ! 376: PHP_FE(curl_multi_close, arginfo_curl_multi_close) ! 377: PHP_FE_END ! 378: }; ! 379: /* }}} */ ! 380: ! 381: /* {{{ curl_module_entry ! 382: */ ! 383: zend_module_entry curl_module_entry = { ! 384: STANDARD_MODULE_HEADER, ! 385: "curl", ! 386: curl_functions, ! 387: PHP_MINIT(curl), ! 388: PHP_MSHUTDOWN(curl), ! 389: NULL, ! 390: NULL, ! 391: PHP_MINFO(curl), ! 392: NO_VERSION_YET, ! 393: STANDARD_MODULE_PROPERTIES ! 394: }; ! 395: /* }}} */ ! 396: ! 397: #ifdef COMPILE_DL_CURL ! 398: ZEND_GET_MODULE (curl) ! 399: #endif ! 400: ! 401: /* {{{ PHP_INI_BEGIN */ ! 402: PHP_INI_BEGIN() ! 403: PHP_INI_ENTRY("curl.cainfo", "", PHP_INI_SYSTEM, NULL) ! 404: PHP_INI_END() ! 405: /* }}} */ ! 406: ! 407: /* {{{ PHP_MINFO_FUNCTION ! 408: */ ! 409: PHP_MINFO_FUNCTION(curl) ! 410: { ! 411: curl_version_info_data *d; ! 412: char **p; ! 413: char str[1024]; ! 414: size_t n = 0; ! 415: ! 416: d = curl_version_info(CURLVERSION_NOW); ! 417: php_info_print_table_start(); ! 418: php_info_print_table_row(2, "cURL support", "enabled"); ! 419: php_info_print_table_row(2, "cURL Information", d->version); ! 420: sprintf(str, "%d", d->age); ! 421: php_info_print_table_row(2, "Age", str); ! 422: ! 423: /* To update on each new cURL release using src/main.c in cURL sources */ ! 424: if (d->features) { ! 425: struct feat { ! 426: const char *name; ! 427: int bitmask; ! 428: }; ! 429: ! 430: unsigned int i; ! 431: ! 432: static const struct feat feats[] = { ! 433: #if LIBCURL_VERSION_NUM > 0x070a06 /* 7.10.7 */ ! 434: {"AsynchDNS", CURL_VERSION_ASYNCHDNS}, ! 435: #endif ! 436: #if LIBCURL_VERSION_NUM > 0x070a05 /* 7.10.6 */ ! 437: {"Debug", CURL_VERSION_DEBUG}, ! 438: {"GSS-Negotiate", CURL_VERSION_GSSNEGOTIATE}, ! 439: #endif ! 440: #if LIBCURL_VERSION_NUM > 0x070b02 /* 7.12.0 */ ! 441: {"IDN", CURL_VERSION_IDN}, ! 442: #endif ! 443: #ifdef CURL_VERSION_IPV6 ! 444: {"IPv6", CURL_VERSION_IPV6}, ! 445: #endif ! 446: #if LIBCURL_VERSION_NUM > 0x070b00 /* 7.11.1 */ ! 447: {"Largefile", CURL_VERSION_LARGEFILE}, ! 448: #endif ! 449: #if LIBCURL_VERSION_NUM > 0x070a05 /* 7.10.6 */ ! 450: {"NTLM", CURL_VERSION_NTLM}, ! 451: #endif ! 452: #if LIBCURL_VERSION_NUM > 0x070a07 /* 7.10.8 */ ! 453: {"SPNEGO", CURL_VERSION_SPNEGO}, ! 454: #endif ! 455: #ifdef CURL_VERSION_SSL ! 456: {"SSL", CURL_VERSION_SSL}, ! 457: #endif ! 458: #if LIBCURL_VERSION_NUM > 0x070d01 /* 7.13.2 */ ! 459: {"SSPI", CURL_VERSION_SSPI}, ! 460: #endif ! 461: #ifdef CURL_VERSION_KERBEROS4 ! 462: {"krb4", CURL_VERSION_KERBEROS4}, ! 463: #endif ! 464: #ifdef CURL_VERSION_LIBZ ! 465: {"libz", CURL_VERSION_LIBZ}, ! 466: #endif ! 467: #if LIBCURL_VERSION_NUM > 0x070f03 /* 7.15.4 */ ! 468: {"CharConv", CURL_VERSION_CONV}, ! 469: #endif ! 470: {NULL, 0} ! 471: }; ! 472: ! 473: php_info_print_table_row(1, "Features"); ! 474: for(i=0; i<sizeof(feats)/sizeof(feats[0]); i++) { ! 475: if (feats[i].name) { ! 476: php_info_print_table_row(2, feats[i].name, d->features & feats[i].bitmask ? "Yes" : "No"); ! 477: } ! 478: } ! 479: } ! 480: ! 481: n = 0; ! 482: p = (char **) d->protocols; ! 483: while (*p != NULL) { ! 484: n += sprintf(str + n, "%s%s", *p, *(p + 1) != NULL ? ", " : ""); ! 485: p++; ! 486: } ! 487: php_info_print_table_row(2, "Protocols", str); ! 488: ! 489: php_info_print_table_row(2, "Host", d->host); ! 490: ! 491: if (d->ssl_version) { ! 492: php_info_print_table_row(2, "SSL Version", d->ssl_version); ! 493: } ! 494: ! 495: if (d->libz_version) { ! 496: php_info_print_table_row(2, "ZLib Version", d->libz_version); ! 497: } ! 498: ! 499: #if defined(CURLVERSION_SECOND) && CURLVERSION_NOW >= CURLVERSION_SECOND ! 500: if (d->ares) { ! 501: php_info_print_table_row(2, "ZLib Version", d->ares); ! 502: } ! 503: #endif ! 504: ! 505: #if defined(CURLVERSION_THIRD) && CURLVERSION_NOW >= CURLVERSION_THIRD ! 506: if (d->libidn) { ! 507: php_info_print_table_row(2, "libIDN Version", d->libidn); ! 508: } ! 509: #endif ! 510: ! 511: #if LIBCURL_VERSION_NUM >= 0x071300 ! 512: ! 513: if (d->iconv_ver_num) { ! 514: php_info_print_table_row(2, "IconV Version", d->iconv_ver_num); ! 515: } ! 516: ! 517: if (d->libssh_version) { ! 518: php_info_print_table_row(2, "libSSH Version", d->libssh_version); ! 519: } ! 520: #endif ! 521: php_info_print_table_end(); ! 522: } ! 523: /* }}} */ ! 524: ! 525: #define REGISTER_CURL_CONSTANT(__c) REGISTER_LONG_CONSTANT(#__c, __c, CONST_CS | CONST_PERSISTENT) ! 526: ! 527: /* {{{ PHP_MINIT_FUNCTION ! 528: */ ! 529: PHP_MINIT_FUNCTION(curl) ! 530: { ! 531: le_curl = zend_register_list_destructors_ex(_php_curl_close, NULL, "curl", module_number); ! 532: le_curl_multi_handle = zend_register_list_destructors_ex(_php_curl_multi_close, NULL, "curl_multi", module_number); ! 533: ! 534: REGISTER_INI_ENTRIES(); ! 535: ! 536: /* See http://curl.haxx.se/lxr/source/docs/libcurl/symbols-in-versions ! 537: or curl src/docs/libcurl/symbols-in-versions for a (almost) complete list ! 538: of options and which version they were introduced */ ! 539: ! 540: /* Constants for curl_setopt() */ ! 541: #if LIBCURL_VERSION_NUM > 0x070a07 /* CURLOPT_IPRESOLVE is available since curl 7.10.8 */ ! 542: REGISTER_CURL_CONSTANT(CURLOPT_IPRESOLVE); ! 543: REGISTER_CURL_CONSTANT(CURL_IPRESOLVE_WHATEVER); ! 544: REGISTER_CURL_CONSTANT(CURL_IPRESOLVE_V4); ! 545: REGISTER_CURL_CONSTANT(CURL_IPRESOLVE_V6); ! 546: #endif ! 547: REGISTER_CURL_CONSTANT(CURLOPT_DNS_USE_GLOBAL_CACHE); ! 548: REGISTER_CURL_CONSTANT(CURLOPT_DNS_CACHE_TIMEOUT); ! 549: REGISTER_CURL_CONSTANT(CURLOPT_PORT); ! 550: REGISTER_CURL_CONSTANT(CURLOPT_FILE); ! 551: REGISTER_CURL_CONSTANT(CURLOPT_READDATA); ! 552: REGISTER_CURL_CONSTANT(CURLOPT_INFILE); ! 553: REGISTER_CURL_CONSTANT(CURLOPT_INFILESIZE); ! 554: REGISTER_CURL_CONSTANT(CURLOPT_URL); ! 555: REGISTER_CURL_CONSTANT(CURLOPT_PROXY); ! 556: REGISTER_CURL_CONSTANT(CURLOPT_VERBOSE); ! 557: REGISTER_CURL_CONSTANT(CURLOPT_HEADER); ! 558: REGISTER_CURL_CONSTANT(CURLOPT_HTTPHEADER); ! 559: REGISTER_CURL_CONSTANT(CURLOPT_NOPROGRESS); ! 560: REGISTER_CURL_CONSTANT(CURLOPT_PROGRESSFUNCTION); ! 561: REGISTER_CURL_CONSTANT(CURLOPT_NOBODY); ! 562: REGISTER_CURL_CONSTANT(CURLOPT_FAILONERROR); ! 563: REGISTER_CURL_CONSTANT(CURLOPT_UPLOAD); ! 564: REGISTER_CURL_CONSTANT(CURLOPT_POST); ! 565: REGISTER_CURL_CONSTANT(CURLOPT_FTPLISTONLY); ! 566: REGISTER_CURL_CONSTANT(CURLOPT_FTPAPPEND); ! 567: REGISTER_CURL_CONSTANT(CURLOPT_NETRC); ! 568: REGISTER_CURL_CONSTANT(CURLOPT_FOLLOWLOCATION); ! 569: #if CURLOPT_FTPASCII != 0 ! 570: REGISTER_CURL_CONSTANT(CURLOPT_FTPASCII); ! 571: #endif ! 572: REGISTER_CURL_CONSTANT(CURLOPT_PUT); ! 573: #if CURLOPT_MUTE != 0 ! 574: REGISTER_CURL_CONSTANT(CURLOPT_MUTE); ! 575: #endif ! 576: REGISTER_CURL_CONSTANT(CURLOPT_USERPWD); ! 577: REGISTER_CURL_CONSTANT(CURLOPT_PROXYUSERPWD); ! 578: REGISTER_CURL_CONSTANT(CURLOPT_RANGE); ! 579: REGISTER_CURL_CONSTANT(CURLOPT_TIMEOUT); ! 580: #if LIBCURL_VERSION_NUM > 0x071002 ! 581: REGISTER_CURL_CONSTANT(CURLOPT_TIMEOUT_MS); ! 582: #endif ! 583: REGISTER_CURL_CONSTANT(CURLOPT_POSTFIELDS); ! 584: REGISTER_CURL_CONSTANT(CURLOPT_REFERER); ! 585: REGISTER_CURL_CONSTANT(CURLOPT_USERAGENT); ! 586: REGISTER_CURL_CONSTANT(CURLOPT_FTPPORT); ! 587: REGISTER_CURL_CONSTANT(CURLOPT_FTP_USE_EPSV); ! 588: REGISTER_CURL_CONSTANT(CURLOPT_LOW_SPEED_LIMIT); ! 589: REGISTER_CURL_CONSTANT(CURLOPT_LOW_SPEED_TIME); ! 590: REGISTER_CURL_CONSTANT(CURLOPT_RESUME_FROM); ! 591: REGISTER_CURL_CONSTANT(CURLOPT_COOKIE); ! 592: REGISTER_CURL_CONSTANT(CURLOPT_COOKIESESSION); ! 593: REGISTER_CURL_CONSTANT(CURLOPT_AUTOREFERER); ! 594: REGISTER_CURL_CONSTANT(CURLOPT_SSLCERT); ! 595: REGISTER_CURL_CONSTANT(CURLOPT_SSLCERTPASSWD); ! 596: REGISTER_CURL_CONSTANT(CURLOPT_WRITEHEADER); ! 597: REGISTER_CURL_CONSTANT(CURLOPT_SSL_VERIFYHOST); ! 598: REGISTER_CURL_CONSTANT(CURLOPT_COOKIEFILE); ! 599: REGISTER_CURL_CONSTANT(CURLOPT_SSLVERSION); ! 600: REGISTER_CURL_CONSTANT(CURLOPT_TIMECONDITION); ! 601: REGISTER_CURL_CONSTANT(CURLOPT_TIMEVALUE); ! 602: REGISTER_CURL_CONSTANT(CURLOPT_CUSTOMREQUEST); ! 603: REGISTER_CURL_CONSTANT(CURLOPT_STDERR); ! 604: REGISTER_CURL_CONSTANT(CURLOPT_TRANSFERTEXT); ! 605: REGISTER_CURL_CONSTANT(CURLOPT_RETURNTRANSFER); ! 606: REGISTER_CURL_CONSTANT(CURLOPT_QUOTE); ! 607: REGISTER_CURL_CONSTANT(CURLOPT_POSTQUOTE); ! 608: REGISTER_CURL_CONSTANT(CURLOPT_INTERFACE); ! 609: REGISTER_CURL_CONSTANT(CURLOPT_KRB4LEVEL); ! 610: REGISTER_CURL_CONSTANT(CURLOPT_HTTPPROXYTUNNEL); ! 611: REGISTER_CURL_CONSTANT(CURLOPT_FILETIME); ! 612: REGISTER_CURL_CONSTANT(CURLOPT_WRITEFUNCTION); ! 613: REGISTER_CURL_CONSTANT(CURLOPT_READFUNCTION); ! 614: #if CURLOPT_PASSWDFUNCTION != 0 ! 615: REGISTER_CURL_CONSTANT(CURLOPT_PASSWDFUNCTION); ! 616: #endif ! 617: REGISTER_CURL_CONSTANT(CURLOPT_HEADERFUNCTION); ! 618: REGISTER_CURL_CONSTANT(CURLOPT_MAXREDIRS); ! 619: REGISTER_CURL_CONSTANT(CURLOPT_MAXCONNECTS); ! 620: REGISTER_CURL_CONSTANT(CURLOPT_CLOSEPOLICY); ! 621: REGISTER_CURL_CONSTANT(CURLOPT_FRESH_CONNECT); ! 622: REGISTER_CURL_CONSTANT(CURLOPT_FORBID_REUSE); ! 623: REGISTER_CURL_CONSTANT(CURLOPT_RANDOM_FILE); ! 624: REGISTER_CURL_CONSTANT(CURLOPT_EGDSOCKET); ! 625: REGISTER_CURL_CONSTANT(CURLOPT_CONNECTTIMEOUT); ! 626: #if LIBCURL_VERSION_NUM > 0x071002 ! 627: REGISTER_CURL_CONSTANT(CURLOPT_CONNECTTIMEOUT_MS); ! 628: #endif ! 629: REGISTER_CURL_CONSTANT(CURLOPT_SSL_VERIFYPEER); ! 630: REGISTER_CURL_CONSTANT(CURLOPT_CAINFO); ! 631: REGISTER_CURL_CONSTANT(CURLOPT_CAPATH); ! 632: REGISTER_CURL_CONSTANT(CURLOPT_COOKIEJAR); ! 633: REGISTER_CURL_CONSTANT(CURLOPT_SSL_CIPHER_LIST); ! 634: REGISTER_CURL_CONSTANT(CURLOPT_BINARYTRANSFER); ! 635: REGISTER_CURL_CONSTANT(CURLOPT_NOSIGNAL); ! 636: REGISTER_CURL_CONSTANT(CURLOPT_PROXYTYPE); ! 637: REGISTER_CURL_CONSTANT(CURLOPT_BUFFERSIZE); ! 638: REGISTER_CURL_CONSTANT(CURLOPT_HTTPGET); ! 639: REGISTER_CURL_CONSTANT(CURLOPT_HTTP_VERSION); ! 640: REGISTER_CURL_CONSTANT(CURLOPT_SSLKEY); ! 641: REGISTER_CURL_CONSTANT(CURLOPT_SSLKEYTYPE); ! 642: REGISTER_CURL_CONSTANT(CURLOPT_SSLKEYPASSWD); ! 643: REGISTER_CURL_CONSTANT(CURLOPT_SSLENGINE); ! 644: REGISTER_CURL_CONSTANT(CURLOPT_SSLENGINE_DEFAULT); ! 645: REGISTER_CURL_CONSTANT(CURLOPT_SSLCERTTYPE); ! 646: REGISTER_CURL_CONSTANT(CURLOPT_CRLF); ! 647: REGISTER_CURL_CONSTANT(CURLOPT_ENCODING); ! 648: REGISTER_CURL_CONSTANT(CURLOPT_PROXYPORT); ! 649: REGISTER_CURL_CONSTANT(CURLOPT_UNRESTRICTED_AUTH); ! 650: REGISTER_CURL_CONSTANT(CURLOPT_FTP_USE_EPRT); ! 651: #if LIBCURL_VERSION_NUM > 0x070b01 /* CURLOPT_TCP_NODELAY is available since curl 7.11.2 */ ! 652: REGISTER_CURL_CONSTANT(CURLOPT_TCP_NODELAY); ! 653: #endif ! 654: REGISTER_CURL_CONSTANT(CURLOPT_HTTP200ALIASES); ! 655: REGISTER_CURL_CONSTANT(CURL_TIMECOND_IFMODSINCE); ! 656: REGISTER_CURL_CONSTANT(CURL_TIMECOND_IFUNMODSINCE); ! 657: REGISTER_CURL_CONSTANT(CURL_TIMECOND_LASTMOD); ! 658: ! 659: #if LIBCURL_VERSION_NUM > 0x070f04 /* CURLOPT_MAX_RECV_SPEED_LARGE & CURLOPT_MAX_SEND_SPEED_LARGE are available since curl 7.15.5 */ ! 660: REGISTER_CURL_CONSTANT(CURLOPT_MAX_RECV_SPEED_LARGE); ! 661: REGISTER_CURL_CONSTANT(CURLOPT_MAX_SEND_SPEED_LARGE); ! 662: #endif ! 663: ! 664: #if LIBCURL_VERSION_NUM > 0x070a05 /* CURLOPT_HTTPAUTH is available since curl 7.10.6 */ ! 665: REGISTER_CURL_CONSTANT(CURLOPT_HTTPAUTH); ! 666: /* http authentication options */ ! 667: REGISTER_CURL_CONSTANT(CURLAUTH_BASIC); ! 668: REGISTER_CURL_CONSTANT(CURLAUTH_DIGEST); ! 669: REGISTER_CURL_CONSTANT(CURLAUTH_GSSNEGOTIATE); ! 670: REGISTER_CURL_CONSTANT(CURLAUTH_NTLM); ! 671: REGISTER_CURL_CONSTANT(CURLAUTH_ANY); ! 672: REGISTER_CURL_CONSTANT(CURLAUTH_ANYSAFE); ! 673: #endif ! 674: ! 675: #if LIBCURL_VERSION_NUM > 0x070a06 /* CURLOPT_PROXYAUTH & CURLOPT_FTP_CREATE_MISSING_DIRS are available since curl 7.10.7 */ ! 676: REGISTER_CURL_CONSTANT(CURLOPT_PROXYAUTH); ! 677: REGISTER_CURL_CONSTANT(CURLOPT_FTP_CREATE_MISSING_DIRS); ! 678: #endif ! 679: ! 680: REGISTER_CURL_CONSTANT(CURLOPT_PRIVATE); ! 681: ! 682: /* Constants effecting the way CURLOPT_CLOSEPOLICY works */ ! 683: REGISTER_CURL_CONSTANT(CURLCLOSEPOLICY_LEAST_RECENTLY_USED); ! 684: REGISTER_CURL_CONSTANT(CURLCLOSEPOLICY_LEAST_TRAFFIC); ! 685: REGISTER_CURL_CONSTANT(CURLCLOSEPOLICY_SLOWEST); ! 686: REGISTER_CURL_CONSTANT(CURLCLOSEPOLICY_CALLBACK); ! 687: REGISTER_CURL_CONSTANT(CURLCLOSEPOLICY_OLDEST); ! 688: ! 689: /* Info constants */ ! 690: REGISTER_CURL_CONSTANT(CURLINFO_EFFECTIVE_URL); ! 691: REGISTER_CURL_CONSTANT(CURLINFO_HTTP_CODE); ! 692: REGISTER_CURL_CONSTANT(CURLINFO_HEADER_SIZE); ! 693: REGISTER_CURL_CONSTANT(CURLINFO_REQUEST_SIZE); ! 694: REGISTER_CURL_CONSTANT(CURLINFO_TOTAL_TIME); ! 695: REGISTER_CURL_CONSTANT(CURLINFO_NAMELOOKUP_TIME); ! 696: REGISTER_CURL_CONSTANT(CURLINFO_CONNECT_TIME); ! 697: REGISTER_CURL_CONSTANT(CURLINFO_PRETRANSFER_TIME); ! 698: REGISTER_CURL_CONSTANT(CURLINFO_SIZE_UPLOAD); ! 699: REGISTER_CURL_CONSTANT(CURLINFO_SIZE_DOWNLOAD); ! 700: REGISTER_CURL_CONSTANT(CURLINFO_SPEED_DOWNLOAD); ! 701: REGISTER_CURL_CONSTANT(CURLINFO_SPEED_UPLOAD); ! 702: REGISTER_CURL_CONSTANT(CURLINFO_FILETIME); ! 703: REGISTER_CURL_CONSTANT(CURLINFO_SSL_VERIFYRESULT); ! 704: REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_LENGTH_DOWNLOAD); ! 705: REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_LENGTH_UPLOAD); ! 706: REGISTER_CURL_CONSTANT(CURLINFO_STARTTRANSFER_TIME); ! 707: REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_TYPE); ! 708: REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_TIME); ! 709: REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_COUNT); ! 710: REGISTER_CURL_CONSTANT(CURLINFO_HEADER_OUT); ! 711: REGISTER_CURL_CONSTANT(CURLINFO_PRIVATE); ! 712: #if LIBCURL_VERSION_NUM > 0x071301 ! 713: REGISTER_CURL_CONSTANT(CURLINFO_CERTINFO); ! 714: #endif ! 715: #if LIBCURL_VERSION_NUM >= 0x071202 ! 716: REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_URL); ! 717: #endif ! 718: ! 719: ! 720: /* cURL protocol constants (curl_version) */ ! 721: REGISTER_CURL_CONSTANT(CURL_VERSION_IPV6); ! 722: REGISTER_CURL_CONSTANT(CURL_VERSION_KERBEROS4); ! 723: REGISTER_CURL_CONSTANT(CURL_VERSION_SSL); ! 724: REGISTER_CURL_CONSTANT(CURL_VERSION_LIBZ); ! 725: ! 726: /* version constants */ ! 727: REGISTER_CURL_CONSTANT(CURLVERSION_NOW); ! 728: ! 729: /* Error Constants */ ! 730: REGISTER_CURL_CONSTANT(CURLE_OK); ! 731: REGISTER_CURL_CONSTANT(CURLE_UNSUPPORTED_PROTOCOL); ! 732: REGISTER_CURL_CONSTANT(CURLE_FAILED_INIT); ! 733: REGISTER_CURL_CONSTANT(CURLE_URL_MALFORMAT); ! 734: REGISTER_CURL_CONSTANT(CURLE_URL_MALFORMAT_USER); ! 735: REGISTER_CURL_CONSTANT(CURLE_COULDNT_RESOLVE_PROXY); ! 736: REGISTER_CURL_CONSTANT(CURLE_COULDNT_RESOLVE_HOST); ! 737: REGISTER_CURL_CONSTANT(CURLE_COULDNT_CONNECT); ! 738: REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_SERVER_REPLY); ! 739: REGISTER_CURL_CONSTANT(CURLE_FTP_ACCESS_DENIED); ! 740: REGISTER_CURL_CONSTANT(CURLE_FTP_USER_PASSWORD_INCORRECT); ! 741: REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_PASS_REPLY); ! 742: REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_USER_REPLY); ! 743: REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_PASV_REPLY); ! 744: REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_227_FORMAT); ! 745: REGISTER_CURL_CONSTANT(CURLE_FTP_CANT_GET_HOST); ! 746: REGISTER_CURL_CONSTANT(CURLE_FTP_CANT_RECONNECT); ! 747: REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_SET_BINARY); ! 748: REGISTER_CURL_CONSTANT(CURLE_PARTIAL_FILE); ! 749: REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_RETR_FILE); ! 750: REGISTER_CURL_CONSTANT(CURLE_FTP_WRITE_ERROR); ! 751: REGISTER_CURL_CONSTANT(CURLE_FTP_QUOTE_ERROR); ! 752: REGISTER_CURL_CONSTANT(CURLE_HTTP_NOT_FOUND); ! 753: REGISTER_CURL_CONSTANT(CURLE_WRITE_ERROR); ! 754: REGISTER_CURL_CONSTANT(CURLE_MALFORMAT_USER); ! 755: REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_STOR_FILE); ! 756: REGISTER_CURL_CONSTANT(CURLE_READ_ERROR); ! 757: REGISTER_CURL_CONSTANT(CURLE_OUT_OF_MEMORY); ! 758: REGISTER_CURL_CONSTANT(CURLE_OPERATION_TIMEOUTED); ! 759: REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_SET_ASCII); ! 760: REGISTER_CURL_CONSTANT(CURLE_FTP_PORT_FAILED); ! 761: REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_USE_REST); ! 762: REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_GET_SIZE); ! 763: REGISTER_CURL_CONSTANT(CURLE_HTTP_RANGE_ERROR); ! 764: REGISTER_CURL_CONSTANT(CURLE_HTTP_POST_ERROR); ! 765: REGISTER_CURL_CONSTANT(CURLE_SSL_CONNECT_ERROR); ! 766: REGISTER_CURL_CONSTANT(CURLE_FTP_BAD_DOWNLOAD_RESUME); ! 767: REGISTER_CURL_CONSTANT(CURLE_FILE_COULDNT_READ_FILE); ! 768: REGISTER_CURL_CONSTANT(CURLE_LDAP_CANNOT_BIND); ! 769: REGISTER_CURL_CONSTANT(CURLE_LDAP_SEARCH_FAILED); ! 770: REGISTER_CURL_CONSTANT(CURLE_LIBRARY_NOT_FOUND); ! 771: REGISTER_CURL_CONSTANT(CURLE_FUNCTION_NOT_FOUND); ! 772: REGISTER_CURL_CONSTANT(CURLE_ABORTED_BY_CALLBACK); ! 773: REGISTER_CURL_CONSTANT(CURLE_BAD_FUNCTION_ARGUMENT); ! 774: REGISTER_CURL_CONSTANT(CURLE_BAD_CALLING_ORDER); ! 775: REGISTER_CURL_CONSTANT(CURLE_HTTP_PORT_FAILED); ! 776: REGISTER_CURL_CONSTANT(CURLE_BAD_PASSWORD_ENTERED); ! 777: REGISTER_CURL_CONSTANT(CURLE_TOO_MANY_REDIRECTS); ! 778: REGISTER_CURL_CONSTANT(CURLE_UNKNOWN_TELNET_OPTION); ! 779: REGISTER_CURL_CONSTANT(CURLE_TELNET_OPTION_SYNTAX); ! 780: REGISTER_CURL_CONSTANT(CURLE_OBSOLETE); ! 781: REGISTER_CURL_CONSTANT(CURLE_SSL_PEER_CERTIFICATE); ! 782: REGISTER_CURL_CONSTANT(CURLE_GOT_NOTHING); ! 783: REGISTER_CURL_CONSTANT(CURLE_SSL_ENGINE_NOTFOUND); ! 784: REGISTER_CURL_CONSTANT(CURLE_SSL_ENGINE_SETFAILED); ! 785: REGISTER_CURL_CONSTANT(CURLE_SEND_ERROR); ! 786: REGISTER_CURL_CONSTANT(CURLE_RECV_ERROR); ! 787: REGISTER_CURL_CONSTANT(CURLE_SHARE_IN_USE); ! 788: REGISTER_CURL_CONSTANT(CURLE_SSL_CERTPROBLEM); ! 789: REGISTER_CURL_CONSTANT(CURLE_SSL_CIPHER); ! 790: REGISTER_CURL_CONSTANT(CURLE_SSL_CACERT); ! 791: REGISTER_CURL_CONSTANT(CURLE_BAD_CONTENT_ENCODING); ! 792: #if LIBCURL_VERSION_NUM >= 0x070a08 ! 793: REGISTER_CURL_CONSTANT(CURLE_LDAP_INVALID_URL); ! 794: REGISTER_CURL_CONSTANT(CURLE_FILESIZE_EXCEEDED); ! 795: #endif ! 796: #if LIBCURL_VERSION_NUM >= 0x070b00 ! 797: REGISTER_CURL_CONSTANT(CURLE_FTP_SSL_FAILED); ! 798: #endif ! 799: REGISTER_CURL_CONSTANT(CURLPROXY_HTTP); ! 800: REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS4); ! 801: REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS5); ! 802: ! 803: REGISTER_CURL_CONSTANT(CURL_NETRC_OPTIONAL); ! 804: REGISTER_CURL_CONSTANT(CURL_NETRC_IGNORED); ! 805: REGISTER_CURL_CONSTANT(CURL_NETRC_REQUIRED); ! 806: ! 807: REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_NONE); ! 808: REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_1_0); ! 809: REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_1_1); ! 810: ! 811: REGISTER_CURL_CONSTANT(CURLM_CALL_MULTI_PERFORM); ! 812: REGISTER_CURL_CONSTANT(CURLM_OK); ! 813: REGISTER_CURL_CONSTANT(CURLM_BAD_HANDLE); ! 814: REGISTER_CURL_CONSTANT(CURLM_BAD_EASY_HANDLE); ! 815: REGISTER_CURL_CONSTANT(CURLM_OUT_OF_MEMORY); ! 816: REGISTER_CURL_CONSTANT(CURLM_INTERNAL_ERROR); ! 817: ! 818: REGISTER_CURL_CONSTANT(CURLMSG_DONE); ! 819: ! 820: #if LIBCURL_VERSION_NUM >= 0x070c02 ! 821: REGISTER_CURL_CONSTANT(CURLOPT_FTPSSLAUTH); ! 822: REGISTER_CURL_CONSTANT(CURLFTPAUTH_DEFAULT); ! 823: REGISTER_CURL_CONSTANT(CURLFTPAUTH_SSL); ! 824: REGISTER_CURL_CONSTANT(CURLFTPAUTH_TLS); ! 825: #endif ! 826: ! 827: #if LIBCURL_VERSION_NUM > 0x070b00 ! 828: REGISTER_CURL_CONSTANT(CURLOPT_FTP_SSL); ! 829: REGISTER_CURL_CONSTANT(CURLFTPSSL_NONE); ! 830: REGISTER_CURL_CONSTANT(CURLFTPSSL_TRY); ! 831: REGISTER_CURL_CONSTANT(CURLFTPSSL_CONTROL); ! 832: REGISTER_CURL_CONSTANT(CURLFTPSSL_ALL); ! 833: #endif ! 834: ! 835: #if LIBCURL_VERSION_NUM > 0x071301 ! 836: REGISTER_CURL_CONSTANT(CURLOPT_CERTINFO); ! 837: REGISTER_CURL_CONSTANT(CURLOPT_POSTREDIR); ! 838: #endif ! 839: ! 840: /* SSH support works in 7.19.0+ using libssh2 */ ! 841: #if LIBCURL_VERSION_NUM >= 0x071300 ! 842: REGISTER_CURL_CONSTANT(CURLSSH_AUTH_NONE); ! 843: REGISTER_CURL_CONSTANT(CURLSSH_AUTH_PUBLICKEY); ! 844: REGISTER_CURL_CONSTANT(CURLSSH_AUTH_PASSWORD); ! 845: REGISTER_CURL_CONSTANT(CURLSSH_AUTH_HOST); ! 846: REGISTER_CURL_CONSTANT(CURLSSH_AUTH_KEYBOARD); ! 847: REGISTER_CURL_CONSTANT(CURLSSH_AUTH_DEFAULT); ! 848: REGISTER_CURL_CONSTANT(CURLOPT_SSH_AUTH_TYPES); ! 849: REGISTER_CURL_CONSTANT(CURLOPT_KEYPASSWD); ! 850: REGISTER_CURL_CONSTANT(CURLOPT_SSH_PUBLIC_KEYFILE); ! 851: REGISTER_CURL_CONSTANT(CURLOPT_SSH_PRIVATE_KEYFILE); ! 852: REGISTER_CURL_CONSTANT(CURLOPT_SSH_HOST_PUBLIC_KEY_MD5); ! 853: REGISTER_CURL_CONSTANT(CURLE_SSH); ! 854: #endif ! 855: ! 856: #if LIBCURL_VERSION_NUM >= 0x071304 ! 857: REGISTER_CURL_CONSTANT(CURLOPT_REDIR_PROTOCOLS); ! 858: REGISTER_CURL_CONSTANT(CURLOPT_PROTOCOLS); ! 859: REGISTER_CURL_CONSTANT(CURLPROTO_HTTP); ! 860: REGISTER_CURL_CONSTANT(CURLPROTO_HTTPS); ! 861: REGISTER_CURL_CONSTANT(CURLPROTO_FTP); ! 862: REGISTER_CURL_CONSTANT(CURLPROTO_FTPS); ! 863: REGISTER_CURL_CONSTANT(CURLPROTO_SCP); ! 864: REGISTER_CURL_CONSTANT(CURLPROTO_SFTP); ! 865: REGISTER_CURL_CONSTANT(CURLPROTO_TELNET); ! 866: REGISTER_CURL_CONSTANT(CURLPROTO_LDAP); ! 867: REGISTER_CURL_CONSTANT(CURLPROTO_LDAPS); ! 868: REGISTER_CURL_CONSTANT(CURLPROTO_DICT); ! 869: REGISTER_CURL_CONSTANT(CURLPROTO_FILE); ! 870: REGISTER_CURL_CONSTANT(CURLPROTO_TFTP); ! 871: REGISTER_CURL_CONSTANT(CURLPROTO_ALL); ! 872: #endif ! 873: ! 874: #if LIBCURL_VERSION_NUM >= 0x070f01 ! 875: REGISTER_CURL_CONSTANT(CURLOPT_FTP_FILEMETHOD); ! 876: REGISTER_CURL_CONSTANT(CURLOPT_FTP_SKIP_PASV_IP); ! 877: #endif ! 878: ! 879: #if LIBCURL_VERSION_NUM >= 0x071001 ! 880: REGISTER_CURL_CONSTANT(CURLFTPMETHOD_MULTICWD); ! 881: REGISTER_CURL_CONSTANT(CURLFTPMETHOD_NOCWD); ! 882: REGISTER_CURL_CONSTANT(CURLFTPMETHOD_SINGLECWD); ! 883: #endif ! 884: ! 885: #ifdef PHP_CURL_NEED_OPENSSL_TSL ! 886: if (!CRYPTO_get_id_callback()) { ! 887: int i, c = CRYPTO_num_locks(); ! 888: ! 889: php_curl_openssl_tsl = malloc(c * sizeof(MUTEX_T)); ! 890: if (!php_curl_openssl_tsl) { ! 891: return FAILURE; ! 892: } ! 893: ! 894: for (i = 0; i < c; ++i) { ! 895: php_curl_openssl_tsl[i] = tsrm_mutex_alloc(); ! 896: } ! 897: ! 898: CRYPTO_set_id_callback(php_curl_ssl_id); ! 899: CRYPTO_set_locking_callback(php_curl_ssl_lock); ! 900: } ! 901: #endif ! 902: #ifdef PHP_CURL_NEED_GNUTLS_TSL ! 903: gcry_control(GCRYCTL_SET_THREAD_CBS, &php_curl_gnutls_tsl); ! 904: #endif ! 905: ! 906: if (curl_global_init(CURL_GLOBAL_SSL) != CURLE_OK) { ! 907: return FAILURE; ! 908: } ! 909: ! 910: #ifdef PHP_CURL_URL_WRAPPERS ! 911: # if HAVE_CURL_VERSION_INFO ! 912: { ! 913: curl_version_info_data *info = curl_version_info(CURLVERSION_NOW); ! 914: char **p = (char **)info->protocols; ! 915: ! 916: while (*p != NULL) { ! 917: /* Do not enable cURL "file" protocol and make sure cURL is always used when --with-curlwrappers is enabled */ ! 918: if (strncasecmp(*p, "file", sizeof("file")-1) != 0) { ! 919: php_unregister_url_stream_wrapper(*p TSRMLS_CC); ! 920: php_register_url_stream_wrapper(*p, &php_curl_wrapper TSRMLS_CC); ! 921: } ! 922: (void) *p++; ! 923: } ! 924: } ! 925: # else ! 926: php_unregister_url_stream_wrapper("http"); ! 927: php_register_url_stream_wrapper("http", &php_curl_wrapper TSRMLS_CC); ! 928: php_unregister_url_stream_wrapper("https"); ! 929: php_register_url_stream_wrapper("https", &php_curl_wrapper TSRMLS_CC); ! 930: php_unregister_url_stream_wrapper("ftp"); ! 931: php_register_url_stream_wrapper("ftp", &php_curl_wrapper TSRMLS_CC); ! 932: php_unregister_url_stream_wrapper("ftps"); ! 933: php_register_url_stream_wrapper("ftps", &php_curl_wrapper TSRMLS_CC); ! 934: php_unregister_url_stream_wrapper("ldap"); ! 935: php_register_url_stream_wrapper("ldap", &php_curl_wrapper TSRMLS_CC); ! 936: # endif ! 937: #endif ! 938: ! 939: return SUCCESS; ! 940: } ! 941: /* }}} */ ! 942: ! 943: /* {{{ PHP_MSHUTDOWN_FUNCTION ! 944: */ ! 945: PHP_MSHUTDOWN_FUNCTION(curl) ! 946: { ! 947: #ifdef PHP_CURL_URL_WRAPPERS ! 948: php_unregister_url_stream_wrapper("http" TSRMLS_CC); ! 949: php_unregister_url_stream_wrapper("https" TSRMLS_CC); ! 950: php_unregister_url_stream_wrapper("ftp" TSRMLS_CC); ! 951: php_unregister_url_stream_wrapper("ldap" TSRMLS_CC); ! 952: #endif ! 953: curl_global_cleanup(); ! 954: #ifdef PHP_CURL_NEED_OPENSSL_TSL ! 955: if (php_curl_openssl_tsl) { ! 956: int i, c = CRYPTO_num_locks(); ! 957: ! 958: CRYPTO_set_id_callback(NULL); ! 959: CRYPTO_set_locking_callback(NULL); ! 960: ! 961: for (i = 0; i < c; ++i) { ! 962: tsrm_mutex_free(php_curl_openssl_tsl[i]); ! 963: } ! 964: ! 965: free(php_curl_openssl_tsl); ! 966: php_curl_openssl_tsl = NULL; ! 967: } ! 968: #endif ! 969: UNREGISTER_INI_ENTRIES(); ! 970: return SUCCESS; ! 971: } ! 972: /* }}} */ ! 973: ! 974: /* {{{ curl_write ! 975: */ ! 976: static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx) ! 977: { ! 978: php_curl *ch = (php_curl *) ctx; ! 979: php_curl_write *t = ch->handlers->write; ! 980: size_t length = size * nmemb; ! 981: TSRMLS_FETCH_FROM_CTX(ch->thread_ctx); ! 982: ! 983: #if PHP_CURL_DEBUG ! 984: fprintf(stderr, "curl_write() called\n"); ! 985: fprintf(stderr, "data = %s, size = %d, nmemb = %d, ctx = %x\n", data, size, nmemb, ctx); ! 986: #endif ! 987: ! 988: switch (t->method) { ! 989: case PHP_CURL_STDOUT: ! 990: PHPWRITE(data, length); ! 991: break; ! 992: case PHP_CURL_FILE: ! 993: return fwrite(data, size, nmemb, t->fp); ! 994: case PHP_CURL_RETURN: ! 995: if (length > 0) { ! 996: smart_str_appendl(&t->buf, data, (int) length); ! 997: } ! 998: break; ! 999: case PHP_CURL_USER: { ! 1000: zval **argv[2]; ! 1001: zval *retval_ptr = NULL; ! 1002: zval *handle = NULL; ! 1003: zval *zdata = NULL; ! 1004: int error; ! 1005: zend_fcall_info fci; ! 1006: ! 1007: MAKE_STD_ZVAL(handle); ! 1008: ZVAL_RESOURCE(handle, ch->id); ! 1009: zend_list_addref(ch->id); ! 1010: argv[0] = &handle; ! 1011: ! 1012: MAKE_STD_ZVAL(zdata); ! 1013: ZVAL_STRINGL(zdata, data, length, 1); ! 1014: argv[1] = &zdata; ! 1015: ! 1016: fci.size = sizeof(fci); ! 1017: fci.function_table = EG(function_table); ! 1018: fci.object_ptr = NULL; ! 1019: fci.function_name = t->func_name; ! 1020: fci.retval_ptr_ptr = &retval_ptr; ! 1021: fci.param_count = 2; ! 1022: fci.params = argv; ! 1023: fci.no_separation = 0; ! 1024: fci.symbol_table = NULL; ! 1025: ! 1026: ch->in_callback = 1; ! 1027: error = zend_call_function(&fci, &t->fci_cache TSRMLS_CC); ! 1028: ch->in_callback = 0; ! 1029: if (error == FAILURE) { ! 1030: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the CURLOPT_WRITEFUNCTION"); ! 1031: length = -1; ! 1032: } else if (retval_ptr) { ! 1033: if (Z_TYPE_P(retval_ptr) != IS_LONG) { ! 1034: convert_to_long_ex(&retval_ptr); ! 1035: } ! 1036: length = Z_LVAL_P(retval_ptr); ! 1037: zval_ptr_dtor(&retval_ptr); ! 1038: } ! 1039: ! 1040: zval_ptr_dtor(argv[0]); ! 1041: zval_ptr_dtor(argv[1]); ! 1042: break; ! 1043: } ! 1044: } ! 1045: ! 1046: return length; ! 1047: } ! 1048: /* }}} */ ! 1049: ! 1050: /* {{{ curl_progress ! 1051: */ ! 1052: static size_t curl_progress(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) ! 1053: { ! 1054: php_curl *ch = (php_curl *) clientp; ! 1055: php_curl_progress *t = ch->handlers->progress; ! 1056: int length = -1; ! 1057: size_t rval = 0; ! 1058: ! 1059: #if PHP_CURL_DEBUG ! 1060: fprintf(stderr, "curl_progress() called\n"); ! 1061: fprintf(stderr, "clientp = %x, dltotal = %f, dlnow = %f, ultotal = %f, ulnow = %f\n", clientp, dltotal, dlnow, ultotal, ulnow); ! 1062: #endif ! 1063: ! 1064: switch (t->method) { ! 1065: case PHP_CURL_USER: { ! 1066: zval **argv[4]; ! 1067: zval *zdltotal = NULL; ! 1068: zval *zdlnow = NULL; ! 1069: zval *zultotal = NULL; ! 1070: zval *zulnow = NULL; ! 1071: zval *retval_ptr; ! 1072: int error; ! 1073: zend_fcall_info fci; ! 1074: TSRMLS_FETCH_FROM_CTX(ch->thread_ctx); ! 1075: ! 1076: MAKE_STD_ZVAL(zdltotal); ! 1077: MAKE_STD_ZVAL(zdlnow); ! 1078: MAKE_STD_ZVAL(zultotal); ! 1079: MAKE_STD_ZVAL(zulnow); ! 1080: ! 1081: ZVAL_LONG(zdltotal, (long) dltotal); ! 1082: ZVAL_LONG(zdlnow, (long) dlnow); ! 1083: ZVAL_LONG(zultotal, (long) ultotal); ! 1084: ZVAL_LONG(zulnow, (long) ulnow); ! 1085: ! 1086: argv[0] = &zdltotal; ! 1087: argv[1] = &zdlnow; ! 1088: argv[2] = &zultotal; ! 1089: argv[3] = &zulnow; ! 1090: ! 1091: fci.size = sizeof(fci); ! 1092: fci.function_table = EG(function_table); ! 1093: fci.function_name = t->func_name; ! 1094: fci.object_ptr = NULL; ! 1095: fci.retval_ptr_ptr = &retval_ptr; ! 1096: fci.param_count = 4; ! 1097: fci.params = argv; ! 1098: fci.no_separation = 0; ! 1099: fci.symbol_table = NULL; ! 1100: ! 1101: ch->in_callback = 1; ! 1102: error = zend_call_function(&fci, &t->fci_cache TSRMLS_CC); ! 1103: ch->in_callback = 0; ! 1104: if (error == FAILURE) { ! 1105: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot call the CURLOPT_PROGRESSFUNCTION"); ! 1106: length = -1; ! 1107: } else if (retval_ptr) { ! 1108: if (Z_TYPE_P(retval_ptr) != IS_LONG) { ! 1109: convert_to_long_ex(&retval_ptr); ! 1110: } ! 1111: if (0 != Z_LVAL_P(retval_ptr)) { ! 1112: rval = 1; ! 1113: } ! 1114: zval_ptr_dtor(&retval_ptr); ! 1115: } ! 1116: zval_ptr_dtor(argv[0]); ! 1117: zval_ptr_dtor(argv[1]); ! 1118: zval_ptr_dtor(argv[2]); ! 1119: zval_ptr_dtor(argv[3]); ! 1120: break; ! 1121: } ! 1122: } ! 1123: return rval; ! 1124: } ! 1125: /* }}} */ ! 1126: ! 1127: /* {{{ curl_read ! 1128: */ ! 1129: static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx) ! 1130: { ! 1131: php_curl *ch = (php_curl *) ctx; ! 1132: php_curl_read *t = ch->handlers->read; ! 1133: int length = 0; ! 1134: ! 1135: switch (t->method) { ! 1136: case PHP_CURL_DIRECT: ! 1137: if (t->fp) { ! 1138: length = fread(data, size, nmemb, t->fp); ! 1139: } ! 1140: break; ! 1141: case PHP_CURL_USER: { ! 1142: zval **argv[3]; ! 1143: zval *handle = NULL; ! 1144: zval *zfd = NULL; ! 1145: zval *zlength = NULL; ! 1146: zval *retval_ptr; ! 1147: int error; ! 1148: zend_fcall_info fci; ! 1149: TSRMLS_FETCH_FROM_CTX(ch->thread_ctx); ! 1150: ! 1151: MAKE_STD_ZVAL(handle); ! 1152: MAKE_STD_ZVAL(zfd); ! 1153: MAKE_STD_ZVAL(zlength); ! 1154: ! 1155: ZVAL_RESOURCE(handle, ch->id); ! 1156: zend_list_addref(ch->id); ! 1157: ZVAL_RESOURCE(zfd, t->fd); ! 1158: zend_list_addref(t->fd); ! 1159: ZVAL_LONG(zlength, (int) size * nmemb); ! 1160: ! 1161: argv[0] = &handle; ! 1162: argv[1] = &zfd; ! 1163: argv[2] = &zlength; ! 1164: ! 1165: fci.size = sizeof(fci); ! 1166: fci.function_table = EG(function_table); ! 1167: fci.function_name = t->func_name; ! 1168: fci.object_ptr = NULL; ! 1169: fci.retval_ptr_ptr = &retval_ptr; ! 1170: fci.param_count = 3; ! 1171: fci.params = argv; ! 1172: fci.no_separation = 0; ! 1173: fci.symbol_table = NULL; ! 1174: ! 1175: ch->in_callback = 1; ! 1176: error = zend_call_function(&fci, &t->fci_cache TSRMLS_CC); ! 1177: ch->in_callback = 0; ! 1178: if (error == FAILURE) { ! 1179: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot call the CURLOPT_READFUNCTION"); ! 1180: #if LIBCURL_VERSION_NUM >= 0x070c01 /* 7.12.1 */ ! 1181: length = CURL_READFUNC_ABORT; ! 1182: #endif ! 1183: } else if (retval_ptr) { ! 1184: if (Z_TYPE_P(retval_ptr) == IS_STRING) { ! 1185: length = MIN((int) (size * nmemb), Z_STRLEN_P(retval_ptr)); ! 1186: memcpy(data, Z_STRVAL_P(retval_ptr), length); ! 1187: } ! 1188: zval_ptr_dtor(&retval_ptr); ! 1189: } ! 1190: ! 1191: zval_ptr_dtor(argv[0]); ! 1192: zval_ptr_dtor(argv[1]); ! 1193: zval_ptr_dtor(argv[2]); ! 1194: break; ! 1195: } ! 1196: } ! 1197: ! 1198: return length; ! 1199: } ! 1200: /* }}} */ ! 1201: ! 1202: /* {{{ curl_write_header ! 1203: */ ! 1204: static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx) ! 1205: { ! 1206: php_curl *ch = (php_curl *) ctx; ! 1207: php_curl_write *t = ch->handlers->write_header; ! 1208: size_t length = size * nmemb; ! 1209: TSRMLS_FETCH_FROM_CTX(ch->thread_ctx); ! 1210: ! 1211: switch (t->method) { ! 1212: case PHP_CURL_STDOUT: ! 1213: /* Handle special case write when we're returning the entire transfer ! 1214: */ ! 1215: if (ch->handlers->write->method == PHP_CURL_RETURN && length > 0) { ! 1216: smart_str_appendl(&ch->handlers->write->buf, data, (int) length); ! 1217: } else { ! 1218: PHPWRITE(data, length); ! 1219: } ! 1220: break; ! 1221: case PHP_CURL_FILE: ! 1222: return fwrite(data, size, nmemb, t->fp); ! 1223: case PHP_CURL_USER: { ! 1224: zval **argv[2]; ! 1225: zval *handle = NULL; ! 1226: zval *zdata = NULL; ! 1227: zval *retval_ptr; ! 1228: int error; ! 1229: zend_fcall_info fci; ! 1230: ! 1231: MAKE_STD_ZVAL(handle); ! 1232: MAKE_STD_ZVAL(zdata); ! 1233: ! 1234: ZVAL_RESOURCE(handle, ch->id); ! 1235: zend_list_addref(ch->id); ! 1236: ZVAL_STRINGL(zdata, data, length, 1); ! 1237: ! 1238: argv[0] = &handle; ! 1239: argv[1] = &zdata; ! 1240: ! 1241: fci.size = sizeof(fci); ! 1242: fci.function_table = EG(function_table); ! 1243: fci.function_name = t->func_name; ! 1244: fci.symbol_table = NULL; ! 1245: fci.object_ptr = NULL; ! 1246: fci.retval_ptr_ptr = &retval_ptr; ! 1247: fci.param_count = 2; ! 1248: fci.params = argv; ! 1249: fci.no_separation = 0; ! 1250: ! 1251: ch->in_callback = 1; ! 1252: error = zend_call_function(&fci, &t->fci_cache TSRMLS_CC); ! 1253: ch->in_callback = 0; ! 1254: if (error == FAILURE) { ! 1255: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the CURLOPT_HEADERFUNCTION"); ! 1256: length = -1; ! 1257: } else if (retval_ptr) { ! 1258: if (Z_TYPE_P(retval_ptr) != IS_LONG) { ! 1259: convert_to_long_ex(&retval_ptr); ! 1260: } ! 1261: length = Z_LVAL_P(retval_ptr); ! 1262: zval_ptr_dtor(&retval_ptr); ! 1263: } ! 1264: zval_ptr_dtor(argv[0]); ! 1265: zval_ptr_dtor(argv[1]); ! 1266: break; ! 1267: } ! 1268: ! 1269: case PHP_CURL_IGNORE: ! 1270: return length; ! 1271: ! 1272: default: ! 1273: return -1; ! 1274: } ! 1275: ! 1276: return length; ! 1277: } ! 1278: /* }}} */ ! 1279: ! 1280: static int curl_debug(CURL *cp, curl_infotype type, char *buf, size_t buf_len, void *ctx) /* {{{ */ ! 1281: { ! 1282: php_curl *ch = (php_curl *) ctx; ! 1283: ! 1284: if (type == CURLINFO_HEADER_OUT) { ! 1285: if (ch->header.str_len) { ! 1286: efree(ch->header.str); ! 1287: } ! 1288: if (buf_len > 0) { ! 1289: ch->header.str = estrndup(buf, buf_len); ! 1290: ch->header.str_len = buf_len; ! 1291: } ! 1292: } ! 1293: ! 1294: return 0; ! 1295: } ! 1296: /* }}} */ ! 1297: ! 1298: #if CURLOPT_PASSWDFUNCTION != 0 ! 1299: /* {{{ curl_passwd ! 1300: */ ! 1301: static size_t curl_passwd(void *ctx, char *prompt, char *buf, int buflen) ! 1302: { ! 1303: php_curl *ch = (php_curl *) ctx; ! 1304: zval *func = ch->handlers->passwd; ! 1305: zval *argv[3]; ! 1306: zval *retval = NULL; ! 1307: int error; ! 1308: int ret = -1; ! 1309: TSRMLS_FETCH_FROM_CTX(ch->thread_ctx); ! 1310: ! 1311: MAKE_STD_ZVAL(argv[0]); ! 1312: MAKE_STD_ZVAL(argv[1]); ! 1313: MAKE_STD_ZVAL(argv[2]); ! 1314: ! 1315: ZVAL_RESOURCE(argv[0], ch->id); ! 1316: zend_list_addref(ch->id); ! 1317: ZVAL_STRING(argv[1], prompt, 1); ! 1318: ZVAL_LONG(argv[2], buflen); ! 1319: ! 1320: error = call_user_function(EG(function_table), NULL, func, retval, 2, argv TSRMLS_CC); ! 1321: if (error == FAILURE) { ! 1322: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the CURLOPT_PASSWDFUNCTION"); ! 1323: } else if (Z_TYPE_P(retval) == IS_STRING) { ! 1324: if (Z_STRLEN_P(retval) > buflen) { ! 1325: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Returned password is too long for libcurl to handle"); ! 1326: } else { ! 1327: strlcpy(buf, Z_STRVAL_P(retval), Z_STRLEN_P(retval)); ! 1328: } ! 1329: } else { ! 1330: php_error_docref(NULL TSRMLS_CC, E_WARNING, "User handler '%s' did not return a string", Z_STRVAL_P(func)); ! 1331: } ! 1332: ! 1333: zval_ptr_dtor(&argv[0]); ! 1334: zval_ptr_dtor(&argv[1]); ! 1335: zval_ptr_dtor(&argv[2]); ! 1336: zval_ptr_dtor(&retval); ! 1337: ! 1338: return ret; ! 1339: } ! 1340: /* }}} */ ! 1341: #endif ! 1342: ! 1343: /* {{{ curl_free_string ! 1344: */ ! 1345: static void curl_free_string(void **string) ! 1346: { ! 1347: efree(*string); ! 1348: } ! 1349: /* }}} */ ! 1350: ! 1351: /* {{{ curl_free_post ! 1352: */ ! 1353: static void curl_free_post(void **post) ! 1354: { ! 1355: curl_formfree((struct HttpPost *) *post); ! 1356: } ! 1357: /* }}} */ ! 1358: ! 1359: /* {{{ curl_free_slist ! 1360: */ ! 1361: static void curl_free_slist(void **slist) ! 1362: { ! 1363: curl_slist_free_all((struct curl_slist *) *slist); ! 1364: } ! 1365: /* }}} */ ! 1366: ! 1367: /* {{{ proto array curl_version([int version]) ! 1368: Return cURL version information. */ ! 1369: PHP_FUNCTION(curl_version) ! 1370: { ! 1371: curl_version_info_data *d; ! 1372: long uversion = CURLVERSION_NOW; ! 1373: ! 1374: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &uversion) == FAILURE) { ! 1375: return; ! 1376: } ! 1377: ! 1378: d = curl_version_info(uversion); ! 1379: if (d == NULL) { ! 1380: RETURN_FALSE; ! 1381: } ! 1382: ! 1383: array_init(return_value); ! 1384: ! 1385: CAAL("version_number", d->version_num); ! 1386: CAAL("age", d->age); ! 1387: CAAL("features", d->features); ! 1388: CAAL("ssl_version_number", d->ssl_version_num); ! 1389: CAAS("version", d->version); ! 1390: CAAS("host", d->host); ! 1391: CAAS("ssl_version", d->ssl_version); ! 1392: CAAS("libz_version", d->libz_version); ! 1393: /* Add an array of protocols */ ! 1394: { ! 1395: char **p = (char **) d->protocols; ! 1396: zval *protocol_list = NULL; ! 1397: ! 1398: MAKE_STD_ZVAL(protocol_list); ! 1399: array_init(protocol_list); ! 1400: ! 1401: while (*p != NULL) { ! 1402: add_next_index_string(protocol_list, *p, 1); ! 1403: p++; ! 1404: } ! 1405: CAAZ("protocols", protocol_list); ! 1406: } ! 1407: } ! 1408: /* }}} */ ! 1409: ! 1410: /* {{{ alloc_curl_handle ! 1411: */ ! 1412: static void alloc_curl_handle(php_curl **ch) ! 1413: { ! 1414: *ch = emalloc(sizeof(php_curl)); ! 1415: (*ch)->to_free = ecalloc(1, sizeof(struct _php_curl_free)); ! 1416: (*ch)->handlers = ecalloc(1, sizeof(php_curl_handlers)); ! 1417: (*ch)->handlers->write = ecalloc(1, sizeof(php_curl_write)); ! 1418: (*ch)->handlers->write_header = ecalloc(1, sizeof(php_curl_write)); ! 1419: (*ch)->handlers->read = ecalloc(1, sizeof(php_curl_read)); ! 1420: (*ch)->handlers->progress = ecalloc(1, sizeof(php_curl_progress)); ! 1421: ! 1422: (*ch)->in_callback = 0; ! 1423: (*ch)->header.str_len = 0; ! 1424: ! 1425: memset(&(*ch)->err, 0, sizeof((*ch)->err)); ! 1426: (*ch)->handlers->write->stream = NULL; ! 1427: (*ch)->handlers->write_header->stream = NULL; ! 1428: (*ch)->handlers->read->stream = NULL; ! 1429: ! 1430: zend_llist_init(&(*ch)->to_free->str, sizeof(char *), (llist_dtor_func_t) curl_free_string, 0); ! 1431: zend_llist_init(&(*ch)->to_free->slist, sizeof(struct curl_slist), (llist_dtor_func_t) curl_free_slist, 0); ! 1432: zend_llist_init(&(*ch)->to_free->post, sizeof(struct HttpPost), (llist_dtor_func_t) curl_free_post, 0); ! 1433: } ! 1434: /* }}} */ ! 1435: ! 1436: #if LIBCURL_VERSION_NUM > 0x071301 ! 1437: /* {{{ split_certinfo ! 1438: */ ! 1439: static void split_certinfo(char *string, zval *hash) ! 1440: { ! 1441: char *org = estrdup(string); ! 1442: char *s = org; ! 1443: char *split; ! 1444: ! 1445: if(org) { ! 1446: do { ! 1447: char *key; ! 1448: char *val; ! 1449: char *tmp; ! 1450: ! 1451: split = strstr(s, "; "); ! 1452: if(split) ! 1453: *split = '\0'; ! 1454: ! 1455: key = s; ! 1456: tmp = memchr(key, '=', 64); ! 1457: if(tmp) { ! 1458: *tmp = '\0'; ! 1459: val = tmp+1; ! 1460: add_assoc_string(hash, key, val, 1); ! 1461: } ! 1462: s = split+2; ! 1463: } while(split); ! 1464: efree(org); ! 1465: } ! 1466: } ! 1467: /* }}} */ ! 1468: ! 1469: /* {{{ create_certinfo ! 1470: */ ! 1471: static void create_certinfo(struct curl_certinfo *ci, zval *listcode TSRMLS_DC) ! 1472: { ! 1473: int i; ! 1474: ! 1475: if(ci) { ! 1476: zval *certhash = NULL; ! 1477: ! 1478: for(i=0; i<ci->num_of_certs; i++) { ! 1479: struct curl_slist *slist; ! 1480: ! 1481: MAKE_STD_ZVAL(certhash); ! 1482: array_init(certhash); ! 1483: for(slist = ci->certinfo[i]; slist; slist = slist->next) { ! 1484: int len; ! 1485: char s[64]; ! 1486: char *tmp; ! 1487: strncpy(s, slist->data, 64); ! 1488: tmp = memchr(s, ':', 64); ! 1489: if(tmp) { ! 1490: *tmp = '\0'; ! 1491: len = strlen(s); ! 1492: if(!strcmp(s, "Subject") || !strcmp(s, "Issuer")) { ! 1493: zval *hash; ! 1494: ! 1495: MAKE_STD_ZVAL(hash); ! 1496: array_init(hash); ! 1497: ! 1498: split_certinfo(&slist->data[len+1], hash); ! 1499: add_assoc_zval(certhash, s, hash); ! 1500: } else { ! 1501: add_assoc_string(certhash, s, &slist->data[len+1], 1); ! 1502: } ! 1503: } else { ! 1504: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not extract hash key from certificate info"); ! 1505: } ! 1506: } ! 1507: add_next_index_zval(listcode, certhash); ! 1508: } ! 1509: } ! 1510: } ! 1511: /* }}} */ ! 1512: #endif ! 1513: ! 1514: /* {{{ proto resource curl_init([string url]) ! 1515: Initialize a cURL session */ ! 1516: PHP_FUNCTION(curl_init) ! 1517: { ! 1518: php_curl *ch; ! 1519: CURL *cp; ! 1520: zval *clone; ! 1521: char *url = NULL; ! 1522: int url_len = 0; ! 1523: char *cainfo; ! 1524: ! 1525: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &url, &url_len) == FAILURE) { ! 1526: return; ! 1527: } ! 1528: ! 1529: cp = curl_easy_init(); ! 1530: if (!cp) { ! 1531: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not initialize a new cURL handle"); ! 1532: RETURN_FALSE; ! 1533: } ! 1534: ! 1535: alloc_curl_handle(&ch); ! 1536: TSRMLS_SET_CTX(ch->thread_ctx); ! 1537: ! 1538: ch->cp = cp; ! 1539: ! 1540: ch->handlers->write->method = PHP_CURL_STDOUT; ! 1541: ch->handlers->write->type = PHP_CURL_ASCII; ! 1542: ch->handlers->read->method = PHP_CURL_DIRECT; ! 1543: ch->handlers->write_header->method = PHP_CURL_IGNORE; ! 1544: ! 1545: ch->uses = 0; ! 1546: ! 1547: MAKE_STD_ZVAL(clone); ! 1548: ch->clone = clone; ! 1549: ! 1550: ! 1551: ! 1552: curl_easy_setopt(ch->cp, CURLOPT_NOPROGRESS, 1); ! 1553: curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 0); ! 1554: curl_easy_setopt(ch->cp, CURLOPT_ERRORBUFFER, ch->err.str); ! 1555: curl_easy_setopt(ch->cp, CURLOPT_WRITEFUNCTION, curl_write); ! 1556: curl_easy_setopt(ch->cp, CURLOPT_FILE, (void *) ch); ! 1557: curl_easy_setopt(ch->cp, CURLOPT_READFUNCTION, curl_read); ! 1558: curl_easy_setopt(ch->cp, CURLOPT_INFILE, (void *) ch); ! 1559: curl_easy_setopt(ch->cp, CURLOPT_HEADERFUNCTION, curl_write_header); ! 1560: curl_easy_setopt(ch->cp, CURLOPT_WRITEHEADER, (void *) ch); ! 1561: curl_easy_setopt(ch->cp, CURLOPT_DNS_USE_GLOBAL_CACHE, 1); ! 1562: curl_easy_setopt(ch->cp, CURLOPT_DNS_CACHE_TIMEOUT, 120); ! 1563: curl_easy_setopt(ch->cp, CURLOPT_MAXREDIRS, 20); /* prevent infinite redirects */ ! 1564: ! 1565: cainfo = INI_STR("curl.cainfo"); ! 1566: if (cainfo && strlen(cainfo) > 0) { ! 1567: curl_easy_setopt(ch->cp, CURLOPT_CAINFO, cainfo); ! 1568: } ! 1569: ! 1570: #if defined(ZTS) ! 1571: curl_easy_setopt(ch->cp, CURLOPT_NOSIGNAL, 1); ! 1572: #endif ! 1573: ! 1574: if (url) { ! 1575: if (!php_curl_option_url(ch, url, url_len)) { ! 1576: _php_curl_close_ex(ch TSRMLS_CC); ! 1577: RETURN_FALSE; ! 1578: } ! 1579: } ! 1580: ! 1581: ZEND_REGISTER_RESOURCE(return_value, ch, le_curl); ! 1582: ch->id = Z_LVAL_P(return_value); ! 1583: } ! 1584: /* }}} */ ! 1585: ! 1586: /* {{{ proto resource curl_copy_handle(resource ch) ! 1587: Copy a cURL handle along with all of it's preferences */ ! 1588: PHP_FUNCTION(curl_copy_handle) ! 1589: { ! 1590: CURL *cp; ! 1591: zval *zid; ! 1592: php_curl *ch, *dupch; ! 1593: ! 1594: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zid) == FAILURE) { ! 1595: return; ! 1596: } ! 1597: ! 1598: ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl); ! 1599: ! 1600: cp = curl_easy_duphandle(ch->cp); ! 1601: if (!cp) { ! 1602: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot duplicate cURL handle"); ! 1603: RETURN_FALSE; ! 1604: } ! 1605: ! 1606: alloc_curl_handle(&dupch); ! 1607: TSRMLS_SET_CTX(dupch->thread_ctx); ! 1608: ! 1609: dupch->cp = cp; ! 1610: dupch->uses = 0; ! 1611: ch->uses++; ! 1612: if (ch->handlers->write->stream) { ! 1613: Z_ADDREF_P(dupch->handlers->write->stream); ! 1614: dupch->handlers->write->stream = ch->handlers->write->stream; ! 1615: } ! 1616: dupch->handlers->write->method = ch->handlers->write->method; ! 1617: dupch->handlers->write->type = ch->handlers->write->type; ! 1618: if (ch->handlers->read->stream) { ! 1619: Z_ADDREF_P(ch->handlers->read->stream); ! 1620: } ! 1621: dupch->handlers->read->stream = ch->handlers->read->stream; ! 1622: dupch->handlers->read->method = ch->handlers->read->method; ! 1623: dupch->handlers->write_header->method = ch->handlers->write_header->method; ! 1624: if (ch->handlers->write_header->stream) { ! 1625: Z_ADDREF_P(ch->handlers->write_header->stream); ! 1626: } ! 1627: dupch->handlers->write_header->stream = ch->handlers->write_header->stream; ! 1628: ! 1629: dupch->handlers->write->fp = ch->handlers->write->fp; ! 1630: dupch->handlers->write_header->fp = ch->handlers->write_header->fp; ! 1631: dupch->handlers->read->fp = ch->handlers->read->fp; ! 1632: dupch->handlers->read->fd = ch->handlers->read->fd; ! 1633: #if CURLOPT_PASSWDDATA != 0 ! 1634: if (ch->handlers->passwd) { ! 1635: zval_add_ref(&ch->handlers->passwd); ! 1636: dupch->handlers->passwd = ch->handlers->passwd; ! 1637: curl_easy_setopt(ch->cp, CURLOPT_PASSWDDATA, (void *) dupch); ! 1638: } ! 1639: #endif ! 1640: if (ch->handlers->write->func_name) { ! 1641: zval_add_ref(&ch->handlers->write->func_name); ! 1642: dupch->handlers->write->func_name = ch->handlers->write->func_name; ! 1643: } ! 1644: if (ch->handlers->read->func_name) { ! 1645: zval_add_ref(&ch->handlers->read->func_name); ! 1646: dupch->handlers->read->func_name = ch->handlers->read->func_name; ! 1647: } ! 1648: if (ch->handlers->write_header->func_name) { ! 1649: zval_add_ref(&ch->handlers->write_header->func_name); ! 1650: dupch->handlers->write_header->func_name = ch->handlers->write_header->func_name; ! 1651: } ! 1652: ! 1653: if (ch->handlers->progress->func_name) { ! 1654: zval_add_ref(&ch->handlers->progress->func_name); ! 1655: dupch->handlers->progress->func_name = ch->handlers->progress->func_name; ! 1656: } ! 1657: dupch->handlers->progress->method = ch->handlers->progress->method; ! 1658: ! 1659: curl_easy_setopt(dupch->cp, CURLOPT_ERRORBUFFER, dupch->err.str); ! 1660: curl_easy_setopt(dupch->cp, CURLOPT_FILE, (void *) dupch); ! 1661: curl_easy_setopt(dupch->cp, CURLOPT_INFILE, (void *) dupch); ! 1662: curl_easy_setopt(dupch->cp, CURLOPT_WRITEHEADER, (void *) dupch); ! 1663: curl_easy_setopt(dupch->cp, CURLOPT_PROGRESSDATA, (void *) dupch); ! 1664: ! 1665: efree(dupch->to_free); ! 1666: dupch->to_free = ch->to_free; ! 1667: ! 1668: /* Keep track of cloned copies to avoid invoking curl destructors for every clone */ ! 1669: Z_ADDREF_P(ch->clone); ! 1670: dupch->clone = ch->clone; ! 1671: ! 1672: ZEND_REGISTER_RESOURCE(return_value, dupch, le_curl); ! 1673: dupch->id = Z_LVAL_P(return_value); ! 1674: } ! 1675: /* }}} */ ! 1676: ! 1677: static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *return_value TSRMLS_DC) /* {{{ */ ! 1678: { ! 1679: CURLcode error=CURLE_OK; ! 1680: ! 1681: switch (option) { ! 1682: case CURLOPT_INFILESIZE: ! 1683: case CURLOPT_VERBOSE: ! 1684: case CURLOPT_HEADER: ! 1685: case CURLOPT_NOPROGRESS: ! 1686: case CURLOPT_NOBODY: ! 1687: case CURLOPT_FAILONERROR: ! 1688: case CURLOPT_UPLOAD: ! 1689: case CURLOPT_POST: ! 1690: case CURLOPT_FTPLISTONLY: ! 1691: case CURLOPT_FTPAPPEND: ! 1692: case CURLOPT_NETRC: ! 1693: case CURLOPT_PUT: ! 1694: #if CURLOPT_MUTE != 0 ! 1695: case CURLOPT_MUTE: ! 1696: #endif ! 1697: case CURLOPT_TIMEOUT: ! 1698: #if LIBCURL_VERSION_NUM > 0x071002 ! 1699: case CURLOPT_TIMEOUT_MS: ! 1700: #endif ! 1701: case CURLOPT_FTP_USE_EPSV: ! 1702: case CURLOPT_LOW_SPEED_LIMIT: ! 1703: case CURLOPT_SSLVERSION: ! 1704: case CURLOPT_LOW_SPEED_TIME: ! 1705: case CURLOPT_RESUME_FROM: ! 1706: case CURLOPT_TIMEVALUE: ! 1707: case CURLOPT_TIMECONDITION: ! 1708: case CURLOPT_TRANSFERTEXT: ! 1709: case CURLOPT_HTTPPROXYTUNNEL: ! 1710: case CURLOPT_FILETIME: ! 1711: case CURLOPT_MAXREDIRS: ! 1712: case CURLOPT_MAXCONNECTS: ! 1713: case CURLOPT_CLOSEPOLICY: ! 1714: case CURLOPT_FRESH_CONNECT: ! 1715: case CURLOPT_FORBID_REUSE: ! 1716: case CURLOPT_CONNECTTIMEOUT: ! 1717: #if LIBCURL_VERSION_NUM > 0x071002 ! 1718: case CURLOPT_CONNECTTIMEOUT_MS: ! 1719: #endif ! 1720: case CURLOPT_SSL_VERIFYHOST: ! 1721: case CURLOPT_SSL_VERIFYPEER: ! 1722: case CURLOPT_DNS_USE_GLOBAL_CACHE: ! 1723: case CURLOPT_NOSIGNAL: ! 1724: case CURLOPT_PROXYTYPE: ! 1725: case CURLOPT_BUFFERSIZE: ! 1726: case CURLOPT_HTTPGET: ! 1727: case CURLOPT_HTTP_VERSION: ! 1728: case CURLOPT_CRLF: ! 1729: case CURLOPT_DNS_CACHE_TIMEOUT: ! 1730: case CURLOPT_PROXYPORT: ! 1731: case CURLOPT_FTP_USE_EPRT: ! 1732: #if LIBCURL_VERSION_NUM > 0x070a05 /* CURLOPT_HTTPAUTH is available since curl 7.10.6 */ ! 1733: case CURLOPT_HTTPAUTH: ! 1734: #endif ! 1735: #if LIBCURL_VERSION_NUM > 0x070a06 /* CURLOPT_PROXYAUTH & CURLOPT_FTP_CREATE_MISSING_DIRS are available since curl 7.10.7 */ ! 1736: case CURLOPT_PROXYAUTH: ! 1737: case CURLOPT_FTP_CREATE_MISSING_DIRS: ! 1738: #endif ! 1739: ! 1740: #if LIBCURL_VERSION_NUM >= 0x070c02 ! 1741: case CURLOPT_FTPSSLAUTH: ! 1742: #endif ! 1743: #if LIBCURL_VERSION_NUM > 0x070b00 ! 1744: case CURLOPT_FTP_SSL: ! 1745: #endif ! 1746: case CURLOPT_UNRESTRICTED_AUTH: ! 1747: case CURLOPT_PORT: ! 1748: case CURLOPT_AUTOREFERER: ! 1749: case CURLOPT_COOKIESESSION: ! 1750: #if LIBCURL_VERSION_NUM > 0x070b01 /* CURLOPT_TCP_NODELAY is available since curl 7.11.2 */ ! 1751: case CURLOPT_TCP_NODELAY: ! 1752: #endif ! 1753: #if LIBCURL_VERSION_NUM >= 0x71304 ! 1754: case CURLOPT_REDIR_PROTOCOLS: ! 1755: case CURLOPT_PROTOCOLS: ! 1756: #endif ! 1757: #if LIBCURL_VERSION_NUM > 0x070a07 /* CURLOPT_IPRESOLVE is available since curl 7.10.8 */ ! 1758: case CURLOPT_IPRESOLVE: ! 1759: #endif ! 1760: #if LIBCURL_VERSION_NUM >= 0x070f01 ! 1761: case CURLOPT_FTP_FILEMETHOD: ! 1762: case CURLOPT_FTP_SKIP_PASV_IP: ! 1763: #endif ! 1764: #if LIBCURL_VERSION_NUM > 0x071301 ! 1765: case CURLOPT_CERTINFO: ! 1766: #endif ! 1767: convert_to_long_ex(zvalue); ! 1768: #if LIBCURL_VERSION_NUM >= 0x71304 ! 1769: if ((option == CURLOPT_PROTOCOLS || option == CURLOPT_REDIR_PROTOCOLS) && ! 1770: ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) && (Z_LVAL_PP(zvalue) & CURLPROTO_FILE)) { ! 1771: php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLPROTO_FILE cannot be activated when in safe_mode or an open_basedir is set"); ! 1772: RETVAL_FALSE; ! 1773: return 1; ! 1774: } ! 1775: #endif ! 1776: error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); ! 1777: break; ! 1778: #if LIBCURL_VERSION_NUM > 0x070f04 ! 1779: case CURLOPT_MAX_RECV_SPEED_LARGE: ! 1780: case CURLOPT_MAX_SEND_SPEED_LARGE: ! 1781: convert_to_long_ex(zvalue); ! 1782: error = curl_easy_setopt(ch->cp, option, (curl_off_t)Z_LVAL_PP(zvalue)); ! 1783: break; ! 1784: #endif ! 1785: case CURLOPT_FOLLOWLOCATION: ! 1786: convert_to_long_ex(zvalue); ! 1787: if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) { ! 1788: if (Z_LVAL_PP(zvalue) != 0) { ! 1789: php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_FOLLOWLOCATION cannot be activated when safe_mode is enabled or an open_basedir is set"); ! 1790: RETVAL_FALSE; ! 1791: return 1; ! 1792: } ! 1793: } ! 1794: error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); ! 1795: break; ! 1796: #if LIBCURL_VERSION_NUM > 0x071301 ! 1797: case CURLOPT_POSTREDIR: ! 1798: convert_to_long_ex(zvalue); ! 1799: error = curl_easy_setopt(ch->cp, CURLOPT_POSTREDIR, Z_LVAL_PP(zvalue) & CURL_REDIR_POST_ALL); ! 1800: break; ! 1801: #endif ! 1802: case CURLOPT_PRIVATE: ! 1803: case CURLOPT_URL: ! 1804: case CURLOPT_PROXY: ! 1805: case CURLOPT_USERPWD: ! 1806: case CURLOPT_PROXYUSERPWD: ! 1807: case CURLOPT_RANGE: ! 1808: case CURLOPT_CUSTOMREQUEST: ! 1809: case CURLOPT_USERAGENT: ! 1810: case CURLOPT_FTPPORT: ! 1811: case CURLOPT_COOKIE: ! 1812: case CURLOPT_REFERER: ! 1813: case CURLOPT_INTERFACE: ! 1814: case CURLOPT_KRB4LEVEL: ! 1815: case CURLOPT_EGDSOCKET: ! 1816: case CURLOPT_CAINFO: ! 1817: case CURLOPT_CAPATH: ! 1818: case CURLOPT_SSL_CIPHER_LIST: ! 1819: case CURLOPT_SSLKEY: ! 1820: case CURLOPT_SSLKEYTYPE: ! 1821: case CURLOPT_SSLKEYPASSWD: ! 1822: case CURLOPT_SSLENGINE: ! 1823: case CURLOPT_SSLENGINE_DEFAULT: ! 1824: case CURLOPT_SSLCERTTYPE: ! 1825: case CURLOPT_ENCODING: ! 1826: #if LIBCURL_VERSION_NUM >= 0x071300 ! 1827: case CURLOPT_SSH_PUBLIC_KEYFILE: ! 1828: case CURLOPT_SSH_PRIVATE_KEYFILE: ! 1829: #endif ! 1830: { ! 1831: #if LIBCURL_VERSION_NUM < 0x071100 ! 1832: char *copystr = NULL; ! 1833: #endif ! 1834: ! 1835: convert_to_string_ex(zvalue); ! 1836: #if LIBCURL_VERSION_NUM >= 0x071300 ! 1837: if ( ! 1838: option == CURLOPT_SSH_PUBLIC_KEYFILE || option == CURLOPT_SSH_PRIVATE_KEYFILE ! 1839: ! 1840: ) { ! 1841: if (php_check_open_basedir(Z_STRVAL_PP(zvalue) TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(zvalue), "rb+", CHECKUID_CHECK_MODE_PARAM))) { ! 1842: RETVAL_FALSE; ! 1843: return 1; ! 1844: } ! 1845: } ! 1846: #endif ! 1847: if (option == CURLOPT_URL) { ! 1848: if (!php_curl_option_url(ch, Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue))) { ! 1849: RETVAL_FALSE; ! 1850: return 1; ! 1851: } ! 1852: } else { ! 1853: if (option == CURLOPT_PRIVATE) { ! 1854: char *copystr; ! 1855: #if LIBCURL_VERSION_NUM < 0x071100 ! 1856: string_copy: ! 1857: #endif ! 1858: copystr = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue)); ! 1859: error = curl_easy_setopt(ch->cp, option, copystr); ! 1860: zend_llist_add_element(&ch->to_free->str, ©str); ! 1861: } else { ! 1862: #if LIBCURL_VERSION_NUM >= 0x071100 ! 1863: /* Strings passed to libcurl as ’char *’ arguments, are copied by the library... NOTE: before 7.17.0 strings were not copied. */ ! 1864: error = curl_easy_setopt(ch->cp, option, Z_STRVAL_PP(zvalue)); ! 1865: #else ! 1866: goto string_copy; ! 1867: #endif ! 1868: } ! 1869: } ! 1870: break; ! 1871: } ! 1872: case CURLOPT_FILE: ! 1873: case CURLOPT_INFILE: ! 1874: case CURLOPT_WRITEHEADER: ! 1875: case CURLOPT_STDERR: { ! 1876: FILE *fp = NULL; ! 1877: int type; ! 1878: void * what; ! 1879: ! 1880: what = zend_fetch_resource(zvalue TSRMLS_CC, -1, "File-Handle", &type, 1, php_file_le_stream(), php_file_le_pstream()); ! 1881: if (!what) { ! 1882: RETVAL_FALSE; ! 1883: return 1; ! 1884: } ! 1885: ! 1886: if (FAILURE == php_stream_cast((php_stream *) what, PHP_STREAM_AS_STDIO, (void *) &fp, REPORT_ERRORS)) { ! 1887: RETVAL_FALSE; ! 1888: return 1; ! 1889: } ! 1890: ! 1891: if (!fp) { ! 1892: RETVAL_FALSE; ! 1893: return 1; ! 1894: } ! 1895: ! 1896: error = CURLE_OK; ! 1897: switch (option) { ! 1898: case CURLOPT_FILE: ! 1899: if (((php_stream *) what)->mode[0] != 'r' || ((php_stream *) what)->mode[1] == '+') { ! 1900: if (ch->handlers->write->stream) { ! 1901: Z_DELREF_P(ch->handlers->write->stream); ! 1902: } ! 1903: Z_ADDREF_PP(zvalue); ! 1904: ch->handlers->write->fp = fp; ! 1905: ch->handlers->write->method = PHP_CURL_FILE; ! 1906: ch->handlers->write->stream = *zvalue; ! 1907: } else { ! 1908: php_error_docref(NULL TSRMLS_CC, E_WARNING, "the provided file handle is not writable"); ! 1909: RETVAL_FALSE; ! 1910: return 1; ! 1911: } ! 1912: break; ! 1913: case CURLOPT_WRITEHEADER: ! 1914: if (((php_stream *) what)->mode[0] != 'r' || ((php_stream *) what)->mode[1] == '+') { ! 1915: if (ch->handlers->write_header->stream) { ! 1916: Z_DELREF_P(ch->handlers->write_header->stream); ! 1917: } ! 1918: Z_ADDREF_PP(zvalue); ! 1919: ch->handlers->write_header->fp = fp; ! 1920: ch->handlers->write_header->method = PHP_CURL_FILE; ! 1921: ch->handlers->write_header->stream = *zvalue; ! 1922: } else { ! 1923: php_error_docref(NULL TSRMLS_CC, E_WARNING, "the provided file handle is not writable"); ! 1924: RETVAL_FALSE; ! 1925: return 1; ! 1926: } ! 1927: break; ! 1928: case CURLOPT_INFILE: ! 1929: if (ch->handlers->read->stream) { ! 1930: Z_DELREF_P(ch->handlers->read->stream); ! 1931: } ! 1932: Z_ADDREF_PP(zvalue); ! 1933: ch->handlers->read->fp = fp; ! 1934: ch->handlers->read->fd = Z_LVAL_PP(zvalue); ! 1935: ch->handlers->read->stream = *zvalue; ! 1936: break; ! 1937: case CURLOPT_STDERR: ! 1938: if (((php_stream *) what)->mode[0] != 'r' || ((php_stream *) what)->mode[1] == '+') { ! 1939: if (ch->handlers->std_err) { ! 1940: zval_ptr_dtor(&ch->handlers->std_err); ! 1941: } ! 1942: zval_add_ref(zvalue); ! 1943: ch->handlers->std_err = *zvalue; ! 1944: } else { ! 1945: php_error_docref(NULL TSRMLS_CC, E_WARNING, "the provided file handle is not writable"); ! 1946: RETVAL_FALSE; ! 1947: return 1; ! 1948: } ! 1949: /* break omitted intentionally */ ! 1950: default: ! 1951: error = curl_easy_setopt(ch->cp, option, fp); ! 1952: break; ! 1953: } ! 1954: ! 1955: break; ! 1956: } ! 1957: case CURLOPT_RETURNTRANSFER: ! 1958: convert_to_long_ex(zvalue); ! 1959: ! 1960: if (Z_LVAL_PP(zvalue)) { ! 1961: ch->handlers->write->method = PHP_CURL_RETURN; ! 1962: } else { ! 1963: ch->handlers->write->method = PHP_CURL_STDOUT; ! 1964: } ! 1965: break; ! 1966: case CURLOPT_BINARYTRANSFER: ! 1967: convert_to_long_ex(zvalue); ! 1968: ! 1969: if (Z_LVAL_PP(zvalue)) { ! 1970: ch->handlers->write->type = PHP_CURL_BINARY; ! 1971: } else { ! 1972: ch->handlers->write->type = PHP_CURL_ASCII; ! 1973: } ! 1974: break; ! 1975: case CURLOPT_WRITEFUNCTION: ! 1976: if (ch->handlers->write->func_name) { ! 1977: zval_ptr_dtor(&ch->handlers->write->func_name); ! 1978: ch->handlers->write->fci_cache = empty_fcall_info_cache; ! 1979: } ! 1980: zval_add_ref(zvalue); ! 1981: ch->handlers->write->func_name = *zvalue; ! 1982: ch->handlers->write->method = PHP_CURL_USER; ! 1983: break; ! 1984: case CURLOPT_READFUNCTION: ! 1985: if (ch->handlers->read->func_name) { ! 1986: zval_ptr_dtor(&ch->handlers->read->func_name); ! 1987: ch->handlers->read->fci_cache = empty_fcall_info_cache; ! 1988: } ! 1989: zval_add_ref(zvalue); ! 1990: ch->handlers->read->func_name = *zvalue; ! 1991: ch->handlers->read->method = PHP_CURL_USER; ! 1992: break; ! 1993: case CURLOPT_PROGRESSFUNCTION: ! 1994: curl_easy_setopt(ch->cp, CURLOPT_PROGRESSFUNCTION, curl_progress); ! 1995: curl_easy_setopt(ch->cp, CURLOPT_PROGRESSDATA, ch); ! 1996: if (ch->handlers->progress->func_name) { ! 1997: zval_ptr_dtor(&ch->handlers->progress->func_name); ! 1998: ch->handlers->progress->fci_cache = empty_fcall_info_cache; ! 1999: } ! 2000: zval_add_ref(zvalue); ! 2001: ch->handlers->progress->func_name = *zvalue; ! 2002: ch->handlers->progress->method = PHP_CURL_USER; ! 2003: break; ! 2004: case CURLOPT_HEADERFUNCTION: ! 2005: if (ch->handlers->write_header->func_name) { ! 2006: zval_ptr_dtor(&ch->handlers->write_header->func_name); ! 2007: ch->handlers->write_header->fci_cache = empty_fcall_info_cache; ! 2008: } ! 2009: zval_add_ref(zvalue); ! 2010: ch->handlers->write_header->func_name = *zvalue; ! 2011: ch->handlers->write_header->method = PHP_CURL_USER; ! 2012: break; ! 2013: #if CURLOPT_PASSWDFUNCTION != 0 ! 2014: case CURLOPT_PASSWDFUNCTION: ! 2015: if (ch->handlers->passwd) { ! 2016: zval_ptr_dtor(&ch->handlers->passwd); ! 2017: } ! 2018: zval_add_ref(zvalue); ! 2019: ch->handlers->passwd = *zvalue; ! 2020: error = curl_easy_setopt(ch->cp, CURLOPT_PASSWDFUNCTION, curl_passwd); ! 2021: error = curl_easy_setopt(ch->cp, CURLOPT_PASSWDDATA, (void *) ch); ! 2022: break; ! 2023: #endif ! 2024: case CURLOPT_POSTFIELDS: ! 2025: if (Z_TYPE_PP(zvalue) == IS_ARRAY || Z_TYPE_PP(zvalue) == IS_OBJECT) { ! 2026: zval **current; ! 2027: HashTable *postfields; ! 2028: struct HttpPost *first = NULL; ! 2029: struct HttpPost *last = NULL; ! 2030: char *postval; ! 2031: char *string_key = NULL; ! 2032: ulong num_key; ! 2033: uint string_key_len; ! 2034: ! 2035: postfields = HASH_OF(*zvalue); ! 2036: if (!postfields) { ! 2037: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't get HashTable in CURLOPT_POSTFIELDS"); ! 2038: RETVAL_FALSE; ! 2039: return 1; ! 2040: } ! 2041: ! 2042: for (zend_hash_internal_pointer_reset(postfields); ! 2043: zend_hash_get_current_data(postfields, (void **) ¤t) == SUCCESS; ! 2044: zend_hash_move_forward(postfields) ! 2045: ) { ! 2046: ! 2047: SEPARATE_ZVAL(current); ! 2048: convert_to_string_ex(current); ! 2049: ! 2050: zend_hash_get_current_key_ex(postfields, &string_key, &string_key_len, &num_key, 0, NULL); ! 2051: ! 2052: postval = Z_STRVAL_PP(current); ! 2053: ! 2054: /* The arguments after _NAMELENGTH and _CONTENTSLENGTH ! 2055: * must be explicitly cast to long in curl_formadd ! 2056: * use since curl needs a long not an int. */ ! 2057: if (*postval == '@') { ! 2058: char *type, *filename; ! 2059: ++postval; ! 2060: ! 2061: if ((type = php_memnstr(postval, ";type=", sizeof(";type=") - 1, postval + Z_STRLEN_PP(current)))) { ! 2062: *type = '\0'; ! 2063: } ! 2064: if ((filename = php_memnstr(postval, ";filename=", sizeof(";filename=") - 1, postval + Z_STRLEN_PP(current)))) { ! 2065: *filename = '\0'; ! 2066: } ! 2067: /* safe_mode / open_basedir check */ ! 2068: if (php_check_open_basedir(postval TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(postval, "rb+", CHECKUID_CHECK_MODE_PARAM))) { ! 2069: RETVAL_FALSE; ! 2070: return 1; ! 2071: } ! 2072: error = curl_formadd(&first, &last, ! 2073: CURLFORM_COPYNAME, string_key, ! 2074: CURLFORM_NAMELENGTH, (long)string_key_len - 1, ! 2075: CURLFORM_FILENAME, filename ? filename + sizeof(";filename=") - 1 : postval, ! 2076: CURLFORM_CONTENTTYPE, type ? type + sizeof(";type=") - 1 : "application/octet-stream", ! 2077: CURLFORM_FILE, postval, ! 2078: CURLFORM_END); ! 2079: if (type) { ! 2080: *type = ';'; ! 2081: } ! 2082: if (filename) { ! 2083: *filename = ';'; ! 2084: } ! 2085: } else { ! 2086: error = curl_formadd(&first, &last, ! 2087: CURLFORM_COPYNAME, string_key, ! 2088: CURLFORM_NAMELENGTH, (long)string_key_len - 1, ! 2089: CURLFORM_COPYCONTENTS, postval, ! 2090: CURLFORM_CONTENTSLENGTH, (long)Z_STRLEN_PP(current), ! 2091: CURLFORM_END); ! 2092: } ! 2093: } ! 2094: ! 2095: SAVE_CURL_ERROR(ch, error); ! 2096: if (error != CURLE_OK) { ! 2097: RETVAL_FALSE; ! 2098: return 1; ! 2099: } ! 2100: ! 2101: zend_llist_add_element(&ch->to_free->post, &first); ! 2102: error = curl_easy_setopt(ch->cp, CURLOPT_HTTPPOST, first); ! 2103: ! 2104: } else { ! 2105: #if LIBCURL_VERSION_NUM >= 0x071101 ! 2106: convert_to_string_ex(zvalue); ! 2107: /* with curl 7.17.0 and later, we can use COPYPOSTFIELDS, but we have to provide size before */ ! 2108: error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, Z_STRLEN_PP(zvalue)); ! 2109: error = curl_easy_setopt(ch->cp, CURLOPT_COPYPOSTFIELDS, Z_STRVAL_PP(zvalue)); ! 2110: #else ! 2111: char *post = NULL; ! 2112: ! 2113: convert_to_string_ex(zvalue); ! 2114: post = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue)); ! 2115: zend_llist_add_element(&ch->to_free->str, &post); ! 2116: ! 2117: error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDS, post); ! 2118: error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, Z_STRLEN_PP(zvalue)); ! 2119: #endif ! 2120: } ! 2121: break; ! 2122: case CURLOPT_HTTPHEADER: ! 2123: case CURLOPT_QUOTE: ! 2124: case CURLOPT_HTTP200ALIASES: ! 2125: case CURLOPT_POSTQUOTE: { ! 2126: zval **current; ! 2127: HashTable *ph; ! 2128: struct curl_slist *slist = NULL; ! 2129: ! 2130: ph = HASH_OF(*zvalue); ! 2131: if (!ph) { ! 2132: php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must pass either an object or an array with the CURLOPT_HTTPHEADER, CURLOPT_QUOTE, CURLOPT_HTTP200ALIASES and CURLOPT_POSTQUOTE arguments"); ! 2133: RETVAL_FALSE; ! 2134: return 1; ! 2135: } ! 2136: ! 2137: for (zend_hash_internal_pointer_reset(ph); ! 2138: zend_hash_get_current_data(ph, (void **) ¤t) == SUCCESS; ! 2139: zend_hash_move_forward(ph) ! 2140: ) { ! 2141: SEPARATE_ZVAL(current); ! 2142: convert_to_string_ex(current); ! 2143: ! 2144: slist = curl_slist_append(slist, Z_STRVAL_PP(current)); ! 2145: if (!slist) { ! 2146: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not build curl_slist"); ! 2147: RETVAL_FALSE; ! 2148: return 1; ! 2149: } ! 2150: } ! 2151: zend_llist_add_element(&ch->to_free->slist, &slist); ! 2152: ! 2153: error = curl_easy_setopt(ch->cp, option, slist); ! 2154: ! 2155: break; ! 2156: } ! 2157: /* the following options deal with files, therefor safe_mode & open_basedir checks ! 2158: * are required. ! 2159: */ ! 2160: case CURLOPT_COOKIEJAR: ! 2161: case CURLOPT_SSLCERT: ! 2162: case CURLOPT_RANDOM_FILE: ! 2163: case CURLOPT_COOKIEFILE: { ! 2164: #if LIBCURL_VERSION_NUM < 0x071100 ! 2165: char *copystr = NULL; ! 2166: #endif ! 2167: ! 2168: convert_to_string_ex(zvalue); ! 2169: ! 2170: if (php_check_open_basedir(Z_STRVAL_PP(zvalue) TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(zvalue), "rb+", CHECKUID_CHECK_MODE_PARAM))) { ! 2171: RETVAL_FALSE; ! 2172: return 1; ! 2173: } ! 2174: ! 2175: #if LIBCURL_VERSION_NUM >= 0x071100 ! 2176: error = curl_easy_setopt(ch->cp, option, Z_STRVAL_PP(zvalue)); ! 2177: #else ! 2178: copystr = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue)); ! 2179: ! 2180: error = curl_easy_setopt(ch->cp, option, copystr); ! 2181: zend_llist_add_element(&ch->to_free->str, ©str); ! 2182: #endif ! 2183: break; ! 2184: } ! 2185: case CURLINFO_HEADER_OUT: ! 2186: convert_to_long_ex(zvalue); ! 2187: if (Z_LVAL_PP(zvalue) == 1) { ! 2188: curl_easy_setopt(ch->cp, CURLOPT_DEBUGFUNCTION, curl_debug); ! 2189: curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA, (void *)ch); ! 2190: curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 1); ! 2191: } else { ! 2192: curl_easy_setopt(ch->cp, CURLOPT_DEBUGFUNCTION, NULL); ! 2193: curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA, NULL); ! 2194: curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 0); ! 2195: } ! 2196: break; ! 2197: } ! 2198: ! 2199: SAVE_CURL_ERROR(ch, error); ! 2200: if (error != CURLE_OK) { ! 2201: return 1; ! 2202: } else { ! 2203: return 0; ! 2204: } ! 2205: } ! 2206: /* }}} */ ! 2207: ! 2208: /* {{{ proto bool curl_setopt(resource ch, int option, mixed value) ! 2209: Set an option for a cURL transfer */ ! 2210: PHP_FUNCTION(curl_setopt) ! 2211: { ! 2212: zval *zid, **zvalue; ! 2213: long options; ! 2214: php_curl *ch; ! 2215: ! 2216: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlZ", &zid, &options, &zvalue) == FAILURE) { ! 2217: return; ! 2218: } ! 2219: ! 2220: ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl); ! 2221: ! 2222: if (options <= 0) { ! 2223: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid curl configuration option"); ! 2224: RETURN_FALSE; ! 2225: } ! 2226: ! 2227: if (!_php_curl_setopt(ch, options, zvalue, return_value TSRMLS_CC)) { ! 2228: RETURN_TRUE; ! 2229: } else { ! 2230: RETURN_FALSE; ! 2231: } ! 2232: } ! 2233: /* }}} */ ! 2234: ! 2235: /* {{{ proto bool curl_setopt_array(resource ch, array options) ! 2236: Set an array of option for a cURL transfer */ ! 2237: PHP_FUNCTION(curl_setopt_array) ! 2238: { ! 2239: zval *zid, *arr, **entry; ! 2240: php_curl *ch; ! 2241: ulong option; ! 2242: HashPosition pos; ! 2243: char *string_key; ! 2244: uint str_key_len; ! 2245: ! 2246: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "za", &zid, &arr) == FAILURE) { ! 2247: return; ! 2248: } ! 2249: ! 2250: ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl); ! 2251: ! 2252: zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos); ! 2253: while (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)&entry, &pos) == SUCCESS) { ! 2254: if (zend_hash_get_current_key_ex(Z_ARRVAL_P(arr), &string_key, &str_key_len, &option, 0, &pos) != HASH_KEY_IS_LONG) { ! 2255: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array keys must be CURLOPT constants or equivalent integer values"); ! 2256: RETURN_FALSE; ! 2257: } ! 2258: if (_php_curl_setopt(ch, (long) option, entry, return_value TSRMLS_CC)) { ! 2259: RETURN_FALSE; ! 2260: } ! 2261: zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos); ! 2262: } ! 2263: RETURN_TRUE; ! 2264: } ! 2265: /* }}} */ ! 2266: ! 2267: /* {{{ _php_curl_cleanup_handle(ch) ! 2268: Cleanup an execution phase */ ! 2269: void _php_curl_cleanup_handle(php_curl *ch) ! 2270: { ! 2271: if (ch->handlers->write->buf.len > 0) { ! 2272: smart_str_free(&ch->handlers->write->buf); ! 2273: } ! 2274: if (ch->header.str_len) { ! 2275: efree(ch->header.str); ! 2276: ch->header.str_len = 0; ! 2277: } ! 2278: ! 2279: memset(ch->err.str, 0, CURL_ERROR_SIZE + 1); ! 2280: ch->err.no = 0; ! 2281: } ! 2282: /* }}} */ ! 2283: ! 2284: /* {{{ proto bool curl_exec(resource ch) ! 2285: Perform a cURL session */ ! 2286: PHP_FUNCTION(curl_exec) ! 2287: { ! 2288: CURLcode error; ! 2289: zval *zid; ! 2290: php_curl *ch; ! 2291: ! 2292: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zid) == FAILURE) { ! 2293: return; ! 2294: } ! 2295: ! 2296: ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl); ! 2297: ! 2298: _php_curl_verify_handlers(ch, 1 TSRMLS_CC); ! 2299: ! 2300: _php_curl_cleanup_handle(ch); ! 2301: ! 2302: error = curl_easy_perform(ch->cp); ! 2303: SAVE_CURL_ERROR(ch, error); ! 2304: /* CURLE_PARTIAL_FILE is returned by HEAD requests */ ! 2305: if (error != CURLE_OK && error != CURLE_PARTIAL_FILE) { ! 2306: if (ch->handlers->write->buf.len > 0) { ! 2307: smart_str_free(&ch->handlers->write->buf); ! 2308: } ! 2309: RETURN_FALSE; ! 2310: } ! 2311: ! 2312: if (ch->handlers->std_err) { ! 2313: php_stream *stream; ! 2314: stream = (php_stream*)zend_fetch_resource(&ch->handlers->std_err TSRMLS_CC, -1, NULL, NULL, 2, php_file_le_stream(), php_file_le_pstream()); ! 2315: if (stream) { ! 2316: php_stream_flush(stream); ! 2317: } ! 2318: } ! 2319: ! 2320: if (ch->handlers->write->method == PHP_CURL_RETURN && ch->handlers->write->buf.len > 0) { ! 2321: smart_str_0(&ch->handlers->write->buf); ! 2322: RETURN_STRINGL(ch->handlers->write->buf.c, ch->handlers->write->buf.len, 1); ! 2323: } ! 2324: ! 2325: /* flush the file handle, so any remaining data is synched to disk */ ! 2326: if (ch->handlers->write->method == PHP_CURL_FILE && ch->handlers->write->fp) { ! 2327: fflush(ch->handlers->write->fp); ! 2328: } ! 2329: if (ch->handlers->write_header->method == PHP_CURL_FILE && ch->handlers->write_header->fp) { ! 2330: fflush(ch->handlers->write_header->fp); ! 2331: } ! 2332: ! 2333: if (ch->handlers->write->method == PHP_CURL_RETURN) { ! 2334: RETURN_EMPTY_STRING(); ! 2335: } else { ! 2336: RETURN_TRUE; ! 2337: } ! 2338: } ! 2339: /* }}} */ ! 2340: ! 2341: /* {{{ proto mixed curl_getinfo(resource ch [, int option]) ! 2342: Get information regarding a specific transfer */ ! 2343: PHP_FUNCTION(curl_getinfo) ! 2344: { ! 2345: zval *zid; ! 2346: php_curl *ch; ! 2347: long option = 0; ! 2348: ! 2349: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &zid, &option) == FAILURE) { ! 2350: return; ! 2351: } ! 2352: ! 2353: ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl); ! 2354: ! 2355: if (ZEND_NUM_ARGS() < 2) { ! 2356: char *s_code; ! 2357: long l_code; ! 2358: double d_code; ! 2359: #if LIBCURL_VERSION_NUM > 0x071301 ! 2360: struct curl_certinfo *ci = NULL; ! 2361: zval *listcode; ! 2362: #endif ! 2363: ! 2364: array_init(return_value); ! 2365: ! 2366: if (curl_easy_getinfo(ch->cp, CURLINFO_EFFECTIVE_URL, &s_code) == CURLE_OK) { ! 2367: CAAS("url", s_code); ! 2368: } ! 2369: if (curl_easy_getinfo(ch->cp, CURLINFO_CONTENT_TYPE, &s_code) == CURLE_OK) { ! 2370: if (s_code != NULL) { ! 2371: CAAS("content_type", s_code); ! 2372: } else { ! 2373: zval *retnull; ! 2374: MAKE_STD_ZVAL(retnull); ! 2375: ZVAL_NULL(retnull); ! 2376: CAAZ("content_type", retnull); ! 2377: } ! 2378: } ! 2379: if (curl_easy_getinfo(ch->cp, CURLINFO_HTTP_CODE, &l_code) == CURLE_OK) { ! 2380: CAAL("http_code", l_code); ! 2381: } ! 2382: if (curl_easy_getinfo(ch->cp, CURLINFO_HEADER_SIZE, &l_code) == CURLE_OK) { ! 2383: CAAL("header_size", l_code); ! 2384: } ! 2385: if (curl_easy_getinfo(ch->cp, CURLINFO_REQUEST_SIZE, &l_code) == CURLE_OK) { ! 2386: CAAL("request_size", l_code); ! 2387: } ! 2388: if (curl_easy_getinfo(ch->cp, CURLINFO_FILETIME, &l_code) == CURLE_OK) { ! 2389: CAAL("filetime", l_code); ! 2390: } ! 2391: if (curl_easy_getinfo(ch->cp, CURLINFO_SSL_VERIFYRESULT, &l_code) == CURLE_OK) { ! 2392: CAAL("ssl_verify_result", l_code); ! 2393: } ! 2394: if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_COUNT, &l_code) == CURLE_OK) { ! 2395: CAAL("redirect_count", l_code); ! 2396: } ! 2397: if (curl_easy_getinfo(ch->cp, CURLINFO_TOTAL_TIME, &d_code) == CURLE_OK) { ! 2398: CAAD("total_time", d_code); ! 2399: } ! 2400: if (curl_easy_getinfo(ch->cp, CURLINFO_NAMELOOKUP_TIME, &d_code) == CURLE_OK) { ! 2401: CAAD("namelookup_time", d_code); ! 2402: } ! 2403: if (curl_easy_getinfo(ch->cp, CURLINFO_CONNECT_TIME, &d_code) == CURLE_OK) { ! 2404: CAAD("connect_time", d_code); ! 2405: } ! 2406: if (curl_easy_getinfo(ch->cp, CURLINFO_PRETRANSFER_TIME, &d_code) == CURLE_OK) { ! 2407: CAAD("pretransfer_time", d_code); ! 2408: } ! 2409: if (curl_easy_getinfo(ch->cp, CURLINFO_SIZE_UPLOAD, &d_code) == CURLE_OK) { ! 2410: CAAD("size_upload", d_code); ! 2411: } ! 2412: if (curl_easy_getinfo(ch->cp, CURLINFO_SIZE_DOWNLOAD, &d_code) == CURLE_OK) { ! 2413: CAAD("size_download", d_code); ! 2414: } ! 2415: if (curl_easy_getinfo(ch->cp, CURLINFO_SPEED_DOWNLOAD, &d_code) == CURLE_OK) { ! 2416: CAAD("speed_download", d_code); ! 2417: } ! 2418: if (curl_easy_getinfo(ch->cp, CURLINFO_SPEED_UPLOAD, &d_code) == CURLE_OK) { ! 2419: CAAD("speed_upload", d_code); ! 2420: } ! 2421: if (curl_easy_getinfo(ch->cp, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d_code) == CURLE_OK) { ! 2422: CAAD("download_content_length", d_code); ! 2423: } ! 2424: if (curl_easy_getinfo(ch->cp, CURLINFO_CONTENT_LENGTH_UPLOAD, &d_code) == CURLE_OK) { ! 2425: CAAD("upload_content_length", d_code); ! 2426: } ! 2427: if (curl_easy_getinfo(ch->cp, CURLINFO_STARTTRANSFER_TIME, &d_code) == CURLE_OK) { ! 2428: CAAD("starttransfer_time", d_code); ! 2429: } ! 2430: if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_TIME, &d_code) == CURLE_OK) { ! 2431: CAAD("redirect_time", d_code); ! 2432: } ! 2433: #if LIBCURL_VERSION_NUM > 0x071301 ! 2434: if (curl_easy_getinfo(ch->cp, CURLINFO_CERTINFO, &ci) == CURLE_OK) { ! 2435: MAKE_STD_ZVAL(listcode); ! 2436: array_init(listcode); ! 2437: create_certinfo(ci, listcode TSRMLS_CC); ! 2438: CAAZ("certinfo", listcode); ! 2439: } ! 2440: #endif ! 2441: #if LIBCURL_VERSION_NUM >= 0x071202 ! 2442: if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_URL, &s_code) == CURLE_OK) { ! 2443: CAAS("redirect_url", s_code); ! 2444: } ! 2445: #endif ! 2446: if (ch->header.str_len > 0) { ! 2447: CAAS("request_header", ch->header.str); ! 2448: } ! 2449: } else { ! 2450: switch (option) { ! 2451: case CURLINFO_PRIVATE: ! 2452: case CURLINFO_EFFECTIVE_URL: ! 2453: case CURLINFO_CONTENT_TYPE: ! 2454: #if LIBCURL_VERSION_NUM >= 0x071202 ! 2455: case CURLINFO_REDIRECT_URL: ! 2456: #endif ! 2457: { ! 2458: char *s_code = NULL; ! 2459: ! 2460: if (curl_easy_getinfo(ch->cp, option, &s_code) == CURLE_OK && s_code) { ! 2461: RETURN_STRING(s_code, 1); ! 2462: } else { ! 2463: RETURN_FALSE; ! 2464: } ! 2465: break; ! 2466: } ! 2467: case CURLINFO_HTTP_CODE: ! 2468: case CURLINFO_HEADER_SIZE: ! 2469: case CURLINFO_REQUEST_SIZE: ! 2470: case CURLINFO_FILETIME: ! 2471: case CURLINFO_SSL_VERIFYRESULT: ! 2472: case CURLINFO_REDIRECT_COUNT: { ! 2473: long code = 0; ! 2474: ! 2475: if (curl_easy_getinfo(ch->cp, option, &code) == CURLE_OK) { ! 2476: RETURN_LONG(code); ! 2477: } else { ! 2478: RETURN_FALSE; ! 2479: } ! 2480: break; ! 2481: } ! 2482: case CURLINFO_TOTAL_TIME: ! 2483: case CURLINFO_NAMELOOKUP_TIME: ! 2484: case CURLINFO_CONNECT_TIME: ! 2485: case CURLINFO_PRETRANSFER_TIME: ! 2486: case CURLINFO_SIZE_UPLOAD: ! 2487: case CURLINFO_SIZE_DOWNLOAD: ! 2488: case CURLINFO_SPEED_DOWNLOAD: ! 2489: case CURLINFO_SPEED_UPLOAD: ! 2490: case CURLINFO_CONTENT_LENGTH_DOWNLOAD: ! 2491: case CURLINFO_CONTENT_LENGTH_UPLOAD: ! 2492: case CURLINFO_STARTTRANSFER_TIME: ! 2493: case CURLINFO_REDIRECT_TIME: { ! 2494: double code = 0.0; ! 2495: ! 2496: if (curl_easy_getinfo(ch->cp, option, &code) == CURLE_OK) { ! 2497: RETURN_DOUBLE(code); ! 2498: } else { ! 2499: RETURN_FALSE; ! 2500: } ! 2501: break; ! 2502: } ! 2503: case CURLINFO_HEADER_OUT: ! 2504: if (ch->header.str_len > 0) { ! 2505: RETURN_STRINGL(ch->header.str, ch->header.str_len, 1); ! 2506: } else { ! 2507: RETURN_FALSE; ! 2508: } ! 2509: #if LIBCURL_VERSION_NUM > 0x071301 ! 2510: case CURLINFO_CERTINFO: { ! 2511: struct curl_certinfo *ci = NULL; ! 2512: ! 2513: array_init(return_value); ! 2514: ! 2515: if (curl_easy_getinfo(ch->cp, CURLINFO_CERTINFO, &ci) == CURLE_OK) { ! 2516: create_certinfo(ci, return_value TSRMLS_CC); ! 2517: } else { ! 2518: RETURN_FALSE; ! 2519: } ! 2520: break; ! 2521: } ! 2522: #endif ! 2523: } ! 2524: } ! 2525: } ! 2526: /* }}} */ ! 2527: ! 2528: /* {{{ proto string curl_error(resource ch) ! 2529: Return a string contain the last error for the current session */ ! 2530: PHP_FUNCTION(curl_error) ! 2531: { ! 2532: zval *zid; ! 2533: php_curl *ch; ! 2534: ! 2535: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zid) == FAILURE) { ! 2536: return; ! 2537: } ! 2538: ! 2539: ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl); ! 2540: ! 2541: ch->err.str[CURL_ERROR_SIZE] = 0; ! 2542: RETURN_STRING(ch->err.str, 1); ! 2543: } ! 2544: /* }}} */ ! 2545: ! 2546: /* {{{ proto int curl_errno(resource ch) ! 2547: Return an integer containing the last error number */ ! 2548: PHP_FUNCTION(curl_errno) ! 2549: { ! 2550: zval *zid; ! 2551: php_curl *ch; ! 2552: ! 2553: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zid) == FAILURE) { ! 2554: return; ! 2555: } ! 2556: ! 2557: ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl); ! 2558: ! 2559: RETURN_LONG(ch->err.no); ! 2560: } ! 2561: /* }}} */ ! 2562: ! 2563: /* {{{ proto void curl_close(resource ch) ! 2564: Close a cURL session */ ! 2565: PHP_FUNCTION(curl_close) ! 2566: { ! 2567: zval *zid; ! 2568: php_curl *ch; ! 2569: ! 2570: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zid) == FAILURE) { ! 2571: return; ! 2572: } ! 2573: ! 2574: ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl); ! 2575: ! 2576: if (ch->in_callback) { ! 2577: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempt to close cURL handle from a callback"); ! 2578: return; ! 2579: } ! 2580: ! 2581: if (ch->uses) { ! 2582: ch->uses--; ! 2583: } else { ! 2584: zend_list_delete(Z_LVAL_P(zid)); ! 2585: } ! 2586: } ! 2587: /* }}} */ ! 2588: ! 2589: /* {{{ _php_curl_close() ! 2590: List destructor for curl handles */ ! 2591: static void _php_curl_close_ex(php_curl *ch TSRMLS_DC) ! 2592: { ! 2593: #if PHP_CURL_DEBUG ! 2594: fprintf(stderr, "DTOR CALLED, ch = %x\n", ch); ! 2595: #endif ! 2596: ! 2597: _php_curl_verify_handlers(ch, 0 TSRMLS_CC); ! 2598: curl_easy_cleanup(ch->cp); ! 2599: ! 2600: /* cURL destructors should be invoked only by last curl handle */ ! 2601: if (Z_REFCOUNT_P(ch->clone) <= 1) { ! 2602: zend_llist_clean(&ch->to_free->str); ! 2603: zend_llist_clean(&ch->to_free->slist); ! 2604: zend_llist_clean(&ch->to_free->post); ! 2605: efree(ch->to_free); ! 2606: FREE_ZVAL(ch->clone); ! 2607: } else { ! 2608: Z_DELREF_P(ch->clone); ! 2609: } ! 2610: ! 2611: if (ch->handlers->write->buf.len > 0) { ! 2612: smart_str_free(&ch->handlers->write->buf); ! 2613: } ! 2614: if (ch->handlers->write->func_name) { ! 2615: zval_ptr_dtor(&ch->handlers->write->func_name); ! 2616: } ! 2617: if (ch->handlers->read->func_name) { ! 2618: zval_ptr_dtor(&ch->handlers->read->func_name); ! 2619: } ! 2620: if (ch->handlers->write_header->func_name) { ! 2621: zval_ptr_dtor(&ch->handlers->write_header->func_name); ! 2622: } ! 2623: if (ch->handlers->progress->func_name) { ! 2624: zval_ptr_dtor(&ch->handlers->progress->func_name); ! 2625: } ! 2626: if (ch->handlers->passwd) { ! 2627: zval_ptr_dtor(&ch->handlers->passwd); ! 2628: } ! 2629: if (ch->handlers->std_err) { ! 2630: zval_ptr_dtor(&ch->handlers->std_err); ! 2631: } ! 2632: if (ch->header.str_len > 0) { ! 2633: efree(ch->header.str); ! 2634: } ! 2635: ! 2636: if (ch->handlers->write_header->stream) { ! 2637: zval_ptr_dtor(&ch->handlers->write_header->stream); ! 2638: } ! 2639: if (ch->handlers->write->stream) { ! 2640: zval_ptr_dtor(&ch->handlers->write->stream); ! 2641: } ! 2642: if (ch->handlers->read->stream) { ! 2643: zval_ptr_dtor(&ch->handlers->read->stream); ! 2644: } ! 2645: ! 2646: efree(ch->handlers->write); ! 2647: efree(ch->handlers->write_header); ! 2648: efree(ch->handlers->read); ! 2649: efree(ch->handlers->progress); ! 2650: efree(ch->handlers); ! 2651: efree(ch); ! 2652: } ! 2653: /* }}} */ ! 2654: ! 2655: /* {{{ _php_curl_close() ! 2656: List destructor for curl handles */ ! 2657: static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC) ! 2658: { ! 2659: php_curl *ch = (php_curl *) rsrc->ptr; ! 2660: _php_curl_close_ex(ch TSRMLS_CC); ! 2661: } ! 2662: /* }}} */ ! 2663: ! 2664: #endif /* HAVE_CURL */ ! 2665: ! 2666: /* ! 2667: * Local variables: ! 2668: * tab-width: 4 ! 2669: * c-basic-offset: 4 ! 2670: * End: ! 2671: * vim600: fdm=marker ! 2672: * vim: noet sw=4 ts=4 ! 2673: */