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, &copystr);
        !           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, &copystr);
        !          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 **) &current) == 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 **) &current) == 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, &copystr);
        !          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>