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