Annotation of embedaddon/php/ext/curl/interface.c, revision 1.1.1.5
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
1.1.1.5 ! misho 5: | Copyright (c) 1997-2014 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: size_t rval = 0;
1072:
1073: #if PHP_CURL_DEBUG
1074: fprintf(stderr, "curl_progress() called\n");
1075: fprintf(stderr, "clientp = %x, dltotal = %f, dlnow = %f, ultotal = %f, ulnow = %f\n", clientp, dltotal, dlnow, ultotal, ulnow);
1076: #endif
1077:
1078: switch (t->method) {
1079: case PHP_CURL_USER: {
1080: zval **argv[4];
1081: zval *zdltotal = NULL;
1082: zval *zdlnow = NULL;
1083: zval *zultotal = NULL;
1084: zval *zulnow = NULL;
1085: zval *retval_ptr;
1086: int error;
1087: zend_fcall_info fci;
1088: TSRMLS_FETCH_FROM_CTX(ch->thread_ctx);
1089:
1090: MAKE_STD_ZVAL(zdltotal);
1091: MAKE_STD_ZVAL(zdlnow);
1092: MAKE_STD_ZVAL(zultotal);
1093: MAKE_STD_ZVAL(zulnow);
1094:
1095: ZVAL_LONG(zdltotal, (long) dltotal);
1096: ZVAL_LONG(zdlnow, (long) dlnow);
1097: ZVAL_LONG(zultotal, (long) ultotal);
1098: ZVAL_LONG(zulnow, (long) ulnow);
1099:
1100: argv[0] = &zdltotal;
1101: argv[1] = &zdlnow;
1102: argv[2] = &zultotal;
1103: argv[3] = &zulnow;
1104:
1105: fci.size = sizeof(fci);
1106: fci.function_table = EG(function_table);
1107: fci.function_name = t->func_name;
1108: fci.object_ptr = NULL;
1109: fci.retval_ptr_ptr = &retval_ptr;
1110: fci.param_count = 4;
1111: fci.params = argv;
1112: fci.no_separation = 0;
1113: fci.symbol_table = NULL;
1114:
1115: ch->in_callback = 1;
1116: error = zend_call_function(&fci, &t->fci_cache TSRMLS_CC);
1117: ch->in_callback = 0;
1118: if (error == FAILURE) {
1119: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot call the CURLOPT_PROGRESSFUNCTION");
1120: } else if (retval_ptr) {
1121: if (Z_TYPE_P(retval_ptr) != IS_LONG) {
1122: convert_to_long_ex(&retval_ptr);
1123: }
1124: if (0 != Z_LVAL_P(retval_ptr)) {
1125: rval = 1;
1126: }
1127: zval_ptr_dtor(&retval_ptr);
1128: }
1129: zval_ptr_dtor(argv[0]);
1130: zval_ptr_dtor(argv[1]);
1131: zval_ptr_dtor(argv[2]);
1132: zval_ptr_dtor(argv[3]);
1133: break;
1134: }
1135: }
1136: return rval;
1137: }
1138: /* }}} */
1139:
1140: /* {{{ curl_read
1141: */
1142: static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx)
1143: {
1144: php_curl *ch = (php_curl *) ctx;
1145: php_curl_read *t = ch->handlers->read;
1146: int length = 0;
1147:
1148: switch (t->method) {
1149: case PHP_CURL_DIRECT:
1150: if (t->fp) {
1151: length = fread(data, size, nmemb, t->fp);
1152: }
1153: break;
1154: case PHP_CURL_USER: {
1155: zval **argv[3];
1156: zval *handle = NULL;
1157: zval *zfd = NULL;
1158: zval *zlength = NULL;
1159: zval *retval_ptr;
1160: int error;
1161: zend_fcall_info fci;
1162: TSRMLS_FETCH_FROM_CTX(ch->thread_ctx);
1163:
1164: MAKE_STD_ZVAL(handle);
1165: MAKE_STD_ZVAL(zfd);
1166: MAKE_STD_ZVAL(zlength);
1167:
1168: ZVAL_RESOURCE(handle, ch->id);
1169: zend_list_addref(ch->id);
1170: ZVAL_RESOURCE(zfd, t->fd);
1171: zend_list_addref(t->fd);
1172: ZVAL_LONG(zlength, (int) size * nmemb);
1173:
1174: argv[0] = &handle;
1175: argv[1] = &zfd;
1176: argv[2] = &zlength;
1177:
1178: fci.size = sizeof(fci);
1179: fci.function_table = EG(function_table);
1180: fci.function_name = t->func_name;
1181: fci.object_ptr = NULL;
1182: fci.retval_ptr_ptr = &retval_ptr;
1183: fci.param_count = 3;
1184: fci.params = argv;
1185: fci.no_separation = 0;
1186: fci.symbol_table = NULL;
1187:
1188: ch->in_callback = 1;
1189: error = zend_call_function(&fci, &t->fci_cache TSRMLS_CC);
1190: ch->in_callback = 0;
1191: if (error == FAILURE) {
1192: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot call the CURLOPT_READFUNCTION");
1193: #if LIBCURL_VERSION_NUM >= 0x070c01 /* 7.12.1 */
1194: length = CURL_READFUNC_ABORT;
1195: #endif
1196: } else if (retval_ptr) {
1197: if (Z_TYPE_P(retval_ptr) == IS_STRING) {
1198: length = MIN((int) (size * nmemb), Z_STRLEN_P(retval_ptr));
1199: memcpy(data, Z_STRVAL_P(retval_ptr), length);
1200: }
1201: zval_ptr_dtor(&retval_ptr);
1202: }
1203:
1204: zval_ptr_dtor(argv[0]);
1205: zval_ptr_dtor(argv[1]);
1206: zval_ptr_dtor(argv[2]);
1207: break;
1208: }
1209: }
1210:
1211: return length;
1212: }
1213: /* }}} */
1214:
1215: /* {{{ curl_write_header
1216: */
1217: static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx)
1218: {
1219: php_curl *ch = (php_curl *) ctx;
1220: php_curl_write *t = ch->handlers->write_header;
1221: size_t length = size * nmemb;
1222: TSRMLS_FETCH_FROM_CTX(ch->thread_ctx);
1223:
1224: switch (t->method) {
1225: case PHP_CURL_STDOUT:
1226: /* Handle special case write when we're returning the entire transfer
1227: */
1228: if (ch->handlers->write->method == PHP_CURL_RETURN && length > 0) {
1229: smart_str_appendl(&ch->handlers->write->buf, data, (int) length);
1230: } else {
1231: PHPWRITE(data, length);
1232: }
1233: break;
1234: case PHP_CURL_FILE:
1235: return fwrite(data, size, nmemb, t->fp);
1236: case PHP_CURL_USER: {
1237: zval **argv[2];
1238: zval *handle = NULL;
1239: zval *zdata = NULL;
1240: zval *retval_ptr;
1241: int error;
1242: zend_fcall_info fci;
1243:
1244: MAKE_STD_ZVAL(handle);
1245: MAKE_STD_ZVAL(zdata);
1246:
1247: ZVAL_RESOURCE(handle, ch->id);
1248: zend_list_addref(ch->id);
1249: ZVAL_STRINGL(zdata, data, length, 1);
1250:
1251: argv[0] = &handle;
1252: argv[1] = &zdata;
1253:
1254: fci.size = sizeof(fci);
1255: fci.function_table = EG(function_table);
1256: fci.function_name = t->func_name;
1257: fci.symbol_table = NULL;
1258: fci.object_ptr = NULL;
1259: fci.retval_ptr_ptr = &retval_ptr;
1260: fci.param_count = 2;
1261: fci.params = argv;
1262: fci.no_separation = 0;
1263:
1264: ch->in_callback = 1;
1265: error = zend_call_function(&fci, &t->fci_cache TSRMLS_CC);
1266: ch->in_callback = 0;
1267: if (error == FAILURE) {
1268: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the CURLOPT_HEADERFUNCTION");
1269: length = -1;
1270: } else if (retval_ptr) {
1271: if (Z_TYPE_P(retval_ptr) != IS_LONG) {
1272: convert_to_long_ex(&retval_ptr);
1273: }
1274: length = Z_LVAL_P(retval_ptr);
1275: zval_ptr_dtor(&retval_ptr);
1276: }
1277: zval_ptr_dtor(argv[0]);
1278: zval_ptr_dtor(argv[1]);
1279: break;
1280: }
1281:
1282: case PHP_CURL_IGNORE:
1283: return length;
1284:
1285: default:
1286: return -1;
1287: }
1288:
1289: return length;
1290: }
1291: /* }}} */
1292:
1293: static int curl_debug(CURL *cp, curl_infotype type, char *buf, size_t buf_len, void *ctx) /* {{{ */
1294: {
1295: php_curl *ch = (php_curl *) ctx;
1296:
1297: if (type == CURLINFO_HEADER_OUT) {
1298: if (ch->header.str_len) {
1299: efree(ch->header.str);
1300: }
1301: if (buf_len > 0) {
1302: ch->header.str = estrndup(buf, buf_len);
1303: ch->header.str_len = buf_len;
1304: }
1305: }
1306:
1307: return 0;
1308: }
1309: /* }}} */
1310:
1311: #if CURLOPT_PASSWDFUNCTION != 0
1312: /* {{{ curl_passwd
1313: */
1314: static size_t curl_passwd(void *ctx, char *prompt, char *buf, int buflen)
1315: {
1316: php_curl *ch = (php_curl *) ctx;
1317: zval *func = ch->handlers->passwd;
1318: zval *argv[3];
1319: zval *retval = NULL;
1320: int error;
1321: int ret = -1;
1322: TSRMLS_FETCH_FROM_CTX(ch->thread_ctx);
1323:
1324: MAKE_STD_ZVAL(argv[0]);
1325: MAKE_STD_ZVAL(argv[1]);
1326: MAKE_STD_ZVAL(argv[2]);
1327:
1328: ZVAL_RESOURCE(argv[0], ch->id);
1329: zend_list_addref(ch->id);
1330: ZVAL_STRING(argv[1], prompt, 1);
1331: ZVAL_LONG(argv[2], buflen);
1332:
1333: error = call_user_function(EG(function_table), NULL, func, retval, 2, argv TSRMLS_CC);
1334: if (error == FAILURE) {
1335: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the CURLOPT_PASSWDFUNCTION");
1336: } else if (Z_TYPE_P(retval) == IS_STRING) {
1337: if (Z_STRLEN_P(retval) > buflen) {
1338: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Returned password is too long for libcurl to handle");
1339: } else {
1340: strlcpy(buf, Z_STRVAL_P(retval), Z_STRLEN_P(retval));
1341: }
1342: } else {
1343: php_error_docref(NULL TSRMLS_CC, E_WARNING, "User handler '%s' did not return a string", Z_STRVAL_P(func));
1344: }
1345:
1346: zval_ptr_dtor(&argv[0]);
1347: zval_ptr_dtor(&argv[1]);
1348: zval_ptr_dtor(&argv[2]);
1349: zval_ptr_dtor(&retval);
1350:
1351: return ret;
1352: }
1353: /* }}} */
1354: #endif
1355:
1356: /* {{{ curl_free_string
1357: */
1358: static void curl_free_string(void **string)
1359: {
1360: efree(*string);
1361: }
1362: /* }}} */
1363:
1364: /* {{{ curl_free_post
1365: */
1366: static void curl_free_post(void **post)
1367: {
1368: curl_formfree((struct HttpPost *) *post);
1369: }
1370: /* }}} */
1371:
1372: /* {{{ curl_free_slist
1373: */
1.1.1.4 misho 1374: static void curl_free_slist(void *slist)
1.1 misho 1375: {
1.1.1.4 misho 1376: curl_slist_free_all(*((struct curl_slist **) slist));
1.1 misho 1377: }
1378: /* }}} */
1379:
1380: /* {{{ proto array curl_version([int version])
1381: Return cURL version information. */
1382: PHP_FUNCTION(curl_version)
1383: {
1384: curl_version_info_data *d;
1385: long uversion = CURLVERSION_NOW;
1386:
1387: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &uversion) == FAILURE) {
1388: return;
1389: }
1390:
1391: d = curl_version_info(uversion);
1392: if (d == NULL) {
1393: RETURN_FALSE;
1394: }
1395:
1396: array_init(return_value);
1397:
1398: CAAL("version_number", d->version_num);
1399: CAAL("age", d->age);
1400: CAAL("features", d->features);
1401: CAAL("ssl_version_number", d->ssl_version_num);
1402: CAAS("version", d->version);
1403: CAAS("host", d->host);
1404: CAAS("ssl_version", d->ssl_version);
1405: CAAS("libz_version", d->libz_version);
1406: /* Add an array of protocols */
1407: {
1408: char **p = (char **) d->protocols;
1409: zval *protocol_list = NULL;
1410:
1411: MAKE_STD_ZVAL(protocol_list);
1412: array_init(protocol_list);
1413:
1414: while (*p != NULL) {
1415: add_next_index_string(protocol_list, *p, 1);
1416: p++;
1417: }
1418: CAAZ("protocols", protocol_list);
1419: }
1420: }
1421: /* }}} */
1422:
1423: /* {{{ alloc_curl_handle
1424: */
1425: static void alloc_curl_handle(php_curl **ch)
1426: {
1427: *ch = emalloc(sizeof(php_curl));
1428: (*ch)->to_free = ecalloc(1, sizeof(struct _php_curl_free));
1429: (*ch)->handlers = ecalloc(1, sizeof(php_curl_handlers));
1430: (*ch)->handlers->write = ecalloc(1, sizeof(php_curl_write));
1431: (*ch)->handlers->write_header = ecalloc(1, sizeof(php_curl_write));
1432: (*ch)->handlers->read = ecalloc(1, sizeof(php_curl_read));
1433: (*ch)->handlers->progress = ecalloc(1, sizeof(php_curl_progress));
1434:
1435: (*ch)->in_callback = 0;
1436: (*ch)->header.str_len = 0;
1437:
1438: memset(&(*ch)->err, 0, sizeof((*ch)->err));
1439: (*ch)->handlers->write->stream = NULL;
1440: (*ch)->handlers->write_header->stream = NULL;
1441: (*ch)->handlers->read->stream = NULL;
1442:
1443: zend_llist_init(&(*ch)->to_free->str, sizeof(char *), (llist_dtor_func_t) curl_free_string, 0);
1444: zend_llist_init(&(*ch)->to_free->post, sizeof(struct HttpPost), (llist_dtor_func_t) curl_free_post, 0);
1.1.1.4 misho 1445:
1446: (*ch)->to_free->slist = emalloc(sizeof(HashTable));
1447: zend_hash_init((*ch)->to_free->slist, 4, NULL, curl_free_slist, 0);
1.1 misho 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:
1.1.1.4 misho 1678: efree(dupch->to_free->slist);
1.1 misho 1679: efree(dupch->to_free);
1680: dupch->to_free = ch->to_free;
1681:
1682: /* Keep track of cloned copies to avoid invoking curl destructors for every clone */
1683: Z_ADDREF_P(ch->clone);
1684: dupch->clone = ch->clone;
1685:
1686: ZEND_REGISTER_RESOURCE(return_value, dupch, le_curl);
1687: dupch->id = Z_LVAL_P(return_value);
1688: }
1689: /* }}} */
1690:
1691: static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *return_value TSRMLS_DC) /* {{{ */
1692: {
1693: CURLcode error=CURLE_OK;
1694:
1695: switch (option) {
1.1.1.3 misho 1696: /* Long options */
1697: case CURLOPT_SSL_VERIFYHOST:
1698: if(Z_BVAL_PP(zvalue) == 1) {
1699: #if LIBCURL_VERSION_NUM <= 0x071c00 /* 7.28.0 */
1700: 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");
1701: #else
1702: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "CURLOPT_SSL_VERIFYHOST no longer accepts the value 1, value 2 will be used instead");
1703: error = curl_easy_setopt(ch->cp, option, 2);
1704: break;
1705: #endif
1706: }
1.1 misho 1707: case CURLOPT_INFILESIZE:
1708: case CURLOPT_VERBOSE:
1709: case CURLOPT_HEADER:
1710: case CURLOPT_NOPROGRESS:
1711: case CURLOPT_NOBODY:
1712: case CURLOPT_FAILONERROR:
1713: case CURLOPT_UPLOAD:
1714: case CURLOPT_POST:
1715: case CURLOPT_FTPLISTONLY:
1716: case CURLOPT_FTPAPPEND:
1717: case CURLOPT_NETRC:
1718: case CURLOPT_PUT:
1719: #if CURLOPT_MUTE != 0
1720: case CURLOPT_MUTE:
1721: #endif
1722: case CURLOPT_TIMEOUT:
1723: #if LIBCURL_VERSION_NUM > 0x071002
1724: case CURLOPT_TIMEOUT_MS:
1725: #endif
1726: case CURLOPT_FTP_USE_EPSV:
1727: case CURLOPT_LOW_SPEED_LIMIT:
1728: case CURLOPT_SSLVERSION:
1729: case CURLOPT_LOW_SPEED_TIME:
1730: case CURLOPT_RESUME_FROM:
1731: case CURLOPT_TIMEVALUE:
1732: case CURLOPT_TIMECONDITION:
1733: case CURLOPT_TRANSFERTEXT:
1734: case CURLOPT_HTTPPROXYTUNNEL:
1735: case CURLOPT_FILETIME:
1736: case CURLOPT_MAXREDIRS:
1737: case CURLOPT_MAXCONNECTS:
1738: case CURLOPT_CLOSEPOLICY:
1739: case CURLOPT_FRESH_CONNECT:
1740: case CURLOPT_FORBID_REUSE:
1741: case CURLOPT_CONNECTTIMEOUT:
1742: #if LIBCURL_VERSION_NUM > 0x071002
1743: case CURLOPT_CONNECTTIMEOUT_MS:
1744: #endif
1745: case CURLOPT_SSL_VERIFYPEER:
1746: case CURLOPT_DNS_USE_GLOBAL_CACHE:
1747: case CURLOPT_NOSIGNAL:
1748: case CURLOPT_PROXYTYPE:
1749: case CURLOPT_BUFFERSIZE:
1750: case CURLOPT_HTTPGET:
1751: case CURLOPT_HTTP_VERSION:
1752: case CURLOPT_CRLF:
1753: case CURLOPT_DNS_CACHE_TIMEOUT:
1754: case CURLOPT_PROXYPORT:
1755: case CURLOPT_FTP_USE_EPRT:
1756: #if LIBCURL_VERSION_NUM > 0x070a05 /* CURLOPT_HTTPAUTH is available since curl 7.10.6 */
1757: case CURLOPT_HTTPAUTH:
1758: #endif
1759: #if LIBCURL_VERSION_NUM > 0x070a06 /* CURLOPT_PROXYAUTH & CURLOPT_FTP_CREATE_MISSING_DIRS are available since curl 7.10.7 */
1760: case CURLOPT_PROXYAUTH:
1761: case CURLOPT_FTP_CREATE_MISSING_DIRS:
1762: #endif
1763:
1764: #if LIBCURL_VERSION_NUM >= 0x070c02
1765: case CURLOPT_FTPSSLAUTH:
1766: #endif
1767: #if LIBCURL_VERSION_NUM > 0x070b00
1768: case CURLOPT_FTP_SSL:
1769: #endif
1770: case CURLOPT_UNRESTRICTED_AUTH:
1771: case CURLOPT_PORT:
1772: case CURLOPT_AUTOREFERER:
1773: case CURLOPT_COOKIESESSION:
1774: #if LIBCURL_VERSION_NUM > 0x070b01 /* CURLOPT_TCP_NODELAY is available since curl 7.11.2 */
1775: case CURLOPT_TCP_NODELAY:
1776: #endif
1777: #if LIBCURL_VERSION_NUM >= 0x71304
1778: case CURLOPT_REDIR_PROTOCOLS:
1779: case CURLOPT_PROTOCOLS:
1780: #endif
1781: #if LIBCURL_VERSION_NUM > 0x070a07 /* CURLOPT_IPRESOLVE is available since curl 7.10.8 */
1782: case CURLOPT_IPRESOLVE:
1783: #endif
1784: #if LIBCURL_VERSION_NUM >= 0x070f01
1785: case CURLOPT_FTP_FILEMETHOD:
1786: case CURLOPT_FTP_SKIP_PASV_IP:
1787: #endif
1788: #if LIBCURL_VERSION_NUM > 0x071301
1789: case CURLOPT_CERTINFO:
1790: #endif
1791: convert_to_long_ex(zvalue);
1792: #if LIBCURL_VERSION_NUM >= 0x71304
1793: if ((option == CURLOPT_PROTOCOLS || option == CURLOPT_REDIR_PROTOCOLS) &&
1.1.1.2 misho 1794: (PG(open_basedir) && *PG(open_basedir)) && (Z_LVAL_PP(zvalue) & CURLPROTO_FILE)) {
1795: php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLPROTO_FILE cannot be activated when an open_basedir is set");
1.1 misho 1796: RETVAL_FALSE;
1797: return 1;
1798: }
1799: #endif
1800: error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue));
1801: break;
1802: #if LIBCURL_VERSION_NUM > 0x070f04
1803: case CURLOPT_MAX_RECV_SPEED_LARGE:
1804: case CURLOPT_MAX_SEND_SPEED_LARGE:
1805: convert_to_long_ex(zvalue);
1806: error = curl_easy_setopt(ch->cp, option, (curl_off_t)Z_LVAL_PP(zvalue));
1807: break;
1808: #endif
1809: case CURLOPT_FOLLOWLOCATION:
1810: convert_to_long_ex(zvalue);
1.1.1.2 misho 1811: if (PG(open_basedir) && *PG(open_basedir)) {
1.1 misho 1812: if (Z_LVAL_PP(zvalue) != 0) {
1.1.1.2 misho 1813: php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_FOLLOWLOCATION cannot be activated when an open_basedir is set");
1.1 misho 1814: RETVAL_FALSE;
1815: return 1;
1816: }
1817: }
1818: error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue));
1819: break;
1820: #if LIBCURL_VERSION_NUM > 0x071301
1821: case CURLOPT_POSTREDIR:
1822: convert_to_long_ex(zvalue);
1823: error = curl_easy_setopt(ch->cp, CURLOPT_POSTREDIR, Z_LVAL_PP(zvalue) & CURL_REDIR_POST_ALL);
1824: break;
1825: #endif
1826: case CURLOPT_PRIVATE:
1827: case CURLOPT_URL:
1828: case CURLOPT_PROXY:
1829: case CURLOPT_USERPWD:
1830: case CURLOPT_PROXYUSERPWD:
1831: case CURLOPT_RANGE:
1832: case CURLOPT_CUSTOMREQUEST:
1833: case CURLOPT_USERAGENT:
1834: case CURLOPT_FTPPORT:
1835: case CURLOPT_COOKIE:
1836: case CURLOPT_REFERER:
1837: case CURLOPT_INTERFACE:
1838: case CURLOPT_KRB4LEVEL:
1839: case CURLOPT_EGDSOCKET:
1840: case CURLOPT_CAINFO:
1841: case CURLOPT_CAPATH:
1842: case CURLOPT_SSL_CIPHER_LIST:
1843: case CURLOPT_SSLKEY:
1844: case CURLOPT_SSLKEYTYPE:
1845: case CURLOPT_SSLKEYPASSWD:
1846: case CURLOPT_SSLENGINE:
1847: case CURLOPT_SSLENGINE_DEFAULT:
1848: case CURLOPT_SSLCERTTYPE:
1849: case CURLOPT_ENCODING:
1850: #if LIBCURL_VERSION_NUM >= 0x071300
1851: case CURLOPT_SSH_PUBLIC_KEYFILE:
1852: case CURLOPT_SSH_PRIVATE_KEYFILE:
1853: #endif
1854: {
1855: convert_to_string_ex(zvalue);
1856: #if LIBCURL_VERSION_NUM >= 0x071300
1857: if (
1858: option == CURLOPT_SSH_PUBLIC_KEYFILE || option == CURLOPT_SSH_PRIVATE_KEYFILE
1859:
1860: ) {
1.1.1.2 misho 1861: if (php_check_open_basedir(Z_STRVAL_PP(zvalue) TSRMLS_CC)) {
1.1 misho 1862: RETVAL_FALSE;
1863: return 1;
1864: }
1865: }
1866: #endif
1867: if (option == CURLOPT_URL) {
1.1.1.2 misho 1868: if (!php_curl_option_url(ch, Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue) TSRMLS_CC)) {
1.1 misho 1869: RETVAL_FALSE;
1870: return 1;
1871: }
1872: } else {
1873: if (option == CURLOPT_PRIVATE) {
1874: char *copystr;
1875: #if LIBCURL_VERSION_NUM < 0x071100
1876: string_copy:
1877: #endif
1878: copystr = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue));
1879: error = curl_easy_setopt(ch->cp, option, copystr);
1880: zend_llist_add_element(&ch->to_free->str, ©str);
1881: } else {
1882: #if LIBCURL_VERSION_NUM >= 0x071100
1883: /* Strings passed to libcurl as ’char *’ arguments, are copied by the library... NOTE: before 7.17.0 strings were not copied. */
1884: error = curl_easy_setopt(ch->cp, option, Z_STRVAL_PP(zvalue));
1885: #else
1886: goto string_copy;
1887: #endif
1888: }
1889: }
1890: break;
1891: }
1892: case CURLOPT_FILE:
1893: case CURLOPT_INFILE:
1894: case CURLOPT_WRITEHEADER:
1895: case CURLOPT_STDERR: {
1896: FILE *fp = NULL;
1897: int type;
1898: void * what;
1899:
1900: what = zend_fetch_resource(zvalue TSRMLS_CC, -1, "File-Handle", &type, 1, php_file_le_stream(), php_file_le_pstream());
1901: if (!what) {
1902: RETVAL_FALSE;
1903: return 1;
1904: }
1905:
1906: if (FAILURE == php_stream_cast((php_stream *) what, PHP_STREAM_AS_STDIO, (void *) &fp, REPORT_ERRORS)) {
1907: RETVAL_FALSE;
1908: return 1;
1909: }
1910:
1911: if (!fp) {
1912: RETVAL_FALSE;
1913: return 1;
1914: }
1915:
1916: error = CURLE_OK;
1917: switch (option) {
1918: case CURLOPT_FILE:
1919: if (((php_stream *) what)->mode[0] != 'r' || ((php_stream *) what)->mode[1] == '+') {
1920: if (ch->handlers->write->stream) {
1921: Z_DELREF_P(ch->handlers->write->stream);
1922: }
1923: Z_ADDREF_PP(zvalue);
1924: ch->handlers->write->fp = fp;
1925: ch->handlers->write->method = PHP_CURL_FILE;
1926: ch->handlers->write->stream = *zvalue;
1927: } else {
1928: php_error_docref(NULL TSRMLS_CC, E_WARNING, "the provided file handle is not writable");
1929: RETVAL_FALSE;
1930: return 1;
1931: }
1932: break;
1933: case CURLOPT_WRITEHEADER:
1934: if (((php_stream *) what)->mode[0] != 'r' || ((php_stream *) what)->mode[1] == '+') {
1935: if (ch->handlers->write_header->stream) {
1936: Z_DELREF_P(ch->handlers->write_header->stream);
1937: }
1938: Z_ADDREF_PP(zvalue);
1939: ch->handlers->write_header->fp = fp;
1940: ch->handlers->write_header->method = PHP_CURL_FILE;
1941: ch->handlers->write_header->stream = *zvalue;
1942: } else {
1943: php_error_docref(NULL TSRMLS_CC, E_WARNING, "the provided file handle is not writable");
1944: RETVAL_FALSE;
1945: return 1;
1946: }
1947: break;
1948: case CURLOPT_INFILE:
1949: if (ch->handlers->read->stream) {
1950: Z_DELREF_P(ch->handlers->read->stream);
1951: }
1952: Z_ADDREF_PP(zvalue);
1953: ch->handlers->read->fp = fp;
1954: ch->handlers->read->fd = Z_LVAL_PP(zvalue);
1955: ch->handlers->read->stream = *zvalue;
1956: break;
1957: case CURLOPT_STDERR:
1958: if (((php_stream *) what)->mode[0] != 'r' || ((php_stream *) what)->mode[1] == '+') {
1959: if (ch->handlers->std_err) {
1960: zval_ptr_dtor(&ch->handlers->std_err);
1961: }
1962: zval_add_ref(zvalue);
1963: ch->handlers->std_err = *zvalue;
1964: } else {
1965: php_error_docref(NULL TSRMLS_CC, E_WARNING, "the provided file handle is not writable");
1966: RETVAL_FALSE;
1967: return 1;
1968: }
1969: /* break omitted intentionally */
1970: default:
1971: error = curl_easy_setopt(ch->cp, option, fp);
1972: break;
1973: }
1974:
1975: break;
1976: }
1977: case CURLOPT_RETURNTRANSFER:
1978: convert_to_long_ex(zvalue);
1979:
1980: if (Z_LVAL_PP(zvalue)) {
1981: ch->handlers->write->method = PHP_CURL_RETURN;
1982: } else {
1983: ch->handlers->write->method = PHP_CURL_STDOUT;
1984: }
1985: break;
1986: case CURLOPT_BINARYTRANSFER:
1987: convert_to_long_ex(zvalue);
1988:
1989: if (Z_LVAL_PP(zvalue)) {
1990: ch->handlers->write->type = PHP_CURL_BINARY;
1991: } else {
1992: ch->handlers->write->type = PHP_CURL_ASCII;
1993: }
1994: break;
1995: case CURLOPT_WRITEFUNCTION:
1996: if (ch->handlers->write->func_name) {
1997: zval_ptr_dtor(&ch->handlers->write->func_name);
1998: ch->handlers->write->fci_cache = empty_fcall_info_cache;
1999: }
2000: zval_add_ref(zvalue);
2001: ch->handlers->write->func_name = *zvalue;
2002: ch->handlers->write->method = PHP_CURL_USER;
2003: break;
2004: case CURLOPT_READFUNCTION:
2005: if (ch->handlers->read->func_name) {
2006: zval_ptr_dtor(&ch->handlers->read->func_name);
2007: ch->handlers->read->fci_cache = empty_fcall_info_cache;
2008: }
2009: zval_add_ref(zvalue);
2010: ch->handlers->read->func_name = *zvalue;
2011: ch->handlers->read->method = PHP_CURL_USER;
2012: break;
2013: case CURLOPT_PROGRESSFUNCTION:
2014: curl_easy_setopt(ch->cp, CURLOPT_PROGRESSFUNCTION, curl_progress);
2015: curl_easy_setopt(ch->cp, CURLOPT_PROGRESSDATA, ch);
2016: if (ch->handlers->progress->func_name) {
2017: zval_ptr_dtor(&ch->handlers->progress->func_name);
2018: ch->handlers->progress->fci_cache = empty_fcall_info_cache;
2019: }
2020: zval_add_ref(zvalue);
2021: ch->handlers->progress->func_name = *zvalue;
2022: ch->handlers->progress->method = PHP_CURL_USER;
2023: break;
2024: case CURLOPT_HEADERFUNCTION:
2025: if (ch->handlers->write_header->func_name) {
2026: zval_ptr_dtor(&ch->handlers->write_header->func_name);
2027: ch->handlers->write_header->fci_cache = empty_fcall_info_cache;
2028: }
2029: zval_add_ref(zvalue);
2030: ch->handlers->write_header->func_name = *zvalue;
2031: ch->handlers->write_header->method = PHP_CURL_USER;
2032: break;
2033: #if CURLOPT_PASSWDFUNCTION != 0
2034: case CURLOPT_PASSWDFUNCTION:
2035: if (ch->handlers->passwd) {
2036: zval_ptr_dtor(&ch->handlers->passwd);
2037: }
2038: zval_add_ref(zvalue);
2039: ch->handlers->passwd = *zvalue;
2040: error = curl_easy_setopt(ch->cp, CURLOPT_PASSWDFUNCTION, curl_passwd);
2041: error = curl_easy_setopt(ch->cp, CURLOPT_PASSWDDATA, (void *) ch);
2042: break;
2043: #endif
2044: case CURLOPT_POSTFIELDS:
2045: if (Z_TYPE_PP(zvalue) == IS_ARRAY || Z_TYPE_PP(zvalue) == IS_OBJECT) {
2046: zval **current;
2047: HashTable *postfields;
2048: struct HttpPost *first = NULL;
2049: struct HttpPost *last = NULL;
2050:
2051: postfields = HASH_OF(*zvalue);
2052: if (!postfields) {
2053: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't get HashTable in CURLOPT_POSTFIELDS");
2054: RETVAL_FALSE;
2055: return 1;
2056: }
2057:
2058: for (zend_hash_internal_pointer_reset(postfields);
2059: zend_hash_get_current_data(postfields, (void **) ¤t) == SUCCESS;
2060: zend_hash_move_forward(postfields)
2061: ) {
1.1.1.2 misho 2062: char *postval;
2063: char *string_key = NULL;
2064: uint string_key_len;
2065: ulong num_key;
2066: int numeric_key;
1.1 misho 2067:
2068: SEPARATE_ZVAL(current);
2069: convert_to_string_ex(current);
2070:
2071: zend_hash_get_current_key_ex(postfields, &string_key, &string_key_len, &num_key, 0, NULL);
2072:
1.1.1.2 misho 2073: /* Pretend we have a string_key here */
2074: if(!string_key) {
2075: spprintf(&string_key, 0, "%ld", num_key);
2076: string_key_len = strlen(string_key)+1;
2077: numeric_key = 1;
2078: } else {
2079: numeric_key = 0;
2080: }
2081:
1.1 misho 2082: postval = Z_STRVAL_PP(current);
2083:
2084: /* The arguments after _NAMELENGTH and _CONTENTSLENGTH
2085: * must be explicitly cast to long in curl_formadd
2086: * use since curl needs a long not an int. */
2087: if (*postval == '@') {
2088: char *type, *filename;
2089: ++postval;
2090:
2091: if ((type = php_memnstr(postval, ";type=", sizeof(";type=") - 1, postval + Z_STRLEN_PP(current)))) {
2092: *type = '\0';
2093: }
2094: if ((filename = php_memnstr(postval, ";filename=", sizeof(";filename=") - 1, postval + Z_STRLEN_PP(current)))) {
2095: *filename = '\0';
2096: }
1.1.1.2 misho 2097: /* open_basedir check */
2098: if (php_check_open_basedir(postval TSRMLS_CC)) {
1.1 misho 2099: RETVAL_FALSE;
2100: return 1;
2101: }
2102: error = curl_formadd(&first, &last,
2103: CURLFORM_COPYNAME, string_key,
2104: CURLFORM_NAMELENGTH, (long)string_key_len - 1,
2105: CURLFORM_FILENAME, filename ? filename + sizeof(";filename=") - 1 : postval,
2106: CURLFORM_CONTENTTYPE, type ? type + sizeof(";type=") - 1 : "application/octet-stream",
2107: CURLFORM_FILE, postval,
2108: CURLFORM_END);
2109: if (type) {
2110: *type = ';';
2111: }
2112: if (filename) {
2113: *filename = ';';
2114: }
2115: } else {
2116: error = curl_formadd(&first, &last,
2117: CURLFORM_COPYNAME, string_key,
2118: CURLFORM_NAMELENGTH, (long)string_key_len - 1,
2119: CURLFORM_COPYCONTENTS, postval,
2120: CURLFORM_CONTENTSLENGTH, (long)Z_STRLEN_PP(current),
2121: CURLFORM_END);
2122: }
1.1.1.2 misho 2123:
2124: if (numeric_key) {
2125: efree(string_key);
2126: }
1.1 misho 2127: }
2128:
2129: SAVE_CURL_ERROR(ch, error);
2130: if (error != CURLE_OK) {
2131: RETVAL_FALSE;
2132: return 1;
2133: }
2134:
1.1.1.3 misho 2135: if (Z_REFCOUNT_P(ch->clone) <= 1) {
2136: zend_llist_clean(&ch->to_free->post);
2137: }
1.1 misho 2138: zend_llist_add_element(&ch->to_free->post, &first);
2139: error = curl_easy_setopt(ch->cp, CURLOPT_HTTPPOST, first);
2140:
2141: } else {
2142: #if LIBCURL_VERSION_NUM >= 0x071101
2143: convert_to_string_ex(zvalue);
2144: /* with curl 7.17.0 and later, we can use COPYPOSTFIELDS, but we have to provide size before */
2145: error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, Z_STRLEN_PP(zvalue));
2146: error = curl_easy_setopt(ch->cp, CURLOPT_COPYPOSTFIELDS, Z_STRVAL_PP(zvalue));
2147: #else
2148: char *post = NULL;
2149:
2150: convert_to_string_ex(zvalue);
2151: post = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue));
2152: zend_llist_add_element(&ch->to_free->str, &post);
2153:
2154: error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDS, post);
2155: error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, Z_STRLEN_PP(zvalue));
2156: #endif
2157: }
2158: break;
2159: case CURLOPT_HTTPHEADER:
2160: case CURLOPT_QUOTE:
2161: case CURLOPT_HTTP200ALIASES:
2162: case CURLOPT_POSTQUOTE: {
2163: zval **current;
2164: HashTable *ph;
2165: struct curl_slist *slist = NULL;
2166:
2167: ph = HASH_OF(*zvalue);
2168: if (!ph) {
2169: 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");
2170: RETVAL_FALSE;
2171: return 1;
2172: }
2173:
2174: for (zend_hash_internal_pointer_reset(ph);
2175: zend_hash_get_current_data(ph, (void **) ¤t) == SUCCESS;
2176: zend_hash_move_forward(ph)
2177: ) {
2178: SEPARATE_ZVAL(current);
2179: convert_to_string_ex(current);
2180:
2181: slist = curl_slist_append(slist, Z_STRVAL_PP(current));
2182: if (!slist) {
2183: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not build curl_slist");
2184: RETVAL_FALSE;
2185: return 1;
2186: }
2187: }
1.1.1.4 misho 2188: zend_hash_index_update(ch->to_free->slist, (ulong) option, &slist, sizeof(struct curl_slist *), NULL);
1.1 misho 2189:
2190: error = curl_easy_setopt(ch->cp, option, slist);
2191:
2192: break;
2193: }
1.1.1.2 misho 2194: /* the following options deal with files, therefore the open_basedir check
2195: * is required.
1.1 misho 2196: */
2197: case CURLOPT_COOKIEJAR:
2198: case CURLOPT_SSLCERT:
2199: case CURLOPT_RANDOM_FILE:
2200: case CURLOPT_COOKIEFILE: {
2201: #if LIBCURL_VERSION_NUM < 0x071100
2202: char *copystr = NULL;
2203: #endif
2204:
2205: convert_to_string_ex(zvalue);
2206:
1.1.1.3 misho 2207: if (Z_STRLEN_PP(zvalue) && php_check_open_basedir(Z_STRVAL_PP(zvalue) TSRMLS_CC)) {
1.1 misho 2208: RETVAL_FALSE;
2209: return 1;
2210: }
2211:
2212: #if LIBCURL_VERSION_NUM >= 0x071100
2213: error = curl_easy_setopt(ch->cp, option, Z_STRVAL_PP(zvalue));
2214: #else
2215: copystr = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue));
2216:
2217: error = curl_easy_setopt(ch->cp, option, copystr);
2218: zend_llist_add_element(&ch->to_free->str, ©str);
2219: #endif
2220: break;
2221: }
2222: case CURLINFO_HEADER_OUT:
2223: convert_to_long_ex(zvalue);
2224: if (Z_LVAL_PP(zvalue) == 1) {
2225: curl_easy_setopt(ch->cp, CURLOPT_DEBUGFUNCTION, curl_debug);
2226: curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA, (void *)ch);
2227: curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 1);
2228: } else {
2229: curl_easy_setopt(ch->cp, CURLOPT_DEBUGFUNCTION, NULL);
2230: curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA, NULL);
2231: curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 0);
2232: }
2233: break;
2234: }
2235:
2236: SAVE_CURL_ERROR(ch, error);
2237: if (error != CURLE_OK) {
2238: return 1;
2239: } else {
2240: return 0;
2241: }
2242: }
2243: /* }}} */
2244:
2245: /* {{{ proto bool curl_setopt(resource ch, int option, mixed value)
2246: Set an option for a cURL transfer */
2247: PHP_FUNCTION(curl_setopt)
2248: {
2249: zval *zid, **zvalue;
2250: long options;
2251: php_curl *ch;
2252:
2253: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlZ", &zid, &options, &zvalue) == FAILURE) {
2254: return;
2255: }
2256:
2257: ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl);
2258:
2259: if (options <= 0) {
2260: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid curl configuration option");
2261: RETURN_FALSE;
2262: }
2263:
2264: if (!_php_curl_setopt(ch, options, zvalue, return_value TSRMLS_CC)) {
2265: RETURN_TRUE;
2266: } else {
2267: RETURN_FALSE;
2268: }
2269: }
2270: /* }}} */
2271:
2272: /* {{{ proto bool curl_setopt_array(resource ch, array options)
2273: Set an array of option for a cURL transfer */
2274: PHP_FUNCTION(curl_setopt_array)
2275: {
2276: zval *zid, *arr, **entry;
2277: php_curl *ch;
2278: ulong option;
2279: HashPosition pos;
2280: char *string_key;
2281: uint str_key_len;
2282:
2283: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "za", &zid, &arr) == FAILURE) {
2284: return;
2285: }
2286:
2287: ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl);
2288:
2289: zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos);
2290: while (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)&entry, &pos) == SUCCESS) {
2291: if (zend_hash_get_current_key_ex(Z_ARRVAL_P(arr), &string_key, &str_key_len, &option, 0, &pos) != HASH_KEY_IS_LONG) {
2292: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array keys must be CURLOPT constants or equivalent integer values");
2293: RETURN_FALSE;
2294: }
2295: if (_php_curl_setopt(ch, (long) option, entry, return_value TSRMLS_CC)) {
2296: RETURN_FALSE;
2297: }
2298: zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos);
2299: }
2300: RETURN_TRUE;
2301: }
2302: /* }}} */
2303:
2304: /* {{{ _php_curl_cleanup_handle(ch)
2305: Cleanup an execution phase */
2306: void _php_curl_cleanup_handle(php_curl *ch)
2307: {
2308: if (ch->handlers->write->buf.len > 0) {
2309: smart_str_free(&ch->handlers->write->buf);
2310: }
2311: if (ch->header.str_len) {
2312: efree(ch->header.str);
2313: ch->header.str_len = 0;
2314: }
2315:
2316: memset(ch->err.str, 0, CURL_ERROR_SIZE + 1);
2317: ch->err.no = 0;
2318: }
2319: /* }}} */
2320:
2321: /* {{{ proto bool curl_exec(resource ch)
2322: Perform a cURL session */
2323: PHP_FUNCTION(curl_exec)
2324: {
2325: CURLcode error;
2326: zval *zid;
2327: php_curl *ch;
2328:
2329: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zid) == FAILURE) {
2330: return;
2331: }
2332:
2333: ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl);
2334:
2335: _php_curl_verify_handlers(ch, 1 TSRMLS_CC);
2336:
2337: _php_curl_cleanup_handle(ch);
2338:
2339: error = curl_easy_perform(ch->cp);
2340: SAVE_CURL_ERROR(ch, error);
2341: /* CURLE_PARTIAL_FILE is returned by HEAD requests */
2342: if (error != CURLE_OK && error != CURLE_PARTIAL_FILE) {
2343: if (ch->handlers->write->buf.len > 0) {
2344: smart_str_free(&ch->handlers->write->buf);
2345: }
2346: RETURN_FALSE;
2347: }
2348:
2349: if (ch->handlers->std_err) {
2350: php_stream *stream;
2351: stream = (php_stream*)zend_fetch_resource(&ch->handlers->std_err TSRMLS_CC, -1, NULL, NULL, 2, php_file_le_stream(), php_file_le_pstream());
2352: if (stream) {
2353: php_stream_flush(stream);
2354: }
2355: }
2356:
2357: if (ch->handlers->write->method == PHP_CURL_RETURN && ch->handlers->write->buf.len > 0) {
2358: smart_str_0(&ch->handlers->write->buf);
2359: RETURN_STRINGL(ch->handlers->write->buf.c, ch->handlers->write->buf.len, 1);
2360: }
2361:
2362: /* flush the file handle, so any remaining data is synched to disk */
2363: if (ch->handlers->write->method == PHP_CURL_FILE && ch->handlers->write->fp) {
2364: fflush(ch->handlers->write->fp);
2365: }
2366: if (ch->handlers->write_header->method == PHP_CURL_FILE && ch->handlers->write_header->fp) {
2367: fflush(ch->handlers->write_header->fp);
2368: }
2369:
2370: if (ch->handlers->write->method == PHP_CURL_RETURN) {
2371: RETURN_EMPTY_STRING();
2372: } else {
2373: RETURN_TRUE;
2374: }
2375: }
2376: /* }}} */
2377:
2378: /* {{{ proto mixed curl_getinfo(resource ch [, int option])
2379: Get information regarding a specific transfer */
2380: PHP_FUNCTION(curl_getinfo)
2381: {
2382: zval *zid;
2383: php_curl *ch;
2384: long option = 0;
2385:
2386: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &zid, &option) == FAILURE) {
2387: return;
2388: }
2389:
2390: ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl);
2391:
2392: if (ZEND_NUM_ARGS() < 2) {
2393: char *s_code;
2394: long l_code;
2395: double d_code;
2396: #if LIBCURL_VERSION_NUM > 0x071301
2397: struct curl_certinfo *ci = NULL;
2398: zval *listcode;
2399: #endif
2400:
2401: array_init(return_value);
2402:
2403: if (curl_easy_getinfo(ch->cp, CURLINFO_EFFECTIVE_URL, &s_code) == CURLE_OK) {
2404: CAAS("url", s_code);
2405: }
2406: if (curl_easy_getinfo(ch->cp, CURLINFO_CONTENT_TYPE, &s_code) == CURLE_OK) {
2407: if (s_code != NULL) {
2408: CAAS("content_type", s_code);
2409: } else {
2410: zval *retnull;
2411: MAKE_STD_ZVAL(retnull);
2412: ZVAL_NULL(retnull);
2413: CAAZ("content_type", retnull);
2414: }
2415: }
2416: if (curl_easy_getinfo(ch->cp, CURLINFO_HTTP_CODE, &l_code) == CURLE_OK) {
2417: CAAL("http_code", l_code);
2418: }
2419: if (curl_easy_getinfo(ch->cp, CURLINFO_HEADER_SIZE, &l_code) == CURLE_OK) {
2420: CAAL("header_size", l_code);
2421: }
2422: if (curl_easy_getinfo(ch->cp, CURLINFO_REQUEST_SIZE, &l_code) == CURLE_OK) {
2423: CAAL("request_size", l_code);
2424: }
2425: if (curl_easy_getinfo(ch->cp, CURLINFO_FILETIME, &l_code) == CURLE_OK) {
2426: CAAL("filetime", l_code);
2427: }
2428: if (curl_easy_getinfo(ch->cp, CURLINFO_SSL_VERIFYRESULT, &l_code) == CURLE_OK) {
2429: CAAL("ssl_verify_result", l_code);
2430: }
2431: if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_COUNT, &l_code) == CURLE_OK) {
2432: CAAL("redirect_count", l_code);
2433: }
2434: if (curl_easy_getinfo(ch->cp, CURLINFO_TOTAL_TIME, &d_code) == CURLE_OK) {
2435: CAAD("total_time", d_code);
2436: }
2437: if (curl_easy_getinfo(ch->cp, CURLINFO_NAMELOOKUP_TIME, &d_code) == CURLE_OK) {
2438: CAAD("namelookup_time", d_code);
2439: }
2440: if (curl_easy_getinfo(ch->cp, CURLINFO_CONNECT_TIME, &d_code) == CURLE_OK) {
2441: CAAD("connect_time", d_code);
2442: }
2443: if (curl_easy_getinfo(ch->cp, CURLINFO_PRETRANSFER_TIME, &d_code) == CURLE_OK) {
2444: CAAD("pretransfer_time", d_code);
2445: }
2446: if (curl_easy_getinfo(ch->cp, CURLINFO_SIZE_UPLOAD, &d_code) == CURLE_OK) {
2447: CAAD("size_upload", d_code);
2448: }
2449: if (curl_easy_getinfo(ch->cp, CURLINFO_SIZE_DOWNLOAD, &d_code) == CURLE_OK) {
2450: CAAD("size_download", d_code);
2451: }
2452: if (curl_easy_getinfo(ch->cp, CURLINFO_SPEED_DOWNLOAD, &d_code) == CURLE_OK) {
2453: CAAD("speed_download", d_code);
2454: }
2455: if (curl_easy_getinfo(ch->cp, CURLINFO_SPEED_UPLOAD, &d_code) == CURLE_OK) {
2456: CAAD("speed_upload", d_code);
2457: }
2458: if (curl_easy_getinfo(ch->cp, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d_code) == CURLE_OK) {
2459: CAAD("download_content_length", d_code);
2460: }
2461: if (curl_easy_getinfo(ch->cp, CURLINFO_CONTENT_LENGTH_UPLOAD, &d_code) == CURLE_OK) {
2462: CAAD("upload_content_length", d_code);
2463: }
2464: if (curl_easy_getinfo(ch->cp, CURLINFO_STARTTRANSFER_TIME, &d_code) == CURLE_OK) {
2465: CAAD("starttransfer_time", d_code);
2466: }
2467: if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_TIME, &d_code) == CURLE_OK) {
2468: CAAD("redirect_time", d_code);
2469: }
2470: #if LIBCURL_VERSION_NUM > 0x071301
2471: if (curl_easy_getinfo(ch->cp, CURLINFO_CERTINFO, &ci) == CURLE_OK) {
2472: MAKE_STD_ZVAL(listcode);
2473: array_init(listcode);
2474: create_certinfo(ci, listcode TSRMLS_CC);
2475: CAAZ("certinfo", listcode);
2476: }
1.1.1.3 misho 2477: #endif
2478: #if LIBCURL_VERSION_NUM >= 0x071300 /* 7.19.0 */
1.1.1.2 misho 2479: if (curl_easy_getinfo(ch->cp, CURLINFO_PRIMARY_IP, &s_code) == CURLE_OK) {
2480: CAAS("primary_ip", s_code);
2481: }
2482: #endif
2483: #if LIBCURL_VERSION_NUM > 0x071500
2484: if (curl_easy_getinfo(ch->cp, CURLINFO_PRIMARY_PORT, &l_code) == CURLE_OK) {
2485: CAAL("primary_port", l_code);
2486: }
2487: if (curl_easy_getinfo(ch->cp, CURLINFO_LOCAL_IP, &s_code) == CURLE_OK) {
2488: CAAS("local_ip", s_code);
2489: }
2490: if (curl_easy_getinfo(ch->cp, CURLINFO_LOCAL_PORT, &l_code) == CURLE_OK) {
2491: CAAL("local_port", l_code);
2492: }
1.1 misho 2493: #endif
2494: #if LIBCURL_VERSION_NUM >= 0x071202
2495: if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_URL, &s_code) == CURLE_OK) {
2496: CAAS("redirect_url", s_code);
2497: }
2498: #endif
2499: if (ch->header.str_len > 0) {
2500: CAAS("request_header", ch->header.str);
2501: }
2502: } else {
2503: switch (option) {
1.1.1.2 misho 2504: /* string variable types */
1.1.1.3 misho 2505: #if LIBCURL_VERSION_NUM >= 0x071300 /* 7.19.0 */
1.1.1.2 misho 2506: case CURLINFO_PRIMARY_IP:
2507: #endif
1.1.1.3 misho 2508: #if LIBCURL_VERSION_NUM >= 0x071500 /* 7.21.0 */
1.1.1.2 misho 2509: case CURLINFO_LOCAL_IP:
2510: #endif
1.1 misho 2511: case CURLINFO_PRIVATE:
2512: case CURLINFO_EFFECTIVE_URL:
2513: case CURLINFO_CONTENT_TYPE:
2514: #if LIBCURL_VERSION_NUM >= 0x071202
2515: case CURLINFO_REDIRECT_URL:
2516: #endif
2517: {
2518: char *s_code = NULL;
2519:
2520: if (curl_easy_getinfo(ch->cp, option, &s_code) == CURLE_OK && s_code) {
2521: RETURN_STRING(s_code, 1);
2522: } else {
2523: RETURN_FALSE;
2524: }
2525: break;
2526: }
1.1.1.2 misho 2527: /* Long variable types */
1.1.1.3 misho 2528: #if LIBCURL_VERSION_NUM >= 0x071500 /* 7.21.0 */
1.1.1.2 misho 2529: case CURLINFO_PRIMARY_PORT:
2530: case CURLINFO_LOCAL_PORT:
2531: #endif
1.1 misho 2532: case CURLINFO_HTTP_CODE:
2533: case CURLINFO_HEADER_SIZE:
2534: case CURLINFO_REQUEST_SIZE:
2535: case CURLINFO_FILETIME:
2536: case CURLINFO_SSL_VERIFYRESULT:
2537: case CURLINFO_REDIRECT_COUNT: {
2538: long code = 0;
2539:
2540: if (curl_easy_getinfo(ch->cp, option, &code) == CURLE_OK) {
2541: RETURN_LONG(code);
2542: } else {
2543: RETURN_FALSE;
2544: }
2545: break;
2546: }
1.1.1.2 misho 2547: /* Double variable types */
1.1 misho 2548: case CURLINFO_TOTAL_TIME:
2549: case CURLINFO_NAMELOOKUP_TIME:
2550: case CURLINFO_CONNECT_TIME:
2551: case CURLINFO_PRETRANSFER_TIME:
2552: case CURLINFO_SIZE_UPLOAD:
2553: case CURLINFO_SIZE_DOWNLOAD:
2554: case CURLINFO_SPEED_DOWNLOAD:
2555: case CURLINFO_SPEED_UPLOAD:
2556: case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
2557: case CURLINFO_CONTENT_LENGTH_UPLOAD:
2558: case CURLINFO_STARTTRANSFER_TIME:
2559: case CURLINFO_REDIRECT_TIME: {
2560: double code = 0.0;
2561:
2562: if (curl_easy_getinfo(ch->cp, option, &code) == CURLE_OK) {
2563: RETURN_DOUBLE(code);
2564: } else {
2565: RETURN_FALSE;
2566: }
2567: break;
2568: }
2569: case CURLINFO_HEADER_OUT:
2570: if (ch->header.str_len > 0) {
2571: RETURN_STRINGL(ch->header.str, ch->header.str_len, 1);
2572: } else {
2573: RETURN_FALSE;
2574: }
2575: #if LIBCURL_VERSION_NUM > 0x071301
2576: case CURLINFO_CERTINFO: {
2577: struct curl_certinfo *ci = NULL;
2578:
2579: array_init(return_value);
2580:
2581: if (curl_easy_getinfo(ch->cp, CURLINFO_CERTINFO, &ci) == CURLE_OK) {
2582: create_certinfo(ci, return_value TSRMLS_CC);
2583: } else {
2584: RETURN_FALSE;
2585: }
2586: break;
2587: }
2588: #endif
2589: }
2590: }
2591: }
2592: /* }}} */
2593:
2594: /* {{{ proto string curl_error(resource ch)
2595: Return a string contain the last error for the current session */
2596: PHP_FUNCTION(curl_error)
2597: {
2598: zval *zid;
2599: php_curl *ch;
2600:
2601: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zid) == FAILURE) {
2602: return;
2603: }
2604:
2605: ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl);
2606:
2607: ch->err.str[CURL_ERROR_SIZE] = 0;
2608: RETURN_STRING(ch->err.str, 1);
2609: }
2610: /* }}} */
2611:
2612: /* {{{ proto int curl_errno(resource ch)
2613: Return an integer containing the last error number */
2614: PHP_FUNCTION(curl_errno)
2615: {
2616: zval *zid;
2617: php_curl *ch;
2618:
2619: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zid) == FAILURE) {
2620: return;
2621: }
2622:
2623: ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl);
2624:
2625: RETURN_LONG(ch->err.no);
2626: }
2627: /* }}} */
2628:
2629: /* {{{ proto void curl_close(resource ch)
2630: Close a cURL session */
2631: PHP_FUNCTION(curl_close)
2632: {
2633: zval *zid;
2634: php_curl *ch;
2635:
2636: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zid) == FAILURE) {
2637: return;
2638: }
2639:
2640: ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl);
2641:
2642: if (ch->in_callback) {
2643: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempt to close cURL handle from a callback");
2644: return;
2645: }
2646:
2647: if (ch->uses) {
2648: ch->uses--;
2649: } else {
2650: zend_list_delete(Z_LVAL_P(zid));
2651: }
2652: }
2653: /* }}} */
2654:
2655: /* {{{ _php_curl_close()
2656: List destructor for curl handles */
2657: static void _php_curl_close_ex(php_curl *ch TSRMLS_DC)
2658: {
2659: #if PHP_CURL_DEBUG
2660: fprintf(stderr, "DTOR CALLED, ch = %x\n", ch);
2661: #endif
2662:
2663: _php_curl_verify_handlers(ch, 0 TSRMLS_CC);
1.1.1.3 misho 2664:
2665: /*
2666: * Libcurl is doing connection caching. When easy handle is cleaned up,
2667: * if the handle was previously used by the curl_multi_api, the connection
2668: * remains open un the curl multi handle is cleaned up. Some protocols are
2669: * sending content like the FTP one, and libcurl try to use the
2670: * WRITEFUNCTION or the HEADERFUNCTION. Since structures used in those
2671: * callback are freed, we need to use an other callback to which avoid
2672: * segfaults.
2673: *
2674: * Libcurl commit d021f2e8a00 fix this issue and should be part of 7.28.2
2675: */
2676: curl_easy_setopt(ch->cp, CURLOPT_HEADERFUNCTION, curl_write_nothing);
2677: curl_easy_setopt(ch->cp, CURLOPT_WRITEFUNCTION, curl_write_nothing);
2678:
1.1 misho 2679: curl_easy_cleanup(ch->cp);
2680:
2681: /* cURL destructors should be invoked only by last curl handle */
2682: if (Z_REFCOUNT_P(ch->clone) <= 1) {
2683: zend_llist_clean(&ch->to_free->str);
2684: zend_llist_clean(&ch->to_free->post);
1.1.1.4 misho 2685: zend_hash_destroy(ch->to_free->slist);
2686: efree(ch->to_free->slist);
1.1 misho 2687: efree(ch->to_free);
2688: FREE_ZVAL(ch->clone);
2689: } else {
2690: Z_DELREF_P(ch->clone);
2691: }
2692:
2693: if (ch->handlers->write->buf.len > 0) {
2694: smart_str_free(&ch->handlers->write->buf);
2695: }
2696: if (ch->handlers->write->func_name) {
2697: zval_ptr_dtor(&ch->handlers->write->func_name);
2698: }
2699: if (ch->handlers->read->func_name) {
2700: zval_ptr_dtor(&ch->handlers->read->func_name);
2701: }
2702: if (ch->handlers->write_header->func_name) {
2703: zval_ptr_dtor(&ch->handlers->write_header->func_name);
2704: }
2705: if (ch->handlers->progress->func_name) {
2706: zval_ptr_dtor(&ch->handlers->progress->func_name);
2707: }
2708: if (ch->handlers->passwd) {
2709: zval_ptr_dtor(&ch->handlers->passwd);
2710: }
2711: if (ch->handlers->std_err) {
2712: zval_ptr_dtor(&ch->handlers->std_err);
2713: }
2714: if (ch->header.str_len > 0) {
2715: efree(ch->header.str);
2716: }
2717:
2718: if (ch->handlers->write_header->stream) {
2719: zval_ptr_dtor(&ch->handlers->write_header->stream);
2720: }
2721: if (ch->handlers->write->stream) {
2722: zval_ptr_dtor(&ch->handlers->write->stream);
2723: }
2724: if (ch->handlers->read->stream) {
2725: zval_ptr_dtor(&ch->handlers->read->stream);
2726: }
2727:
2728: efree(ch->handlers->write);
2729: efree(ch->handlers->write_header);
2730: efree(ch->handlers->read);
2731: efree(ch->handlers->progress);
2732: efree(ch->handlers);
2733: efree(ch);
2734: }
2735: /* }}} */
2736:
2737: /* {{{ _php_curl_close()
2738: List destructor for curl handles */
2739: static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC)
2740: {
2741: php_curl *ch = (php_curl *) rsrc->ptr;
2742: _php_curl_close_ex(ch TSRMLS_CC);
2743: }
2744: /* }}} */
2745:
2746: #endif /* HAVE_CURL */
2747:
2748: /*
2749: * Local variables:
2750: * tab-width: 4
2751: * c-basic-offset: 4
2752: * End:
2753: * vim600: fdm=marker
2754: * vim: noet sw=4 ts=4
2755: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>