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