Annotation of embedaddon/php/ext/curl/interface.c, revision 1.1
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: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>