1 /*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | http://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Author: Sterling Hughes <sterling@php.net> |
14 +----------------------------------------------------------------------+
15 */
16
17 #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "php.h"
24 #include "Zend/zend_interfaces.h"
25 #include "Zend/zend_exceptions.h"
26
27 #include <stdio.h>
28 #include <string.h>
29
30 #ifdef PHP_WIN32
31 #include <winsock2.h>
32 #include <sys/types.h>
33 #endif
34
35 #include <curl/curl.h>
36 #include <curl/easy.h>
37
38 /* As of curl 7.11.1 this is no longer defined inside curl.h */
39 #ifndef HttpPost
40 #define HttpPost curl_httppost
41 #endif
42
43 /* {{{ cruft for thread safe SSL crypto locks */
44 #if defined(ZTS) && defined(HAVE_CURL_OLD_OPENSSL)
45 # if defined(HAVE_OPENSSL_CRYPTO_H)
46 # define PHP_CURL_NEED_OPENSSL_TSL
47 # include <openssl/crypto.h>
48 # else
49 # warning \
50 "libcurl was compiled with OpenSSL support, but configure could not find " \
51 "openssl/crypto.h; thus no SSL crypto locking callbacks will be set, which may " \
52 "cause random crashes on SSL requests"
53 # endif
54 #endif /* ZTS && HAVE_CURL_OLD_OPENSSL */
55 /* }}} */
56
57 #define SMART_STR_PREALLOC 4096
58
59 #include "zend_smart_str.h"
60 #include "ext/standard/info.h"
61 #include "ext/standard/file.h"
62 #include "ext/standard/url.h"
63 #include "curl_private.h"
64 #include "curl_arginfo.h"
65
66 #ifdef PHP_CURL_NEED_OPENSSL_TSL /* {{{ */
67 static MUTEX_T *php_curl_openssl_tsl = NULL;
68
69 /* Locking callbacks are no longer used since OpenSSL 1.1. Mark the functions as unused to
70 * avoid warnings due to this. */
php_curl_ssl_lock(int mode,int n,const char * file,int line)71 static ZEND_ATTRIBUTE_UNUSED void php_curl_ssl_lock(int mode, int n, const char * file, int line)
72 {
73 if (mode & CRYPTO_LOCK) {
74 tsrm_mutex_lock(php_curl_openssl_tsl[n]);
75 } else {
76 tsrm_mutex_unlock(php_curl_openssl_tsl[n]);
77 }
78 }
79
php_curl_ssl_id(void)80 static ZEND_ATTRIBUTE_UNUSED unsigned long php_curl_ssl_id(void)
81 {
82 return (unsigned long) tsrm_thread_id();
83 }
84 #endif
85 /* }}} */
86
87 #define CAAL(s, v) add_assoc_long_ex(return_value, s, sizeof(s) - 1, (zend_long) v);
88 #define CAAD(s, v) add_assoc_double_ex(return_value, s, sizeof(s) - 1, (double) v);
89 #define CAAS(s, v) add_assoc_string_ex(return_value, s, sizeof(s) - 1, (char *) (v ? v : ""));
90 #define CAASTR(s, v) add_assoc_str_ex(return_value, s, sizeof(s) - 1, \
91 v ? zend_string_copy(v) : ZSTR_EMPTY_ALLOC());
92 #define CAAZ(s, v) add_assoc_zval_ex(return_value, s, sizeof(s) -1 , (zval *) v);
93
94 #if defined(PHP_WIN32) || defined(__GNUC__)
95 # define php_curl_ret(__ret) RETVAL_FALSE; return __ret;
96 #else
97 # define php_curl_ret(__ret) RETVAL_FALSE; return;
98 #endif
99
php_curl_option_str(php_curl * ch,zend_long option,const char * str,const size_t len,zend_bool make_copy)100 static int php_curl_option_str(php_curl *ch, zend_long option, const char *str, const size_t len, zend_bool make_copy)
101 {
102 CURLcode error = CURLE_OK;
103
104 if (strlen(str) != len) {
105 zend_value_error("%s(): cURL option must not contain any null bytes", get_active_function_name());
106 return FAILURE;
107 }
108
109 if (make_copy) {
110 char *copystr;
111
112 /* Strings passed to libcurl as 'char *' arguments, are copied by the library since 7.17.0 */
113 copystr = estrndup(str, len);
114 error = curl_easy_setopt(ch->cp, option, copystr);
115 zend_llist_add_element(&ch->to_free->str, ©str);
116 } else {
117 error = curl_easy_setopt(ch->cp, option, str);
118 }
119
120 SAVE_CURL_ERROR(ch, error);
121
122 return error == CURLE_OK ? SUCCESS : FAILURE;
123 }
124
php_curl_option_url(php_curl * ch,const char * url,const size_t len)125 static int php_curl_option_url(php_curl *ch, const char *url, const size_t len) /* {{{ */
126 {
127 /* Disable file:// if open_basedir are used */
128 if (PG(open_basedir) && *PG(open_basedir)) {
129 curl_easy_setopt(ch->cp, CURLOPT_PROTOCOLS, CURLPROTO_ALL & ~CURLPROTO_FILE);
130 }
131
132 #if LIBCURL_VERSION_NUM > 0x073800 && defined(PHP_WIN32)
133 if (len > sizeof("file://") - 1 && '/' != url[sizeof("file://") - 1] && !strncmp("file://", url, sizeof("file://") - 1) && len < MAXPATHLEN - 2) {
134 char _tmp[MAXPATHLEN] = {0};
135
136 memmove(_tmp, "file:///", sizeof("file:///") - 1);
137 memmove(_tmp + sizeof("file:///") - 1, url + sizeof("file://") - 1, len - sizeof("file://") + 1);
138
139 return php_curl_option_str(ch, CURLOPT_URL, _tmp, len + 1, 0);
140 }
141 #endif
142
143 return php_curl_option_str(ch, CURLOPT_URL, url, len, 0);
144 }
145 /* }}} */
146
_php_curl_verify_handlers(php_curl * ch,int reporterror)147 void _php_curl_verify_handlers(php_curl *ch, int reporterror) /* {{{ */
148 {
149 php_stream *stream;
150
151 ZEND_ASSERT(ch && ch->handlers);
152
153 if (!Z_ISUNDEF(ch->handlers->std_err)) {
154 stream = (php_stream *)zend_fetch_resource2_ex(&ch->handlers->std_err, NULL, php_file_le_stream(), php_file_le_pstream());
155 if (stream == NULL) {
156 if (reporterror) {
157 php_error_docref(NULL, E_WARNING, "CURLOPT_STDERR resource has gone away, resetting to stderr");
158 }
159 zval_ptr_dtor(&ch->handlers->std_err);
160 ZVAL_UNDEF(&ch->handlers->std_err);
161
162 curl_easy_setopt(ch->cp, CURLOPT_STDERR, stderr);
163 }
164 }
165 if (ch->handlers->read && !Z_ISUNDEF(ch->handlers->read->stream)) {
166 stream = (php_stream *)zend_fetch_resource2_ex(&ch->handlers->read->stream, NULL, php_file_le_stream(), php_file_le_pstream());
167 if (stream == NULL) {
168 if (reporterror) {
169 php_error_docref(NULL, E_WARNING, "CURLOPT_INFILE resource has gone away, resetting to default");
170 }
171 zval_ptr_dtor(&ch->handlers->read->stream);
172 ZVAL_UNDEF(&ch->handlers->read->stream);
173 ch->handlers->read->res = NULL;
174 ch->handlers->read->fp = 0;
175
176 curl_easy_setopt(ch->cp, CURLOPT_INFILE, (void *) ch);
177 }
178 }
179 if (ch->handlers->write_header && !Z_ISUNDEF(ch->handlers->write_header->stream)) {
180 stream = (php_stream *)zend_fetch_resource2_ex(&ch->handlers->write_header->stream, NULL, php_file_le_stream(), php_file_le_pstream());
181 if (stream == NULL) {
182 if (reporterror) {
183 php_error_docref(NULL, E_WARNING, "CURLOPT_WRITEHEADER resource has gone away, resetting to default");
184 }
185 zval_ptr_dtor(&ch->handlers->write_header->stream);
186 ZVAL_UNDEF(&ch->handlers->write_header->stream);
187 ch->handlers->write_header->fp = 0;
188
189 ch->handlers->write_header->method = PHP_CURL_IGNORE;
190 curl_easy_setopt(ch->cp, CURLOPT_WRITEHEADER, (void *) ch);
191 }
192 }
193 if (ch->handlers->write && !Z_ISUNDEF(ch->handlers->write->stream)) {
194 stream = (php_stream *)zend_fetch_resource2_ex(&ch->handlers->write->stream, NULL, php_file_le_stream(), php_file_le_pstream());
195 if (stream == NULL) {
196 if (reporterror) {
197 php_error_docref(NULL, E_WARNING, "CURLOPT_FILE resource has gone away, resetting to default");
198 }
199 zval_ptr_dtor(&ch->handlers->write->stream);
200 ZVAL_UNDEF(&ch->handlers->write->stream);
201 ch->handlers->write->fp = 0;
202
203 ch->handlers->write->method = PHP_CURL_STDOUT;
204 curl_easy_setopt(ch->cp, CURLOPT_FILE, (void *) ch);
205 }
206 }
207 return;
208 }
209 /* }}} */
210
211 /* {{{ curl_module_entry */
212 zend_module_entry curl_module_entry = {
213 STANDARD_MODULE_HEADER,
214 "curl",
215 ext_functions,
216 PHP_MINIT(curl),
217 PHP_MSHUTDOWN(curl),
218 NULL,
219 NULL,
220 PHP_MINFO(curl),
221 PHP_CURL_VERSION,
222 STANDARD_MODULE_PROPERTIES
223 };
224 /* }}} */
225
226 #ifdef COMPILE_DL_CURL
227 ZEND_GET_MODULE (curl)
228 #endif
229
230 /* CurlHandle class */
231
232 zend_class_entry *curl_ce;
233 zend_class_entry *curl_share_ce;
234 static zend_object_handlers curl_object_handlers;
235
236 static zend_object *curl_create_object(zend_class_entry *class_type);
237 static void curl_free_obj(zend_object *object);
238 static HashTable *curl_get_gc(zend_object *object, zval **table, int *n);
239 static zend_function *curl_get_constructor(zend_object *object);
240 static zend_object *curl_clone_obj(zend_object *object);
241 php_curl *init_curl_handle_into_zval(zval *curl);
242 static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields);
243
244 /* {{{ PHP_INI_BEGIN */
245 PHP_INI_BEGIN()
246 PHP_INI_ENTRY("curl.cainfo", "", PHP_INI_SYSTEM, NULL)
PHP_INI_END()247 PHP_INI_END()
248 /* }}} */
249
250 /* {{{ PHP_MINFO_FUNCTION */
251 PHP_MINFO_FUNCTION(curl)
252 {
253 curl_version_info_data *d;
254 char **p;
255 char str[1024];
256 size_t n = 0;
257
258 d = curl_version_info(CURLVERSION_NOW);
259 php_info_print_table_start();
260 php_info_print_table_row(2, "cURL support", "enabled");
261 php_info_print_table_row(2, "cURL Information", d->version);
262 sprintf(str, "%d", d->age);
263 php_info_print_table_row(2, "Age", str);
264
265 /* To update on each new cURL release using src/main.c in cURL sources */
266 if (d->features) {
267 struct feat {
268 const char *name;
269 int bitmask;
270 };
271
272 unsigned int i;
273
274 static const struct feat feats[] = {
275 {"AsynchDNS", CURL_VERSION_ASYNCHDNS},
276 {"CharConv", CURL_VERSION_CONV},
277 {"Debug", CURL_VERSION_DEBUG},
278 {"GSS-Negotiate", CURL_VERSION_GSSNEGOTIATE},
279 {"IDN", CURL_VERSION_IDN},
280 {"IPv6", CURL_VERSION_IPV6},
281 {"krb4", CURL_VERSION_KERBEROS4},
282 {"Largefile", CURL_VERSION_LARGEFILE},
283 {"libz", CURL_VERSION_LIBZ},
284 {"NTLM", CURL_VERSION_NTLM},
285 {"NTLMWB", CURL_VERSION_NTLM_WB},
286 {"SPNEGO", CURL_VERSION_SPNEGO},
287 {"SSL", CURL_VERSION_SSL},
288 {"SSPI", CURL_VERSION_SSPI},
289 {"TLS-SRP", CURL_VERSION_TLSAUTH_SRP},
290 #if LIBCURL_VERSION_NUM >= 0x072100 /* 7.33.0 */
291 {"HTTP2", CURL_VERSION_HTTP2},
292 #endif
293 #if LIBCURL_VERSION_NUM >= 0x072600 /* 7.38.0 */
294 {"GSSAPI", CURL_VERSION_GSSAPI},
295 #endif
296 #if LIBCURL_VERSION_NUM >= 0x072800 /* 7.40.0 */
297 {"KERBEROS5", CURL_VERSION_KERBEROS5},
298 {"UNIX_SOCKETS", CURL_VERSION_UNIX_SOCKETS},
299 #endif
300 #if LIBCURL_VERSION_NUM >= 0x072f00 /* 7.47.0 */
301 {"PSL", CURL_VERSION_PSL},
302 #endif
303 #if LIBCURL_VERSION_NUM >= 0x073400 /* 7.52.0 */
304 {"HTTPS_PROXY", CURL_VERSION_HTTPS_PROXY},
305 #endif
306 #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
307 {"MULTI_SSL", CURL_VERSION_MULTI_SSL},
308 #endif
309 #if LIBCURL_VERSION_NUM >= 0x073900 /* 7.57.0 */
310 {"BROTLI", CURL_VERSION_BROTLI},
311 #endif
312 {NULL, 0}
313 };
314
315 php_info_print_table_row(1, "Features");
316 for(i=0; i<sizeof(feats)/sizeof(feats[0]); i++) {
317 if (feats[i].name) {
318 php_info_print_table_row(2, feats[i].name, d->features & feats[i].bitmask ? "Yes" : "No");
319 }
320 }
321 }
322
323 n = 0;
324 p = (char **) d->protocols;
325 while (*p != NULL) {
326 n += sprintf(str + n, "%s%s", *p, *(p + 1) != NULL ? ", " : "");
327 p++;
328 }
329 php_info_print_table_row(2, "Protocols", str);
330
331 php_info_print_table_row(2, "Host", d->host);
332
333 if (d->ssl_version) {
334 php_info_print_table_row(2, "SSL Version", d->ssl_version);
335 }
336
337 if (d->libz_version) {
338 php_info_print_table_row(2, "ZLib Version", d->libz_version);
339 }
340
341 #if defined(CURLVERSION_SECOND) && CURLVERSION_NOW >= CURLVERSION_SECOND
342 if (d->ares) {
343 php_info_print_table_row(2, "ZLib Version", d->ares);
344 }
345 #endif
346
347 #if defined(CURLVERSION_THIRD) && CURLVERSION_NOW >= CURLVERSION_THIRD
348 if (d->libidn) {
349 php_info_print_table_row(2, "libIDN Version", d->libidn);
350 }
351 #endif
352
353 if (d->iconv_ver_num) {
354 php_info_print_table_row(2, "IconV Version", d->iconv_ver_num);
355 }
356
357 if (d->libssh_version) {
358 php_info_print_table_row(2, "libSSH Version", d->libssh_version);
359 }
360
361 php_info_print_table_end();
362
363 DISPLAY_INI_ENTRIES();
364 }
365 /* }}} */
366
367 #define REGISTER_CURL_CONSTANT(__c) REGISTER_LONG_CONSTANT(#__c, __c, CONST_CS | CONST_PERSISTENT)
368
369 /* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(curl)370 PHP_MINIT_FUNCTION(curl)
371 {
372 REGISTER_INI_ENTRIES();
373
374 /* See http://curl.haxx.se/lxr/source/docs/libcurl/symbols-in-versions
375 or curl src/docs/libcurl/symbols-in-versions for a (almost) complete list
376 of options and which version they were introduced */
377
378 /* Constants for curl_setopt() */
379 REGISTER_CURL_CONSTANT(CURLOPT_AUTOREFERER);
380 REGISTER_CURL_CONSTANT(CURLOPT_BINARYTRANSFER);
381 REGISTER_CURL_CONSTANT(CURLOPT_BUFFERSIZE);
382 REGISTER_CURL_CONSTANT(CURLOPT_CAINFO);
383 REGISTER_CURL_CONSTANT(CURLOPT_CAPATH);
384 REGISTER_CURL_CONSTANT(CURLOPT_CONNECTTIMEOUT);
385 REGISTER_CURL_CONSTANT(CURLOPT_COOKIE);
386 REGISTER_CURL_CONSTANT(CURLOPT_COOKIEFILE);
387 REGISTER_CURL_CONSTANT(CURLOPT_COOKIEJAR);
388 REGISTER_CURL_CONSTANT(CURLOPT_COOKIESESSION);
389 REGISTER_CURL_CONSTANT(CURLOPT_CRLF);
390 REGISTER_CURL_CONSTANT(CURLOPT_CUSTOMREQUEST);
391 REGISTER_CURL_CONSTANT(CURLOPT_DNS_CACHE_TIMEOUT);
392 REGISTER_CURL_CONSTANT(CURLOPT_DNS_USE_GLOBAL_CACHE);
393 REGISTER_CURL_CONSTANT(CURLOPT_EGDSOCKET);
394 REGISTER_CURL_CONSTANT(CURLOPT_ENCODING);
395 REGISTER_CURL_CONSTANT(CURLOPT_FAILONERROR);
396 REGISTER_CURL_CONSTANT(CURLOPT_FILE);
397 REGISTER_CURL_CONSTANT(CURLOPT_FILETIME);
398 REGISTER_CURL_CONSTANT(CURLOPT_FOLLOWLOCATION);
399 REGISTER_CURL_CONSTANT(CURLOPT_FORBID_REUSE);
400 REGISTER_CURL_CONSTANT(CURLOPT_FRESH_CONNECT);
401 REGISTER_CURL_CONSTANT(CURLOPT_FTPAPPEND);
402 REGISTER_CURL_CONSTANT(CURLOPT_FTPLISTONLY);
403 REGISTER_CURL_CONSTANT(CURLOPT_FTPPORT);
404 REGISTER_CURL_CONSTANT(CURLOPT_FTP_USE_EPRT);
405 REGISTER_CURL_CONSTANT(CURLOPT_FTP_USE_EPSV);
406 REGISTER_CURL_CONSTANT(CURLOPT_HEADER);
407 REGISTER_CURL_CONSTANT(CURLOPT_HEADERFUNCTION);
408 REGISTER_CURL_CONSTANT(CURLOPT_HTTP200ALIASES);
409 REGISTER_CURL_CONSTANT(CURLOPT_HTTPGET);
410 REGISTER_CURL_CONSTANT(CURLOPT_HTTPHEADER);
411 REGISTER_CURL_CONSTANT(CURLOPT_HTTPPROXYTUNNEL);
412 REGISTER_CURL_CONSTANT(CURLOPT_HTTP_VERSION);
413 REGISTER_CURL_CONSTANT(CURLOPT_INFILE);
414 REGISTER_CURL_CONSTANT(CURLOPT_INFILESIZE);
415 REGISTER_CURL_CONSTANT(CURLOPT_INTERFACE);
416 REGISTER_CURL_CONSTANT(CURLOPT_KRB4LEVEL);
417 REGISTER_CURL_CONSTANT(CURLOPT_LOW_SPEED_LIMIT);
418 REGISTER_CURL_CONSTANT(CURLOPT_LOW_SPEED_TIME);
419 REGISTER_CURL_CONSTANT(CURLOPT_MAXCONNECTS);
420 REGISTER_CURL_CONSTANT(CURLOPT_MAXREDIRS);
421 REGISTER_CURL_CONSTANT(CURLOPT_NETRC);
422 REGISTER_CURL_CONSTANT(CURLOPT_NOBODY);
423 REGISTER_CURL_CONSTANT(CURLOPT_NOPROGRESS);
424 REGISTER_CURL_CONSTANT(CURLOPT_NOSIGNAL);
425 REGISTER_CURL_CONSTANT(CURLOPT_PORT);
426 REGISTER_CURL_CONSTANT(CURLOPT_POST);
427 REGISTER_CURL_CONSTANT(CURLOPT_POSTFIELDS);
428 REGISTER_CURL_CONSTANT(CURLOPT_POSTQUOTE);
429 REGISTER_CURL_CONSTANT(CURLOPT_PREQUOTE);
430 REGISTER_CURL_CONSTANT(CURLOPT_PRIVATE);
431 REGISTER_CURL_CONSTANT(CURLOPT_PROGRESSFUNCTION);
432 REGISTER_CURL_CONSTANT(CURLOPT_PROXY);
433 REGISTER_CURL_CONSTANT(CURLOPT_PROXYPORT);
434 REGISTER_CURL_CONSTANT(CURLOPT_PROXYTYPE);
435 REGISTER_CURL_CONSTANT(CURLOPT_PROXYUSERPWD);
436 REGISTER_CURL_CONSTANT(CURLOPT_PUT);
437 REGISTER_CURL_CONSTANT(CURLOPT_QUOTE);
438 REGISTER_CURL_CONSTANT(CURLOPT_RANDOM_FILE);
439 REGISTER_CURL_CONSTANT(CURLOPT_RANGE);
440 REGISTER_CURL_CONSTANT(CURLOPT_READDATA);
441 REGISTER_CURL_CONSTANT(CURLOPT_READFUNCTION);
442 REGISTER_CURL_CONSTANT(CURLOPT_REFERER);
443 REGISTER_CURL_CONSTANT(CURLOPT_RESUME_FROM);
444 REGISTER_CURL_CONSTANT(CURLOPT_RETURNTRANSFER);
445 REGISTER_CURL_CONSTANT(CURLOPT_SHARE);
446 REGISTER_CURL_CONSTANT(CURLOPT_SSLCERT);
447 REGISTER_CURL_CONSTANT(CURLOPT_SSLCERTPASSWD);
448 REGISTER_CURL_CONSTANT(CURLOPT_SSLCERTTYPE);
449 REGISTER_CURL_CONSTANT(CURLOPT_SSLENGINE);
450 REGISTER_CURL_CONSTANT(CURLOPT_SSLENGINE_DEFAULT);
451 REGISTER_CURL_CONSTANT(CURLOPT_SSLKEY);
452 REGISTER_CURL_CONSTANT(CURLOPT_SSLKEYPASSWD);
453 REGISTER_CURL_CONSTANT(CURLOPT_SSLKEYTYPE);
454 REGISTER_CURL_CONSTANT(CURLOPT_SSLVERSION);
455 REGISTER_CURL_CONSTANT(CURLOPT_SSL_CIPHER_LIST);
456 REGISTER_CURL_CONSTANT(CURLOPT_SSL_VERIFYHOST);
457 REGISTER_CURL_CONSTANT(CURLOPT_SSL_VERIFYPEER);
458 REGISTER_CURL_CONSTANT(CURLOPT_STDERR);
459 REGISTER_CURL_CONSTANT(CURLOPT_TELNETOPTIONS);
460 REGISTER_CURL_CONSTANT(CURLOPT_TIMECONDITION);
461 REGISTER_CURL_CONSTANT(CURLOPT_TIMEOUT);
462 REGISTER_CURL_CONSTANT(CURLOPT_TIMEVALUE);
463 REGISTER_CURL_CONSTANT(CURLOPT_TRANSFERTEXT);
464 REGISTER_CURL_CONSTANT(CURLOPT_UNRESTRICTED_AUTH);
465 REGISTER_CURL_CONSTANT(CURLOPT_UPLOAD);
466 REGISTER_CURL_CONSTANT(CURLOPT_URL);
467 REGISTER_CURL_CONSTANT(CURLOPT_USERAGENT);
468 REGISTER_CURL_CONSTANT(CURLOPT_USERPWD);
469 REGISTER_CURL_CONSTANT(CURLOPT_VERBOSE);
470 REGISTER_CURL_CONSTANT(CURLOPT_WRITEFUNCTION);
471 REGISTER_CURL_CONSTANT(CURLOPT_WRITEHEADER);
472
473 /* */
474 REGISTER_CURL_CONSTANT(CURLE_ABORTED_BY_CALLBACK);
475 REGISTER_CURL_CONSTANT(CURLE_BAD_CALLING_ORDER);
476 REGISTER_CURL_CONSTANT(CURLE_BAD_CONTENT_ENCODING);
477 REGISTER_CURL_CONSTANT(CURLE_BAD_DOWNLOAD_RESUME);
478 REGISTER_CURL_CONSTANT(CURLE_BAD_FUNCTION_ARGUMENT);
479 REGISTER_CURL_CONSTANT(CURLE_BAD_PASSWORD_ENTERED);
480 REGISTER_CURL_CONSTANT(CURLE_COULDNT_CONNECT);
481 REGISTER_CURL_CONSTANT(CURLE_COULDNT_RESOLVE_HOST);
482 REGISTER_CURL_CONSTANT(CURLE_COULDNT_RESOLVE_PROXY);
483 REGISTER_CURL_CONSTANT(CURLE_FAILED_INIT);
484 REGISTER_CURL_CONSTANT(CURLE_FILE_COULDNT_READ_FILE);
485 REGISTER_CURL_CONSTANT(CURLE_FTP_ACCESS_DENIED);
486 REGISTER_CURL_CONSTANT(CURLE_FTP_BAD_DOWNLOAD_RESUME);
487 REGISTER_CURL_CONSTANT(CURLE_FTP_CANT_GET_HOST);
488 REGISTER_CURL_CONSTANT(CURLE_FTP_CANT_RECONNECT);
489 REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_GET_SIZE);
490 REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_RETR_FILE);
491 REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_SET_ASCII);
492 REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_SET_BINARY);
493 REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_STOR_FILE);
494 REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_USE_REST);
495 REGISTER_CURL_CONSTANT(CURLE_FTP_PARTIAL_FILE);
496 REGISTER_CURL_CONSTANT(CURLE_FTP_PORT_FAILED);
497 REGISTER_CURL_CONSTANT(CURLE_FTP_QUOTE_ERROR);
498 REGISTER_CURL_CONSTANT(CURLE_FTP_USER_PASSWORD_INCORRECT);
499 REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_227_FORMAT);
500 REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_PASS_REPLY);
501 REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_PASV_REPLY);
502 REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_SERVER_REPLY);
503 REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_USER_REPLY);
504 REGISTER_CURL_CONSTANT(CURLE_FTP_WRITE_ERROR);
505 REGISTER_CURL_CONSTANT(CURLE_FUNCTION_NOT_FOUND);
506 REGISTER_CURL_CONSTANT(CURLE_GOT_NOTHING);
507 REGISTER_CURL_CONSTANT(CURLE_HTTP_NOT_FOUND);
508 REGISTER_CURL_CONSTANT(CURLE_HTTP_PORT_FAILED);
509 REGISTER_CURL_CONSTANT(CURLE_HTTP_POST_ERROR);
510 REGISTER_CURL_CONSTANT(CURLE_HTTP_RANGE_ERROR);
511 REGISTER_CURL_CONSTANT(CURLE_HTTP_RETURNED_ERROR);
512 REGISTER_CURL_CONSTANT(CURLE_LDAP_CANNOT_BIND);
513 REGISTER_CURL_CONSTANT(CURLE_LDAP_SEARCH_FAILED);
514 REGISTER_CURL_CONSTANT(CURLE_LIBRARY_NOT_FOUND);
515 REGISTER_CURL_CONSTANT(CURLE_MALFORMAT_USER);
516 REGISTER_CURL_CONSTANT(CURLE_OBSOLETE);
517 REGISTER_CURL_CONSTANT(CURLE_OK);
518 REGISTER_CURL_CONSTANT(CURLE_OPERATION_TIMEDOUT);
519 REGISTER_CURL_CONSTANT(CURLE_OPERATION_TIMEOUTED);
520 REGISTER_CURL_CONSTANT(CURLE_OUT_OF_MEMORY);
521 REGISTER_CURL_CONSTANT(CURLE_PARTIAL_FILE);
522 REGISTER_CURL_CONSTANT(CURLE_READ_ERROR);
523 REGISTER_CURL_CONSTANT(CURLE_RECV_ERROR);
524 REGISTER_CURL_CONSTANT(CURLE_SEND_ERROR);
525 REGISTER_CURL_CONSTANT(CURLE_SHARE_IN_USE);
526 REGISTER_CURL_CONSTANT(CURLE_SSL_CACERT);
527 REGISTER_CURL_CONSTANT(CURLE_SSL_CERTPROBLEM);
528 REGISTER_CURL_CONSTANT(CURLE_SSL_CIPHER);
529 REGISTER_CURL_CONSTANT(CURLE_SSL_CONNECT_ERROR);
530 REGISTER_CURL_CONSTANT(CURLE_SSL_ENGINE_NOTFOUND);
531 REGISTER_CURL_CONSTANT(CURLE_SSL_ENGINE_SETFAILED);
532 REGISTER_CURL_CONSTANT(CURLE_SSL_PEER_CERTIFICATE);
533 #if LIBCURL_VERSION_NUM >= 0x072700 /* Available since 7.39.0 */
534 REGISTER_CURL_CONSTANT(CURLE_SSL_PINNEDPUBKEYNOTMATCH);
535 #endif
536 REGISTER_CURL_CONSTANT(CURLE_TELNET_OPTION_SYNTAX);
537 REGISTER_CURL_CONSTANT(CURLE_TOO_MANY_REDIRECTS);
538 REGISTER_CURL_CONSTANT(CURLE_UNKNOWN_TELNET_OPTION);
539 REGISTER_CURL_CONSTANT(CURLE_UNSUPPORTED_PROTOCOL);
540 REGISTER_CURL_CONSTANT(CURLE_URL_MALFORMAT);
541 REGISTER_CURL_CONSTANT(CURLE_URL_MALFORMAT_USER);
542 REGISTER_CURL_CONSTANT(CURLE_WRITE_ERROR);
543
544 /* cURL info constants */
545 REGISTER_CURL_CONSTANT(CURLINFO_CONNECT_TIME);
546 REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_LENGTH_DOWNLOAD);
547 REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_LENGTH_UPLOAD);
548 REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_TYPE);
549 REGISTER_CURL_CONSTANT(CURLINFO_EFFECTIVE_URL);
550 REGISTER_CURL_CONSTANT(CURLINFO_FILETIME);
551 REGISTER_CURL_CONSTANT(CURLINFO_HEADER_OUT);
552 REGISTER_CURL_CONSTANT(CURLINFO_HEADER_SIZE);
553 REGISTER_CURL_CONSTANT(CURLINFO_HTTP_CODE);
554 REGISTER_CURL_CONSTANT(CURLINFO_LASTONE);
555 REGISTER_CURL_CONSTANT(CURLINFO_NAMELOOKUP_TIME);
556 REGISTER_CURL_CONSTANT(CURLINFO_PRETRANSFER_TIME);
557 REGISTER_CURL_CONSTANT(CURLINFO_PRIVATE);
558 REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_COUNT);
559 REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_TIME);
560 REGISTER_CURL_CONSTANT(CURLINFO_REQUEST_SIZE);
561 REGISTER_CURL_CONSTANT(CURLINFO_SIZE_DOWNLOAD);
562 REGISTER_CURL_CONSTANT(CURLINFO_SIZE_UPLOAD);
563 REGISTER_CURL_CONSTANT(CURLINFO_SPEED_DOWNLOAD);
564 REGISTER_CURL_CONSTANT(CURLINFO_SPEED_UPLOAD);
565 REGISTER_CURL_CONSTANT(CURLINFO_SSL_VERIFYRESULT);
566 REGISTER_CURL_CONSTANT(CURLINFO_STARTTRANSFER_TIME);
567 REGISTER_CURL_CONSTANT(CURLINFO_TOTAL_TIME);
568
569 /* Other */
570 REGISTER_CURL_CONSTANT(CURLMSG_DONE);
571 REGISTER_CURL_CONSTANT(CURLVERSION_NOW);
572
573 /* Curl Multi Constants */
574 REGISTER_CURL_CONSTANT(CURLM_BAD_EASY_HANDLE);
575 REGISTER_CURL_CONSTANT(CURLM_BAD_HANDLE);
576 REGISTER_CURL_CONSTANT(CURLM_CALL_MULTI_PERFORM);
577 REGISTER_CURL_CONSTANT(CURLM_INTERNAL_ERROR);
578 REGISTER_CURL_CONSTANT(CURLM_OK);
579 REGISTER_CURL_CONSTANT(CURLM_OUT_OF_MEMORY);
580 #if LIBCURL_VERSION_NUM >= 0x072001 /* Available since 7.32.1 */
581 REGISTER_CURL_CONSTANT(CURLM_ADDED_ALREADY);
582 #endif
583
584 /* Curl proxy constants */
585 REGISTER_CURL_CONSTANT(CURLPROXY_HTTP);
586 REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS4);
587 REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS5);
588
589 /* Curl Share constants */
590 REGISTER_CURL_CONSTANT(CURLSHOPT_NONE);
591 REGISTER_CURL_CONSTANT(CURLSHOPT_SHARE);
592 REGISTER_CURL_CONSTANT(CURLSHOPT_UNSHARE);
593
594 /* Curl Http Version constants (CURLOPT_HTTP_VERSION) */
595 REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_1_0);
596 REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_1_1);
597 REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_NONE);
598
599 /* Curl Lock constants */
600 REGISTER_CURL_CONSTANT(CURL_LOCK_DATA_COOKIE);
601 REGISTER_CURL_CONSTANT(CURL_LOCK_DATA_DNS);
602 REGISTER_CURL_CONSTANT(CURL_LOCK_DATA_SSL_SESSION);
603
604 /* Curl NETRC constants (CURLOPT_NETRC) */
605 REGISTER_CURL_CONSTANT(CURL_NETRC_IGNORED);
606 REGISTER_CURL_CONSTANT(CURL_NETRC_OPTIONAL);
607 REGISTER_CURL_CONSTANT(CURL_NETRC_REQUIRED);
608
609 /* Curl SSL Version constants (CURLOPT_SSLVERSION) */
610 REGISTER_CURL_CONSTANT(CURL_SSLVERSION_DEFAULT);
611 REGISTER_CURL_CONSTANT(CURL_SSLVERSION_SSLv2);
612 REGISTER_CURL_CONSTANT(CURL_SSLVERSION_SSLv3);
613 REGISTER_CURL_CONSTANT(CURL_SSLVERSION_TLSv1);
614
615 /* Curl TIMECOND constants (CURLOPT_TIMECONDITION) */
616 REGISTER_CURL_CONSTANT(CURL_TIMECOND_IFMODSINCE);
617 REGISTER_CURL_CONSTANT(CURL_TIMECOND_IFUNMODSINCE);
618 REGISTER_CURL_CONSTANT(CURL_TIMECOND_LASTMOD);
619 REGISTER_CURL_CONSTANT(CURL_TIMECOND_NONE);
620
621 /* Curl version constants */
622 REGISTER_CURL_CONSTANT(CURL_VERSION_ASYNCHDNS);
623 REGISTER_CURL_CONSTANT(CURL_VERSION_CONV);
624 REGISTER_CURL_CONSTANT(CURL_VERSION_DEBUG);
625 REGISTER_CURL_CONSTANT(CURL_VERSION_GSSNEGOTIATE);
626 REGISTER_CURL_CONSTANT(CURL_VERSION_IDN);
627 REGISTER_CURL_CONSTANT(CURL_VERSION_IPV6);
628 REGISTER_CURL_CONSTANT(CURL_VERSION_KERBEROS4);
629 REGISTER_CURL_CONSTANT(CURL_VERSION_LARGEFILE);
630 REGISTER_CURL_CONSTANT(CURL_VERSION_LIBZ);
631 REGISTER_CURL_CONSTANT(CURL_VERSION_NTLM);
632 REGISTER_CURL_CONSTANT(CURL_VERSION_SPNEGO);
633 REGISTER_CURL_CONSTANT(CURL_VERSION_SSL);
634 REGISTER_CURL_CONSTANT(CURL_VERSION_SSPI);
635
636 /* Available since 7.10.6 */
637 REGISTER_CURL_CONSTANT(CURLOPT_HTTPAUTH);
638 /* http authentication options */
639 REGISTER_CURL_CONSTANT(CURLAUTH_ANY);
640 REGISTER_CURL_CONSTANT(CURLAUTH_ANYSAFE);
641 REGISTER_CURL_CONSTANT(CURLAUTH_BASIC);
642 REGISTER_CURL_CONSTANT(CURLAUTH_DIGEST);
643 REGISTER_CURL_CONSTANT(CURLAUTH_GSSNEGOTIATE);
644 REGISTER_CURL_CONSTANT(CURLAUTH_NONE);
645 REGISTER_CURL_CONSTANT(CURLAUTH_NTLM);
646
647 /* Available since 7.10.7 */
648 REGISTER_CURL_CONSTANT(CURLINFO_HTTP_CONNECTCODE);
649 REGISTER_CURL_CONSTANT(CURLOPT_FTP_CREATE_MISSING_DIRS);
650 REGISTER_CURL_CONSTANT(CURLOPT_PROXYAUTH);
651
652 /* Available since 7.10.8 */
653 REGISTER_CURL_CONSTANT(CURLE_FILESIZE_EXCEEDED);
654 REGISTER_CURL_CONSTANT(CURLE_LDAP_INVALID_URL);
655 REGISTER_CURL_CONSTANT(CURLINFO_HTTPAUTH_AVAIL);
656 REGISTER_CURL_CONSTANT(CURLINFO_RESPONSE_CODE);
657 REGISTER_CURL_CONSTANT(CURLINFO_PROXYAUTH_AVAIL);
658 REGISTER_CURL_CONSTANT(CURLOPT_FTP_RESPONSE_TIMEOUT);
659 REGISTER_CURL_CONSTANT(CURLOPT_IPRESOLVE);
660 REGISTER_CURL_CONSTANT(CURLOPT_MAXFILESIZE);
661 REGISTER_CURL_CONSTANT(CURL_IPRESOLVE_V4);
662 REGISTER_CURL_CONSTANT(CURL_IPRESOLVE_V6);
663 REGISTER_CURL_CONSTANT(CURL_IPRESOLVE_WHATEVER);
664
665 /* Available since 7.11.0 */
666 REGISTER_CURL_CONSTANT(CURLE_FTP_SSL_FAILED);
667 REGISTER_CURL_CONSTANT(CURLFTPSSL_ALL);
668 REGISTER_CURL_CONSTANT(CURLFTPSSL_CONTROL);
669 REGISTER_CURL_CONSTANT(CURLFTPSSL_NONE);
670 REGISTER_CURL_CONSTANT(CURLFTPSSL_TRY);
671 REGISTER_CURL_CONSTANT(CURLOPT_FTP_SSL);
672 REGISTER_CURL_CONSTANT(CURLOPT_NETRC_FILE);
673
674 /* Available since 7.11.2 */
675 REGISTER_CURL_CONSTANT(CURLOPT_TCP_NODELAY);
676
677 /* Available since 7.12.2 */
678 REGISTER_CURL_CONSTANT(CURLFTPAUTH_DEFAULT);
679 REGISTER_CURL_CONSTANT(CURLFTPAUTH_SSL);
680 REGISTER_CURL_CONSTANT(CURLFTPAUTH_TLS);
681 REGISTER_CURL_CONSTANT(CURLOPT_FTPSSLAUTH);
682
683 /* Available since 7.13.0 */
684 REGISTER_CURL_CONSTANT(CURLOPT_FTP_ACCOUNT);
685
686 /* Available since 7.12.2 */
687 REGISTER_CURL_CONSTANT(CURLINFO_OS_ERRNO);
688
689 /* Available since 7.12.3 */
690 REGISTER_CURL_CONSTANT(CURLINFO_NUM_CONNECTS);
691 REGISTER_CURL_CONSTANT(CURLINFO_SSL_ENGINES);
692
693 /* Available since 7.14.1 */
694 REGISTER_CURL_CONSTANT(CURLINFO_COOKIELIST);
695 REGISTER_CURL_CONSTANT(CURLOPT_COOKIELIST);
696 REGISTER_CURL_CONSTANT(CURLOPT_IGNORE_CONTENT_LENGTH);
697
698 /* Available since 7.15.0 */
699 REGISTER_CURL_CONSTANT(CURLOPT_FTP_SKIP_PASV_IP);
700
701 /* Available since 7.15.1 */
702 REGISTER_CURL_CONSTANT(CURLOPT_FTP_FILEMETHOD);
703
704 /* Available since 7.15.2 */
705 REGISTER_CURL_CONSTANT(CURLOPT_CONNECT_ONLY);
706 REGISTER_CURL_CONSTANT(CURLOPT_LOCALPORT);
707 REGISTER_CURL_CONSTANT(CURLOPT_LOCALPORTRANGE);
708
709 /* Available since 7.15.3 */
710 REGISTER_CURL_CONSTANT(CURLFTPMETHOD_MULTICWD);
711 REGISTER_CURL_CONSTANT(CURLFTPMETHOD_NOCWD);
712 REGISTER_CURL_CONSTANT(CURLFTPMETHOD_SINGLECWD);
713
714 /* Available since 7.15.4 */
715 REGISTER_CURL_CONSTANT(CURLINFO_FTP_ENTRY_PATH);
716
717 /* Available since 7.15.5 */
718 REGISTER_CURL_CONSTANT(CURLOPT_FTP_ALTERNATIVE_TO_USER);
719 REGISTER_CURL_CONSTANT(CURLOPT_MAX_RECV_SPEED_LARGE);
720 REGISTER_CURL_CONSTANT(CURLOPT_MAX_SEND_SPEED_LARGE);
721
722 /* Available since 7.16.0 */
723 REGISTER_CURL_CONSTANT(CURLE_SSL_CACERT_BADFILE);
724 REGISTER_CURL_CONSTANT(CURLOPT_SSL_SESSIONID_CACHE);
725 REGISTER_CURL_CONSTANT(CURLMOPT_PIPELINING);
726
727 /* Available since 7.16.1 */
728 REGISTER_CURL_CONSTANT(CURLE_SSH);
729 REGISTER_CURL_CONSTANT(CURLOPT_FTP_SSL_CCC);
730 REGISTER_CURL_CONSTANT(CURLOPT_SSH_AUTH_TYPES);
731 REGISTER_CURL_CONSTANT(CURLOPT_SSH_PRIVATE_KEYFILE);
732 REGISTER_CURL_CONSTANT(CURLOPT_SSH_PUBLIC_KEYFILE);
733 REGISTER_CURL_CONSTANT(CURLFTPSSL_CCC_ACTIVE);
734 REGISTER_CURL_CONSTANT(CURLFTPSSL_CCC_NONE);
735 REGISTER_CURL_CONSTANT(CURLFTPSSL_CCC_PASSIVE);
736
737 /* Available since 7.16.2 */
738 REGISTER_CURL_CONSTANT(CURLOPT_CONNECTTIMEOUT_MS);
739 REGISTER_CURL_CONSTANT(CURLOPT_HTTP_CONTENT_DECODING);
740 REGISTER_CURL_CONSTANT(CURLOPT_HTTP_TRANSFER_DECODING);
741 REGISTER_CURL_CONSTANT(CURLOPT_TIMEOUT_MS);
742
743 /* Available since 7.16.3 */
744 REGISTER_CURL_CONSTANT(CURLMOPT_MAXCONNECTS);
745
746 /* Available since 7.16.4 */
747 REGISTER_CURL_CONSTANT(CURLOPT_KRBLEVEL);
748 REGISTER_CURL_CONSTANT(CURLOPT_NEW_DIRECTORY_PERMS);
749 REGISTER_CURL_CONSTANT(CURLOPT_NEW_FILE_PERMS);
750
751 /* Available since 7.17.0 */
752 REGISTER_CURL_CONSTANT(CURLOPT_APPEND);
753 REGISTER_CURL_CONSTANT(CURLOPT_DIRLISTONLY);
754 REGISTER_CURL_CONSTANT(CURLOPT_USE_SSL);
755 /* Curl SSL Constants */
756 REGISTER_CURL_CONSTANT(CURLUSESSL_ALL);
757 REGISTER_CURL_CONSTANT(CURLUSESSL_CONTROL);
758 REGISTER_CURL_CONSTANT(CURLUSESSL_NONE);
759 REGISTER_CURL_CONSTANT(CURLUSESSL_TRY);
760
761 /* Available since 7.17.1 */
762 REGISTER_CURL_CONSTANT(CURLOPT_SSH_HOST_PUBLIC_KEY_MD5);
763
764 /* Available since 7.18.0 */
765 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_TRANSFER_MODE);
766 REGISTER_CURL_CONSTANT(CURLPAUSE_ALL);
767 REGISTER_CURL_CONSTANT(CURLPAUSE_CONT);
768 REGISTER_CURL_CONSTANT(CURLPAUSE_RECV);
769 REGISTER_CURL_CONSTANT(CURLPAUSE_RECV_CONT);
770 REGISTER_CURL_CONSTANT(CURLPAUSE_SEND);
771 REGISTER_CURL_CONSTANT(CURLPAUSE_SEND_CONT);
772 REGISTER_CURL_CONSTANT(CURL_READFUNC_PAUSE);
773 REGISTER_CURL_CONSTANT(CURL_WRITEFUNC_PAUSE);
774
775 REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS4A);
776 REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS5_HOSTNAME);
777
778 /* Available since 7.18.2 */
779 REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_URL);
780
781 /* Available since 7.19.0 */
782 REGISTER_CURL_CONSTANT(CURLINFO_APPCONNECT_TIME);
783 REGISTER_CURL_CONSTANT(CURLINFO_PRIMARY_IP);
784
785 REGISTER_CURL_CONSTANT(CURLOPT_ADDRESS_SCOPE);
786 REGISTER_CURL_CONSTANT(CURLOPT_CRLFILE);
787 REGISTER_CURL_CONSTANT(CURLOPT_ISSUERCERT);
788 REGISTER_CURL_CONSTANT(CURLOPT_KEYPASSWD);
789
790 REGISTER_CURL_CONSTANT(CURLSSH_AUTH_ANY);
791 REGISTER_CURL_CONSTANT(CURLSSH_AUTH_DEFAULT);
792 REGISTER_CURL_CONSTANT(CURLSSH_AUTH_HOST);
793 REGISTER_CURL_CONSTANT(CURLSSH_AUTH_KEYBOARD);
794 REGISTER_CURL_CONSTANT(CURLSSH_AUTH_NONE);
795 REGISTER_CURL_CONSTANT(CURLSSH_AUTH_PASSWORD);
796 REGISTER_CURL_CONSTANT(CURLSSH_AUTH_PUBLICKEY);
797
798 /* Available since 7.19.1 */
799 REGISTER_CURL_CONSTANT(CURLINFO_CERTINFO);
800 REGISTER_CURL_CONSTANT(CURLOPT_CERTINFO);
801 REGISTER_CURL_CONSTANT(CURLOPT_PASSWORD);
802 REGISTER_CURL_CONSTANT(CURLOPT_POSTREDIR);
803 REGISTER_CURL_CONSTANT(CURLOPT_PROXYPASSWORD);
804 REGISTER_CURL_CONSTANT(CURLOPT_PROXYUSERNAME);
805 REGISTER_CURL_CONSTANT(CURLOPT_USERNAME);
806 REGISTER_CURL_CONSTANT(CURL_REDIR_POST_301);
807 REGISTER_CURL_CONSTANT(CURL_REDIR_POST_302);
808 REGISTER_CURL_CONSTANT(CURL_REDIR_POST_ALL);
809
810 /* Available since 7.19.3 */
811 REGISTER_CURL_CONSTANT(CURLAUTH_DIGEST_IE);
812
813 /* Available since 7.19.4 */
814 REGISTER_CURL_CONSTANT(CURLINFO_CONDITION_UNMET);
815
816 REGISTER_CURL_CONSTANT(CURLOPT_NOPROXY);
817 REGISTER_CURL_CONSTANT(CURLOPT_PROTOCOLS);
818 REGISTER_CURL_CONSTANT(CURLOPT_REDIR_PROTOCOLS);
819 REGISTER_CURL_CONSTANT(CURLOPT_SOCKS5_GSSAPI_NEC);
820 REGISTER_CURL_CONSTANT(CURLOPT_SOCKS5_GSSAPI_SERVICE);
821 REGISTER_CURL_CONSTANT(CURLOPT_TFTP_BLKSIZE);
822
823 REGISTER_CURL_CONSTANT(CURLPROTO_ALL);
824 REGISTER_CURL_CONSTANT(CURLPROTO_DICT);
825 REGISTER_CURL_CONSTANT(CURLPROTO_FILE);
826 REGISTER_CURL_CONSTANT(CURLPROTO_FTP);
827 REGISTER_CURL_CONSTANT(CURLPROTO_FTPS);
828 REGISTER_CURL_CONSTANT(CURLPROTO_HTTP);
829 REGISTER_CURL_CONSTANT(CURLPROTO_HTTPS);
830 REGISTER_CURL_CONSTANT(CURLPROTO_LDAP);
831 REGISTER_CURL_CONSTANT(CURLPROTO_LDAPS);
832 REGISTER_CURL_CONSTANT(CURLPROTO_SCP);
833 REGISTER_CURL_CONSTANT(CURLPROTO_SFTP);
834 REGISTER_CURL_CONSTANT(CURLPROTO_TELNET);
835 REGISTER_CURL_CONSTANT(CURLPROTO_TFTP);
836
837 REGISTER_CURL_CONSTANT(CURLPROXY_HTTP_1_0);
838
839 REGISTER_CURL_CONSTANT(CURLFTP_CREATE_DIR);
840 REGISTER_CURL_CONSTANT(CURLFTP_CREATE_DIR_NONE);
841 REGISTER_CURL_CONSTANT(CURLFTP_CREATE_DIR_RETRY);
842
843 /* Available since 7.19.6 */
844 REGISTER_CURL_CONSTANT(CURL_VERSION_CURLDEBUG);
845 REGISTER_CURL_CONSTANT(CURLOPT_SSH_KNOWNHOSTS);
846
847 /* Available since 7.20.0 */
848 REGISTER_CURL_CONSTANT(CURLINFO_RTSP_CLIENT_CSEQ);
849 REGISTER_CURL_CONSTANT(CURLINFO_RTSP_CSEQ_RECV);
850 REGISTER_CURL_CONSTANT(CURLINFO_RTSP_SERVER_CSEQ);
851 REGISTER_CURL_CONSTANT(CURLINFO_RTSP_SESSION_ID);
852 REGISTER_CURL_CONSTANT(CURLOPT_FTP_USE_PRET);
853 REGISTER_CURL_CONSTANT(CURLOPT_MAIL_FROM);
854 REGISTER_CURL_CONSTANT(CURLOPT_MAIL_RCPT);
855 REGISTER_CURL_CONSTANT(CURLOPT_RTSP_CLIENT_CSEQ);
856 REGISTER_CURL_CONSTANT(CURLOPT_RTSP_REQUEST);
857 REGISTER_CURL_CONSTANT(CURLOPT_RTSP_SERVER_CSEQ);
858 REGISTER_CURL_CONSTANT(CURLOPT_RTSP_SESSION_ID);
859 REGISTER_CURL_CONSTANT(CURLOPT_RTSP_STREAM_URI);
860 REGISTER_CURL_CONSTANT(CURLOPT_RTSP_TRANSPORT);
861 REGISTER_CURL_CONSTANT(CURLPROTO_IMAP);
862 REGISTER_CURL_CONSTANT(CURLPROTO_IMAPS);
863 REGISTER_CURL_CONSTANT(CURLPROTO_POP3);
864 REGISTER_CURL_CONSTANT(CURLPROTO_POP3S);
865 REGISTER_CURL_CONSTANT(CURLPROTO_RTSP);
866 REGISTER_CURL_CONSTANT(CURLPROTO_SMTP);
867 REGISTER_CURL_CONSTANT(CURLPROTO_SMTPS);
868 REGISTER_CURL_CONSTANT(CURL_RTSPREQ_ANNOUNCE);
869 REGISTER_CURL_CONSTANT(CURL_RTSPREQ_DESCRIBE);
870 REGISTER_CURL_CONSTANT(CURL_RTSPREQ_GET_PARAMETER);
871 REGISTER_CURL_CONSTANT(CURL_RTSPREQ_OPTIONS);
872 REGISTER_CURL_CONSTANT(CURL_RTSPREQ_PAUSE);
873 REGISTER_CURL_CONSTANT(CURL_RTSPREQ_PLAY);
874 REGISTER_CURL_CONSTANT(CURL_RTSPREQ_RECEIVE);
875 REGISTER_CURL_CONSTANT(CURL_RTSPREQ_RECORD);
876 REGISTER_CURL_CONSTANT(CURL_RTSPREQ_SET_PARAMETER);
877 REGISTER_CURL_CONSTANT(CURL_RTSPREQ_SETUP);
878 REGISTER_CURL_CONSTANT(CURL_RTSPREQ_TEARDOWN);
879
880 /* Available since 7.21.0 */
881 REGISTER_CURL_CONSTANT(CURLINFO_LOCAL_IP);
882 REGISTER_CURL_CONSTANT(CURLINFO_LOCAL_PORT);
883 REGISTER_CURL_CONSTANT(CURLINFO_PRIMARY_PORT);
884 REGISTER_CURL_CONSTANT(CURLOPT_FNMATCH_FUNCTION);
885 REGISTER_CURL_CONSTANT(CURLOPT_WILDCARDMATCH);
886 REGISTER_CURL_CONSTANT(CURLPROTO_RTMP);
887 REGISTER_CURL_CONSTANT(CURLPROTO_RTMPE);
888 REGISTER_CURL_CONSTANT(CURLPROTO_RTMPS);
889 REGISTER_CURL_CONSTANT(CURLPROTO_RTMPT);
890 REGISTER_CURL_CONSTANT(CURLPROTO_RTMPTE);
891 REGISTER_CURL_CONSTANT(CURLPROTO_RTMPTS);
892 REGISTER_CURL_CONSTANT(CURL_FNMATCHFUNC_FAIL);
893 REGISTER_CURL_CONSTANT(CURL_FNMATCHFUNC_MATCH);
894 REGISTER_CURL_CONSTANT(CURL_FNMATCHFUNC_NOMATCH);
895
896 /* Available since 7.21.2 */
897 REGISTER_CURL_CONSTANT(CURLPROTO_GOPHER);
898
899 /* Available since 7.21.3 */
900 REGISTER_CURL_CONSTANT(CURLAUTH_ONLY);
901 REGISTER_CURL_CONSTANT(CURLOPT_RESOLVE);
902
903 /* Available since 7.21.4 */
904 REGISTER_CURL_CONSTANT(CURLOPT_TLSAUTH_PASSWORD);
905 REGISTER_CURL_CONSTANT(CURLOPT_TLSAUTH_TYPE);
906 REGISTER_CURL_CONSTANT(CURLOPT_TLSAUTH_USERNAME);
907 REGISTER_CURL_CONSTANT(CURL_TLSAUTH_SRP);
908 REGISTER_CURL_CONSTANT(CURL_VERSION_TLSAUTH_SRP);
909
910 /* Available since 7.21.6 */
911 REGISTER_CURL_CONSTANT(CURLOPT_ACCEPT_ENCODING);
912 REGISTER_CURL_CONSTANT(CURLOPT_TRANSFER_ENCODING);
913
914 /* Available since 7.22.0 */
915 REGISTER_CURL_CONSTANT(CURLAUTH_NTLM_WB);
916 REGISTER_CURL_CONSTANT(CURLGSSAPI_DELEGATION_FLAG);
917 REGISTER_CURL_CONSTANT(CURLGSSAPI_DELEGATION_POLICY_FLAG);
918 REGISTER_CURL_CONSTANT(CURLOPT_GSSAPI_DELEGATION);
919 REGISTER_CURL_CONSTANT(CURL_VERSION_NTLM_WB);
920
921 /* Available since 7.24.0 */
922 REGISTER_CURL_CONSTANT(CURLOPT_ACCEPTTIMEOUT_MS);
923 REGISTER_CURL_CONSTANT(CURLOPT_DNS_SERVERS);
924
925 /* Available since 7.25.0 */
926 REGISTER_CURL_CONSTANT(CURLOPT_MAIL_AUTH);
927 REGISTER_CURL_CONSTANT(CURLOPT_SSL_OPTIONS);
928 REGISTER_CURL_CONSTANT(CURLOPT_TCP_KEEPALIVE);
929 REGISTER_CURL_CONSTANT(CURLOPT_TCP_KEEPIDLE);
930 REGISTER_CURL_CONSTANT(CURLOPT_TCP_KEEPINTVL);
931 REGISTER_CURL_CONSTANT(CURLSSLOPT_ALLOW_BEAST);
932
933 /* Available since 7.25.1 */
934 REGISTER_CURL_CONSTANT(CURL_REDIR_POST_303);
935
936 /* Available since 7.28.0 */
937 REGISTER_CURL_CONSTANT(CURLSSH_AUTH_AGENT);
938
939 #if LIBCURL_VERSION_NUM >= 0x071e00 /* Available since 7.30.0 */
940 REGISTER_CURL_CONSTANT(CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE);
941 REGISTER_CURL_CONSTANT(CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE);
942 REGISTER_CURL_CONSTANT(CURLMOPT_MAX_HOST_CONNECTIONS);
943 REGISTER_CURL_CONSTANT(CURLMOPT_MAX_PIPELINE_LENGTH);
944 REGISTER_CURL_CONSTANT(CURLMOPT_MAX_TOTAL_CONNECTIONS);
945 #endif
946
947 #if LIBCURL_VERSION_NUM >= 0x071f00 /* Available since 7.31.0 */
948 REGISTER_CURL_CONSTANT(CURLOPT_SASL_IR);
949 #endif
950
951 #if LIBCURL_VERSION_NUM >= 0x072100 /* Available since 7.33.0 */
952 REGISTER_CURL_CONSTANT(CURLOPT_DNS_INTERFACE);
953 REGISTER_CURL_CONSTANT(CURLOPT_DNS_LOCAL_IP4);
954 REGISTER_CURL_CONSTANT(CURLOPT_DNS_LOCAL_IP6);
955 REGISTER_CURL_CONSTANT(CURLOPT_XOAUTH2_BEARER);
956
957 REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_2_0);
958 REGISTER_CURL_CONSTANT(CURL_VERSION_HTTP2);
959 #endif
960
961 #if LIBCURL_VERSION_NUM >= 0x072200 /* Available since 7.34.0 */
962 REGISTER_CURL_CONSTANT(CURLOPT_LOGIN_OPTIONS);
963
964 REGISTER_CURL_CONSTANT(CURL_SSLVERSION_TLSv1_0);
965 REGISTER_CURL_CONSTANT(CURL_SSLVERSION_TLSv1_1);
966 REGISTER_CURL_CONSTANT(CURL_SSLVERSION_TLSv1_2);
967 #endif
968
969 #if LIBCURL_VERSION_NUM >= 0x072400 /* Available since 7.36.0 */
970 REGISTER_CURL_CONSTANT(CURLOPT_EXPECT_100_TIMEOUT_MS);
971 REGISTER_CURL_CONSTANT(CURLOPT_SSL_ENABLE_ALPN);
972 REGISTER_CURL_CONSTANT(CURLOPT_SSL_ENABLE_NPN);
973 #endif
974
975 #if LIBCURL_VERSION_NUM >= 0x072500 /* Available since 7.37.0 */
976 REGISTER_CURL_CONSTANT(CURLHEADER_SEPARATE);
977 REGISTER_CURL_CONSTANT(CURLHEADER_UNIFIED);
978 REGISTER_CURL_CONSTANT(CURLOPT_HEADEROPT);
979 REGISTER_CURL_CONSTANT(CURLOPT_PROXYHEADER);
980 #endif
981
982 #if LIBCURL_VERSION_NUM >= 0x072600 /* Available since 7.38.0 */
983 REGISTER_CURL_CONSTANT(CURLAUTH_NEGOTIATE);
984 REGISTER_CURL_CONSTANT(CURL_VERSION_GSSAPI);
985 #endif
986
987 #if LIBCURL_VERSION_NUM >= 0x072700 /* Available since 7.39.0 */
988 REGISTER_CURL_CONSTANT(CURLOPT_PINNEDPUBLICKEY);
989 #endif
990
991 #if LIBCURL_VERSION_NUM >= 0x072800 /* Available since 7.40.0 */
992 REGISTER_CURL_CONSTANT(CURLOPT_UNIX_SOCKET_PATH);
993 REGISTER_CURL_CONSTANT(CURLPROTO_SMB);
994 REGISTER_CURL_CONSTANT(CURLPROTO_SMBS);
995 REGISTER_CURL_CONSTANT(CURL_VERSION_KERBEROS5);
996 REGISTER_CURL_CONSTANT(CURL_VERSION_UNIX_SOCKETS);
997 #endif
998
999 #if LIBCURL_VERSION_NUM >= 0x072900 /* Available since 7.41.0 */
1000 REGISTER_CURL_CONSTANT(CURLOPT_SSL_VERIFYSTATUS);
1001 #endif
1002
1003 #if LIBCURL_VERSION_NUM >= 0x072a00 /* Available since 7.42.0 */
1004 REGISTER_CURL_CONSTANT(CURLOPT_PATH_AS_IS);
1005 REGISTER_CURL_CONSTANT(CURLOPT_SSL_FALSESTART);
1006 #endif
1007
1008 #if LIBCURL_VERSION_NUM >= 0x072b00 /* Available since 7.43.0 */
1009 REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_2);
1010
1011 REGISTER_CURL_CONSTANT(CURLOPT_PIPEWAIT);
1012 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SERVICE_NAME);
1013 REGISTER_CURL_CONSTANT(CURLOPT_SERVICE_NAME);
1014
1015 REGISTER_CURL_CONSTANT(CURLPIPE_NOTHING);
1016 REGISTER_CURL_CONSTANT(CURLPIPE_HTTP1);
1017 REGISTER_CURL_CONSTANT(CURLPIPE_MULTIPLEX);
1018 #endif
1019
1020 #if LIBCURL_VERSION_NUM >= 0x072c00 /* Available since 7.44.0 */
1021 REGISTER_CURL_CONSTANT(CURLSSLOPT_NO_REVOKE);
1022 #endif
1023
1024 #if LIBCURL_VERSION_NUM >= 0x072d00 /* Available since 7.45.0 */
1025 REGISTER_CURL_CONSTANT(CURLOPT_DEFAULT_PROTOCOL);
1026 #endif
1027
1028 #if LIBCURL_VERSION_NUM >= 0x072e00 /* Available since 7.46.0 */
1029 REGISTER_CURL_CONSTANT(CURLOPT_STREAM_WEIGHT);
1030 REGISTER_CURL_CONSTANT(CURLMOPT_PUSHFUNCTION);
1031 REGISTER_CURL_CONSTANT(CURL_PUSH_OK);
1032 REGISTER_CURL_CONSTANT(CURL_PUSH_DENY);
1033 #endif
1034
1035 #if LIBCURL_VERSION_NUM >= 0x072f00 /* Available since 7.47.0 */
1036 REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_2TLS);
1037 REGISTER_CURL_CONSTANT(CURL_VERSION_PSL);
1038 #endif
1039
1040 #if LIBCURL_VERSION_NUM >= 0x073000 /* Available since 7.48.0 */
1041 REGISTER_CURL_CONSTANT(CURLOPT_TFTP_NO_OPTIONS);
1042 #endif
1043
1044 #if LIBCURL_VERSION_NUM >= 0x073100 /* Available since 7.49.0 */
1045 REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
1046 REGISTER_CURL_CONSTANT(CURLOPT_CONNECT_TO);
1047 REGISTER_CURL_CONSTANT(CURLOPT_TCP_FASTOPEN);
1048 #endif
1049
1050 #if LIBCURL_VERSION_NUM >= 0x073200 /* Available since 7.50.0 */
1051 REGISTER_CURL_CONSTANT(CURLINFO_HTTP_VERSION);
1052 #endif
1053
1054 #if LIBCURL_VERSION_NUM >= 0x073300 /* Available since 7.51.0 */
1055 REGISTER_CURL_CONSTANT(CURLE_WEIRD_SERVER_REPLY);
1056 REGISTER_CURL_CONSTANT(CURLOPT_KEEP_SENDING_ON_ERROR);
1057 #endif
1058
1059 #if LIBCURL_VERSION_NUM >= 0x073400 /* Available since 7.52.0 */
1060 REGISTER_CURL_CONSTANT(CURL_SSLVERSION_TLSv1_3);
1061 REGISTER_CURL_CONSTANT(CURL_VERSION_HTTPS_PROXY);
1062 REGISTER_CURL_CONSTANT(CURLINFO_PROTOCOL);
1063 REGISTER_CURL_CONSTANT(CURLINFO_PROXY_SSL_VERIFYRESULT);
1064 REGISTER_CURL_CONSTANT(CURLINFO_SCHEME);
1065 REGISTER_CURL_CONSTANT(CURLOPT_PRE_PROXY);
1066 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_CAINFO);
1067 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_CAPATH);
1068 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_CRLFILE);
1069 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_KEYPASSWD);
1070 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_PINNEDPUBLICKEY);
1071 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSL_CIPHER_LIST);
1072 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSL_OPTIONS);
1073 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSL_VERIFYHOST);
1074 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSL_VERIFYPEER);
1075 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSLCERT);
1076 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSLCERTTYPE);
1077 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSLKEY);
1078 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSLKEYTYPE);
1079 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_SSLVERSION);
1080 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_TLSAUTH_PASSWORD);
1081 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_TLSAUTH_TYPE);
1082 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_TLSAUTH_USERNAME);
1083 REGISTER_CURL_CONSTANT(CURLPROXY_HTTPS);
1084 #endif
1085
1086 #if LIBCURL_VERSION_NUM >= 0x073500 /* Available since 7.53.0 */
1087 REGISTER_CURL_CONSTANT(CURL_MAX_READ_SIZE);
1088 REGISTER_CURL_CONSTANT(CURLOPT_ABSTRACT_UNIX_SOCKET);
1089 #endif
1090
1091 #if LIBCURL_VERSION_NUM >= 0x073600 /* Available since 7.54.0 */
1092 REGISTER_CURL_CONSTANT(CURL_SSLVERSION_MAX_DEFAULT);
1093 REGISTER_CURL_CONSTANT(CURL_SSLVERSION_MAX_NONE);
1094 REGISTER_CURL_CONSTANT(CURL_SSLVERSION_MAX_TLSv1_0);
1095 REGISTER_CURL_CONSTANT(CURL_SSLVERSION_MAX_TLSv1_1);
1096 REGISTER_CURL_CONSTANT(CURL_SSLVERSION_MAX_TLSv1_2);
1097 REGISTER_CURL_CONSTANT(CURL_SSLVERSION_MAX_TLSv1_3);
1098 REGISTER_CURL_CONSTANT(CURLOPT_SUPPRESS_CONNECT_HEADERS);
1099 #endif
1100
1101 #if LIBCURL_VERSION_NUM >= 0x073601 /* Available since 7.54.1 */
1102 REGISTER_CURL_CONSTANT(CURLAUTH_GSSAPI);
1103 #endif
1104
1105 #if LIBCURL_VERSION_NUM >= 0x073700 /* Available since 7.55.0 */
1106 REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_LENGTH_DOWNLOAD_T);
1107 REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_LENGTH_UPLOAD_T);
1108 REGISTER_CURL_CONSTANT(CURLINFO_SIZE_DOWNLOAD_T);
1109 REGISTER_CURL_CONSTANT(CURLINFO_SIZE_UPLOAD_T);
1110 REGISTER_CURL_CONSTANT(CURLINFO_SPEED_DOWNLOAD_T);
1111 REGISTER_CURL_CONSTANT(CURLINFO_SPEED_UPLOAD_T);
1112 REGISTER_CURL_CONSTANT(CURLOPT_REQUEST_TARGET);
1113 REGISTER_CURL_CONSTANT(CURLOPT_SOCKS5_AUTH);
1114 #endif
1115
1116 #if LIBCURL_VERSION_NUM >= 0x073800 /* Available since 7.56.0 */
1117 REGISTER_CURL_CONSTANT(CURLOPT_SSH_COMPRESSION);
1118 REGISTER_CURL_CONSTANT(CURL_VERSION_MULTI_SSL);
1119 #endif
1120
1121 #if LIBCURL_VERSION_NUM >= 0x073900 /* Available since 7.57.0 */
1122 REGISTER_CURL_CONSTANT(CURL_VERSION_BROTLI);
1123 REGISTER_CURL_CONSTANT(CURL_LOCK_DATA_CONNECT);
1124 #endif
1125
1126 #if LIBCURL_VERSION_NUM >= 0x073a00 /* Available since 7.58.0 */
1127 REGISTER_CURL_CONSTANT(CURLSSH_AUTH_GSSAPI);
1128 #endif
1129
1130 #if LIBCURL_VERSION_NUM >= 0x073b00 /* Available since 7.59.0 */
1131 REGISTER_CURL_CONSTANT(CURLINFO_FILETIME_T);
1132 REGISTER_CURL_CONSTANT(CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS);
1133 REGISTER_CURL_CONSTANT(CURLOPT_TIMEVALUE_LARGE);
1134 #endif
1135
1136 #if LIBCURL_VERSION_NUM >= 0x073c00 /* Available since 7.60.0 */
1137 REGISTER_CURL_CONSTANT(CURLOPT_DNS_SHUFFLE_ADDRESSES);
1138 REGISTER_CURL_CONSTANT(CURLOPT_HAPROXYPROTOCOL);
1139 #endif
1140
1141 #if LIBCURL_VERSION_NUM >= 0x073d00 /* Available since 7.61.0 */
1142 REGISTER_CURL_CONSTANT(CURL_LOCK_DATA_PSL);
1143 REGISTER_CURL_CONSTANT(CURLAUTH_BEARER);
1144 REGISTER_CURL_CONSTANT(CURLINFO_APPCONNECT_TIME_T);
1145 REGISTER_CURL_CONSTANT(CURLINFO_CONNECT_TIME_T);
1146 REGISTER_CURL_CONSTANT(CURLINFO_NAMELOOKUP_TIME_T);
1147 REGISTER_CURL_CONSTANT(CURLINFO_PRETRANSFER_TIME_T);
1148 REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_TIME_T);
1149 REGISTER_CURL_CONSTANT(CURLINFO_STARTTRANSFER_TIME_T);
1150 REGISTER_CURL_CONSTANT(CURLINFO_TOTAL_TIME_T);
1151 REGISTER_CURL_CONSTANT(CURLOPT_DISALLOW_USERNAME_IN_URL);
1152 REGISTER_CURL_CONSTANT(CURLOPT_PROXY_TLS13_CIPHERS);
1153 REGISTER_CURL_CONSTANT(CURLOPT_TLS13_CIPHERS);
1154 #endif
1155
1156 #if LIBCURL_VERSION_NUM >= 0x074000 /* Available since 7.64.0 */
1157 REGISTER_CURL_CONSTANT(CURLOPT_HTTP09_ALLOWED);
1158 #endif
1159
1160 #if LIBCURL_VERSION_NUM >= 0x074001 /* Available since 7.64.1 */
1161 REGISTER_CURL_CONSTANT(CURL_VERSION_ALTSVC);
1162 #endif
1163
1164 REGISTER_CURL_CONSTANT(CURLOPT_SAFE_UPLOAD);
1165
1166 #ifdef PHP_CURL_NEED_OPENSSL_TSL
1167 if (!CRYPTO_get_id_callback()) {
1168 int i, c = CRYPTO_num_locks();
1169
1170 php_curl_openssl_tsl = malloc(c * sizeof(MUTEX_T));
1171 if (!php_curl_openssl_tsl) {
1172 return FAILURE;
1173 }
1174
1175 for (i = 0; i < c; ++i) {
1176 php_curl_openssl_tsl[i] = tsrm_mutex_alloc();
1177 }
1178
1179 CRYPTO_set_id_callback(php_curl_ssl_id);
1180 CRYPTO_set_locking_callback(php_curl_ssl_lock);
1181 }
1182 #endif
1183
1184 if (curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) {
1185 return FAILURE;
1186 }
1187
1188 zend_class_entry ce;
1189 INIT_CLASS_ENTRY(ce, "CurlHandle", class_CurlHandle_methods);
1190 curl_ce = zend_register_internal_class(&ce);
1191 curl_ce->ce_flags |= ZEND_ACC_FINAL | ZEND_ACC_NO_DYNAMIC_PROPERTIES;
1192 curl_ce->create_object = curl_create_object;
1193 curl_ce->serialize = zend_class_serialize_deny;
1194 curl_ce->unserialize = zend_class_unserialize_deny;
1195
1196 memcpy(&curl_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
1197 curl_object_handlers.offset = XtOffsetOf(php_curl, std);
1198 curl_object_handlers.free_obj = curl_free_obj;
1199 curl_object_handlers.get_gc = curl_get_gc;
1200 curl_object_handlers.get_constructor = curl_get_constructor;
1201 curl_object_handlers.clone_obj = curl_clone_obj;
1202 curl_object_handlers.cast_object = curl_cast_object;
1203 curl_object_handlers.compare = zend_objects_not_comparable;
1204
1205 curl_multi_register_class(class_CurlMultiHandle_methods);
1206 curl_share_register_class(class_CurlShareHandle_methods);
1207 curlfile_register_class();
1208
1209 return SUCCESS;
1210 }
1211 /* }}} */
1212
1213 /* CurlHandle class */
1214
curl_create_object(zend_class_entry * class_type)1215 static zend_object *curl_create_object(zend_class_entry *class_type) {
1216 php_curl *intern = zend_object_alloc(sizeof(php_curl), class_type);
1217
1218 zend_object_std_init(&intern->std, class_type);
1219 object_properties_init(&intern->std, class_type);
1220 intern->std.handlers = &curl_object_handlers;
1221
1222 return &intern->std;
1223 }
1224
curl_get_constructor(zend_object * object)1225 static zend_function *curl_get_constructor(zend_object *object) {
1226 zend_throw_error(NULL, "Cannot directly construct CurlHandle, use curl_init() instead");
1227 return NULL;
1228 }
1229
curl_clone_obj(zend_object * object)1230 static zend_object *curl_clone_obj(zend_object *object) {
1231 php_curl *ch;
1232 CURL *cp;
1233 zval *postfields;
1234 zend_object *clone_object;
1235 php_curl *clone_ch;
1236
1237 clone_object = curl_create_object(curl_ce);
1238 clone_ch = curl_from_obj(clone_object);
1239 init_curl_handle(clone_ch);
1240
1241 ch = curl_from_obj(object);
1242 cp = curl_easy_duphandle(ch->cp);
1243 if (!cp) {
1244 zend_throw_exception(NULL, "Failed to clone CurlHandle", 0);
1245 return &clone_ch->std;
1246 }
1247
1248 clone_ch->cp = cp;
1249 _php_setup_easy_copy_handlers(clone_ch, ch);
1250
1251 postfields = &clone_ch->postfields;
1252 if (Z_TYPE_P(postfields) != IS_UNDEF) {
1253 if (build_mime_structure_from_hash(clone_ch, postfields) != SUCCESS) {
1254 zend_throw_exception(NULL, "Failed to clone CurlHandle", 0);
1255 return &clone_ch->std;
1256 }
1257 }
1258
1259 return &clone_ch->std;
1260 }
1261
curl_get_gc(zend_object * object,zval ** table,int * n)1262 static HashTable *curl_get_gc(zend_object *object, zval **table, int *n)
1263 {
1264 php_curl *curl = curl_from_obj(object);
1265
1266 zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create();
1267
1268 zend_get_gc_buffer_add_zval(gc_buffer, &curl->postfields);
1269 if (curl->handlers) {
1270 if (curl->handlers->read) {
1271 zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers->read->func_name);
1272 zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers->read->stream);
1273 }
1274
1275 if (curl->handlers->write) {
1276 zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers->write->func_name);
1277 zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers->write->stream);
1278 }
1279
1280 if (curl->handlers->write_header) {
1281 zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers->write_header->func_name);
1282 zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers->write_header->stream);
1283 }
1284
1285 if (curl->handlers->progress) {
1286 zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers->progress->func_name);
1287 }
1288
1289 #if LIBCURL_VERSION_NUM >= 0x071500
1290 if (curl->handlers->fnmatch) {
1291 zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers->fnmatch->func_name);
1292 }
1293 #endif
1294
1295 zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers->std_err);
1296 }
1297
1298 zend_get_gc_buffer_use(gc_buffer, table, n);
1299
1300 return zend_std_get_properties(object);
1301 }
1302
curl_cast_object(zend_object * obj,zval * result,int type)1303 int curl_cast_object(zend_object *obj, zval *result, int type)
1304 {
1305 if (type == IS_LONG) {
1306 /* For better backward compatibility, make (int) $curl_handle return the object ID,
1307 * similar to how it previously returned the resource ID. */
1308 ZVAL_LONG(result, obj->handle);
1309 return SUCCESS;
1310 }
1311
1312 return zend_std_cast_object_tostring(obj, result, type);
1313 }
1314
1315 /* {{{ PHP_MSHUTDOWN_FUNCTION */
PHP_MSHUTDOWN_FUNCTION(curl)1316 PHP_MSHUTDOWN_FUNCTION(curl)
1317 {
1318 curl_global_cleanup();
1319 #ifdef PHP_CURL_NEED_OPENSSL_TSL
1320 if (php_curl_openssl_tsl) {
1321 int i, c = CRYPTO_num_locks();
1322
1323 CRYPTO_set_id_callback(NULL);
1324 CRYPTO_set_locking_callback(NULL);
1325
1326 for (i = 0; i < c; ++i) {
1327 tsrm_mutex_free(php_curl_openssl_tsl[i]);
1328 }
1329
1330 free(php_curl_openssl_tsl);
1331 php_curl_openssl_tsl = NULL;
1332 }
1333 #endif
1334 UNREGISTER_INI_ENTRIES();
1335 return SUCCESS;
1336 }
1337 /* }}} */
1338
1339 /* {{{ curl_write_nothing
1340 * Used as a work around. See _php_curl_close_ex
1341 */
curl_write_nothing(char * data,size_t size,size_t nmemb,void * ctx)1342 static size_t curl_write_nothing(char *data, size_t size, size_t nmemb, void *ctx)
1343 {
1344 return size * nmemb;
1345 }
1346 /* }}} */
1347
1348 /* {{{ curl_write */
curl_write(char * data,size_t size,size_t nmemb,void * ctx)1349 static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx)
1350 {
1351 php_curl *ch = (php_curl *) ctx;
1352 php_curl_write *t = ch->handlers->write;
1353 size_t length = size * nmemb;
1354
1355 #if PHP_CURL_DEBUG
1356 fprintf(stderr, "curl_write() called\n");
1357 fprintf(stderr, "data = %s, size = %d, nmemb = %d, ctx = %x\n", data, size, nmemb, ctx);
1358 #endif
1359
1360 switch (t->method) {
1361 case PHP_CURL_STDOUT:
1362 PHPWRITE(data, length);
1363 break;
1364 case PHP_CURL_FILE:
1365 return fwrite(data, size, nmemb, t->fp);
1366 case PHP_CURL_RETURN:
1367 if (length > 0) {
1368 smart_str_appendl(&t->buf, data, (int) length);
1369 }
1370 break;
1371 case PHP_CURL_USER: {
1372 zval argv[2];
1373 zval retval;
1374 int error;
1375 zend_fcall_info fci;
1376
1377 GC_ADDREF(&ch->std);
1378 ZVAL_OBJ(&argv[0], &ch->std);
1379 ZVAL_STRINGL(&argv[1], data, length);
1380
1381 fci.size = sizeof(fci);
1382 fci.object = NULL;
1383 ZVAL_COPY_VALUE(&fci.function_name, &t->func_name);
1384 fci.retval = &retval;
1385 fci.param_count = 2;
1386 fci.params = argv;
1387 fci.named_params = NULL;
1388
1389 ch->in_callback = 1;
1390 error = zend_call_function(&fci, &t->fci_cache);
1391 ch->in_callback = 0;
1392 if (error == FAILURE) {
1393 php_error_docref(NULL, E_WARNING, "Could not call the CURLOPT_WRITEFUNCTION");
1394 length = -1;
1395 } else if (!Z_ISUNDEF(retval)) {
1396 _php_curl_verify_handlers(ch, 1);
1397 length = zval_get_long(&retval);
1398 }
1399
1400 zval_ptr_dtor(&argv[0]);
1401 zval_ptr_dtor(&argv[1]);
1402 break;
1403 }
1404 }
1405
1406 return length;
1407 }
1408 /* }}} */
1409
1410 /* {{{ curl_fnmatch */
curl_fnmatch(void * ctx,const char * pattern,const char * string)1411 static int curl_fnmatch(void *ctx, const char *pattern, const char *string)
1412 {
1413 php_curl *ch = (php_curl *) ctx;
1414 php_curl_fnmatch *t = ch->handlers->fnmatch;
1415 int rval = CURL_FNMATCHFUNC_FAIL;
1416 switch (t->method) {
1417 case PHP_CURL_USER: {
1418 zval argv[3];
1419 zval retval;
1420 int error;
1421 zend_fcall_info fci;
1422
1423 GC_ADDREF(&ch->std);
1424 ZVAL_OBJ(&argv[0], &ch->std);
1425 ZVAL_STRING(&argv[1], pattern);
1426 ZVAL_STRING(&argv[2], string);
1427
1428 fci.size = sizeof(fci);
1429 ZVAL_COPY_VALUE(&fci.function_name, &t->func_name);
1430 fci.object = NULL;
1431 fci.retval = &retval;
1432 fci.param_count = 3;
1433 fci.params = argv;
1434 fci.named_params = NULL;
1435
1436 ch->in_callback = 1;
1437 error = zend_call_function(&fci, &t->fci_cache);
1438 ch->in_callback = 0;
1439 if (error == FAILURE) {
1440 php_error_docref(NULL, E_WARNING, "Cannot call the CURLOPT_FNMATCH_FUNCTION");
1441 } else if (!Z_ISUNDEF(retval)) {
1442 _php_curl_verify_handlers(ch, 1);
1443 rval = zval_get_long(&retval);
1444 }
1445 zval_ptr_dtor(&argv[0]);
1446 zval_ptr_dtor(&argv[1]);
1447 zval_ptr_dtor(&argv[2]);
1448 break;
1449 }
1450 }
1451 return rval;
1452 }
1453 /* }}} */
1454
1455 /* {{{ curl_progress */
curl_progress(void * clientp,double dltotal,double dlnow,double ultotal,double ulnow)1456 static size_t curl_progress(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
1457 {
1458 php_curl *ch = (php_curl *)clientp;
1459 php_curl_progress *t = ch->handlers->progress;
1460 size_t rval = 0;
1461
1462 #if PHP_CURL_DEBUG
1463 fprintf(stderr, "curl_progress() called\n");
1464 fprintf(stderr, "clientp = %x, dltotal = %f, dlnow = %f, ultotal = %f, ulnow = %f\n", clientp, dltotal, dlnow, ultotal, ulnow);
1465 #endif
1466
1467 switch (t->method) {
1468 case PHP_CURL_USER: {
1469 zval argv[5];
1470 zval retval;
1471 int error;
1472 zend_fcall_info fci;
1473
1474 GC_ADDREF(&ch->std);
1475 ZVAL_OBJ(&argv[0], &ch->std);
1476 ZVAL_LONG(&argv[1], (zend_long)dltotal);
1477 ZVAL_LONG(&argv[2], (zend_long)dlnow);
1478 ZVAL_LONG(&argv[3], (zend_long)ultotal);
1479 ZVAL_LONG(&argv[4], (zend_long)ulnow);
1480
1481 fci.size = sizeof(fci);
1482 ZVAL_COPY_VALUE(&fci.function_name, &t->func_name);
1483 fci.object = NULL;
1484 fci.retval = &retval;
1485 fci.param_count = 5;
1486 fci.params = argv;
1487 fci.named_params = NULL;
1488
1489 ch->in_callback = 1;
1490 error = zend_call_function(&fci, &t->fci_cache);
1491 ch->in_callback = 0;
1492 if (error == FAILURE) {
1493 php_error_docref(NULL, E_WARNING, "Cannot call the CURLOPT_PROGRESSFUNCTION");
1494 } else if (!Z_ISUNDEF(retval)) {
1495 _php_curl_verify_handlers(ch, 1);
1496 if (0 != zval_get_long(&retval)) {
1497 rval = 1;
1498 }
1499 }
1500 zval_ptr_dtor(&argv[0]);
1501 break;
1502 }
1503 }
1504 return rval;
1505 }
1506 /* }}} */
1507
1508 /* {{{ curl_read */
curl_read(char * data,size_t size,size_t nmemb,void * ctx)1509 static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx)
1510 {
1511 php_curl *ch = (php_curl *)ctx;
1512 php_curl_read *t = ch->handlers->read;
1513 int length = 0;
1514
1515 switch (t->method) {
1516 case PHP_CURL_DIRECT:
1517 if (t->fp) {
1518 length = fread(data, size, nmemb, t->fp);
1519 }
1520 break;
1521 case PHP_CURL_USER: {
1522 zval argv[3];
1523 zval retval;
1524 int error;
1525 zend_fcall_info fci;
1526
1527 GC_ADDREF(&ch->std);
1528 ZVAL_OBJ(&argv[0], &ch->std);
1529 if (t->res) {
1530 GC_ADDREF(t->res);
1531 ZVAL_RES(&argv[1], t->res);
1532 } else {
1533 ZVAL_NULL(&argv[1]);
1534 }
1535 ZVAL_LONG(&argv[2], (int)size * nmemb);
1536
1537 fci.size = sizeof(fci);
1538 ZVAL_COPY_VALUE(&fci.function_name, &t->func_name);
1539 fci.object = NULL;
1540 fci.retval = &retval;
1541 fci.param_count = 3;
1542 fci.params = argv;
1543 fci.named_params = NULL;
1544
1545 ch->in_callback = 1;
1546 error = zend_call_function(&fci, &t->fci_cache);
1547 ch->in_callback = 0;
1548 if (error == FAILURE) {
1549 php_error_docref(NULL, E_WARNING, "Cannot call the CURLOPT_READFUNCTION");
1550 length = CURL_READFUNC_ABORT;
1551 } else if (!Z_ISUNDEF(retval)) {
1552 _php_curl_verify_handlers(ch, 1);
1553 if (Z_TYPE(retval) == IS_STRING) {
1554 length = MIN((int) (size * nmemb), Z_STRLEN(retval));
1555 memcpy(data, Z_STRVAL(retval), length);
1556 }
1557 zval_ptr_dtor(&retval);
1558 }
1559
1560 zval_ptr_dtor(&argv[0]);
1561 zval_ptr_dtor(&argv[1]);
1562 break;
1563 }
1564 }
1565
1566 return length;
1567 }
1568 /* }}} */
1569
1570 /* {{{ curl_write_header */
curl_write_header(char * data,size_t size,size_t nmemb,void * ctx)1571 static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx)
1572 {
1573 php_curl *ch = (php_curl *) ctx;
1574 php_curl_write *t = ch->handlers->write_header;
1575 size_t length = size * nmemb;
1576
1577 switch (t->method) {
1578 case PHP_CURL_STDOUT:
1579 /* Handle special case write when we're returning the entire transfer
1580 */
1581 if (ch->handlers->write->method == PHP_CURL_RETURN && length > 0) {
1582 smart_str_appendl(&ch->handlers->write->buf, data, (int) length);
1583 } else {
1584 PHPWRITE(data, length);
1585 }
1586 break;
1587 case PHP_CURL_FILE:
1588 return fwrite(data, size, nmemb, t->fp);
1589 case PHP_CURL_USER: {
1590 zval argv[2];
1591 zval retval;
1592 int error;
1593 zend_fcall_info fci;
1594
1595 GC_ADDREF(&ch->std);
1596 ZVAL_OBJ(&argv[0], &ch->std);
1597 ZVAL_STRINGL(&argv[1], data, length);
1598
1599 fci.size = sizeof(fci);
1600 ZVAL_COPY_VALUE(&fci.function_name, &t->func_name);
1601 fci.object = NULL;
1602 fci.retval = &retval;
1603 fci.param_count = 2;
1604 fci.params = argv;
1605 fci.named_params = NULL;
1606
1607 ch->in_callback = 1;
1608 error = zend_call_function(&fci, &t->fci_cache);
1609 ch->in_callback = 0;
1610 if (error == FAILURE) {
1611 php_error_docref(NULL, E_WARNING, "Could not call the CURLOPT_HEADERFUNCTION");
1612 length = -1;
1613 } else if (!Z_ISUNDEF(retval)) {
1614 _php_curl_verify_handlers(ch, 1);
1615 length = zval_get_long(&retval);
1616 }
1617 zval_ptr_dtor(&argv[0]);
1618 zval_ptr_dtor(&argv[1]);
1619 break;
1620 }
1621
1622 case PHP_CURL_IGNORE:
1623 return length;
1624
1625 default:
1626 return -1;
1627 }
1628
1629 return length;
1630 }
1631 /* }}} */
1632
curl_debug(CURL * cp,curl_infotype type,char * buf,size_t buf_len,void * ctx)1633 static int curl_debug(CURL *cp, curl_infotype type, char *buf, size_t buf_len, void *ctx) /* {{{ */
1634 {
1635 php_curl *ch = (php_curl *)ctx;
1636
1637 if (type == CURLINFO_HEADER_OUT) {
1638 if (ch->header.str) {
1639 zend_string_release_ex(ch->header.str, 0);
1640 }
1641 ch->header.str = zend_string_init(buf, buf_len, 0);
1642 }
1643
1644 return 0;
1645 }
1646 /* }}} */
1647
1648 /* {{{ curl_free_string */
curl_free_string(void ** string)1649 static void curl_free_string(void **string)
1650 {
1651 efree((char *)*string);
1652 }
1653 /* }}} */
1654
1655 /* {{{ curl_free_post */
curl_free_post(void ** post)1656 static void curl_free_post(void **post)
1657 {
1658 #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
1659 curl_mime_free((curl_mime *)*post);
1660 #else
1661 curl_formfree((struct HttpPost *)*post);
1662 #endif
1663 }
1664 /* }}} */
1665
1666 struct mime_data_cb_arg {
1667 zend_string *filename;
1668 php_stream *stream;
1669 };
1670
1671 /* {{{ curl_free_cb_arg */
curl_free_cb_arg(void ** cb_arg_p)1672 static void curl_free_cb_arg(void **cb_arg_p)
1673 {
1674 struct mime_data_cb_arg *cb_arg = (struct mime_data_cb_arg *) *cb_arg_p;
1675
1676 ZEND_ASSERT(cb_arg->stream == NULL);
1677 zend_string_release(cb_arg->filename);
1678 efree(cb_arg);
1679 }
1680 /* }}} */
1681
1682 /* {{{ curl_free_slist */
curl_free_slist(zval * el)1683 static void curl_free_slist(zval *el)
1684 {
1685 curl_slist_free_all(((struct curl_slist *)Z_PTR_P(el)));
1686 }
1687 /* }}} */
1688
1689 /* {{{ Return cURL version information. */
PHP_FUNCTION(curl_version)1690 PHP_FUNCTION(curl_version)
1691 {
1692 curl_version_info_data *d;
1693
1694 ZEND_PARSE_PARAMETERS_NONE();
1695
1696 d = curl_version_info(CURLVERSION_NOW);
1697 if (d == NULL) {
1698 RETURN_FALSE;
1699 }
1700
1701 array_init(return_value);
1702
1703 CAAL("version_number", d->version_num);
1704 CAAL("age", d->age);
1705 CAAL("features", d->features);
1706 CAAL("ssl_version_number", d->ssl_version_num);
1707 CAAS("version", d->version);
1708 CAAS("host", d->host);
1709 CAAS("ssl_version", d->ssl_version);
1710 CAAS("libz_version", d->libz_version);
1711 /* Add an array of protocols */
1712 {
1713 char **p = (char **) d->protocols;
1714 zval protocol_list;
1715
1716 array_init(&protocol_list);
1717
1718 while (*p != NULL) {
1719 add_next_index_string(&protocol_list, *p);
1720 p++;
1721 }
1722 CAAZ("protocols", &protocol_list);
1723 }
1724 if (d->age >= 1) {
1725 CAAS("ares", d->ares);
1726 CAAL("ares_num", d->ares_num);
1727 }
1728 if (d->age >= 2) {
1729 CAAS("libidn", d->libidn);
1730 }
1731 if (d->age >= 3) {
1732 CAAL("iconv_ver_num", d->iconv_ver_num);
1733 CAAS("libssh_version", d->libssh_version);
1734 }
1735 #if LIBCURL_VERSION_NUM >= 0x073900 /* Available since 7.57.0 */
1736 if (d->age >= 4) {
1737 CAAL("brotli_ver_num", d->brotli_ver_num);
1738 CAAS("brotli_version", d->brotli_version);
1739 }
1740 #endif
1741 }
1742 /* }}} */
1743
init_curl_handle_into_zval(zval * curl)1744 php_curl *init_curl_handle_into_zval(zval *curl)
1745 {
1746 php_curl *ch;
1747
1748 object_init_ex(curl, curl_ce);
1749 ch = Z_CURL_P(curl);
1750
1751 init_curl_handle(ch);
1752
1753 return ch;
1754 }
1755
init_curl_handle(php_curl * ch)1756 void init_curl_handle(php_curl *ch)
1757 {
1758 ch->to_free = ecalloc(1, sizeof(struct _php_curl_free));
1759 ch->handlers = ecalloc(1, sizeof(php_curl_handlers));
1760 ch->handlers->write = ecalloc(1, sizeof(php_curl_write));
1761 ch->handlers->write_header = ecalloc(1, sizeof(php_curl_write));
1762 ch->handlers->read = ecalloc(1, sizeof(php_curl_read));
1763 ch->handlers->progress = NULL;
1764 ch->handlers->fnmatch = NULL;
1765 ch->clone = emalloc(sizeof(uint32_t));
1766 *ch->clone = 1;
1767
1768 memset(&ch->err, 0, sizeof(struct _php_curl_error));
1769
1770 zend_llist_init(&ch->to_free->str, sizeof(char *), (llist_dtor_func_t)curl_free_string, 0);
1771 zend_llist_init(&ch->to_free->post, sizeof(struct HttpPost *), (llist_dtor_func_t)curl_free_post, 0);
1772 zend_llist_init(&ch->to_free->stream, sizeof(struct mime_data_cb_arg *), (llist_dtor_func_t)curl_free_cb_arg, 0);
1773
1774 ch->to_free->slist = emalloc(sizeof(HashTable));
1775 zend_hash_init(ch->to_free->slist, 4, NULL, curl_free_slist, 0);
1776 ZVAL_UNDEF(&ch->postfields);
1777 }
1778
1779 /* }}} */
1780
1781 /* {{{ create_certinfo */
create_certinfo(struct curl_certinfo * ci,zval * listcode)1782 static void create_certinfo(struct curl_certinfo *ci, zval *listcode)
1783 {
1784 int i;
1785
1786 if (ci) {
1787 zval certhash;
1788
1789 for (i=0; i<ci->num_of_certs; i++) {
1790 struct curl_slist *slist;
1791
1792 array_init(&certhash);
1793 for (slist = ci->certinfo[i]; slist; slist = slist->next) {
1794 int len;
1795 char s[64];
1796 char *tmp;
1797 strncpy(s, slist->data, sizeof(s));
1798 s[sizeof(s)-1] = '\0';
1799 tmp = memchr(s, ':', sizeof(s));
1800 if(tmp) {
1801 *tmp = '\0';
1802 len = strlen(s);
1803 add_assoc_string(&certhash, s, &slist->data[len+1]);
1804 } else {
1805 php_error_docref(NULL, E_WARNING, "Could not extract hash key from certificate info");
1806 }
1807 }
1808 add_next_index_zval(listcode, &certhash);
1809 }
1810 }
1811 }
1812 /* }}} */
1813
1814 /* {{{ _php_curl_set_default_options()
1815 Set default options for a handle */
_php_curl_set_default_options(php_curl * ch)1816 static void _php_curl_set_default_options(php_curl *ch)
1817 {
1818 char *cainfo;
1819
1820 curl_easy_setopt(ch->cp, CURLOPT_NOPROGRESS, 1);
1821 curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 0);
1822 curl_easy_setopt(ch->cp, CURLOPT_ERRORBUFFER, ch->err.str);
1823 curl_easy_setopt(ch->cp, CURLOPT_WRITEFUNCTION, curl_write);
1824 curl_easy_setopt(ch->cp, CURLOPT_FILE, (void *) ch);
1825 curl_easy_setopt(ch->cp, CURLOPT_READFUNCTION, curl_read);
1826 curl_easy_setopt(ch->cp, CURLOPT_INFILE, (void *) ch);
1827 curl_easy_setopt(ch->cp, CURLOPT_HEADERFUNCTION, curl_write_header);
1828 curl_easy_setopt(ch->cp, CURLOPT_WRITEHEADER, (void *) ch);
1829 #ifndef ZTS
1830 curl_easy_setopt(ch->cp, CURLOPT_DNS_USE_GLOBAL_CACHE, 1);
1831 #endif
1832 curl_easy_setopt(ch->cp, CURLOPT_DNS_CACHE_TIMEOUT, 120);
1833 curl_easy_setopt(ch->cp, CURLOPT_MAXREDIRS, 20); /* prevent infinite redirects */
1834
1835 cainfo = INI_STR("openssl.cafile");
1836 if (!(cainfo && cainfo[0] != '\0')) {
1837 cainfo = INI_STR("curl.cainfo");
1838 }
1839 if (cainfo && cainfo[0] != '\0') {
1840 curl_easy_setopt(ch->cp, CURLOPT_CAINFO, cainfo);
1841 }
1842
1843 #ifdef ZTS
1844 curl_easy_setopt(ch->cp, CURLOPT_NOSIGNAL, 1);
1845 #endif
1846 }
1847 /* }}} */
1848
1849 /* {{{ Initialize a cURL session */
PHP_FUNCTION(curl_init)1850 PHP_FUNCTION(curl_init)
1851 {
1852 php_curl *ch;
1853 CURL *cp;
1854 zend_string *url = NULL;
1855
1856 ZEND_PARSE_PARAMETERS_START(0,1)
1857 Z_PARAM_OPTIONAL
1858 Z_PARAM_STR_OR_NULL(url)
1859 ZEND_PARSE_PARAMETERS_END();
1860
1861 cp = curl_easy_init();
1862 if (!cp) {
1863 php_error_docref(NULL, E_WARNING, "Could not initialize a new cURL handle");
1864 RETURN_FALSE;
1865 }
1866
1867 ch = init_curl_handle_into_zval(return_value);
1868
1869 ch->cp = cp;
1870
1871 ch->handlers->write->method = PHP_CURL_STDOUT;
1872 ch->handlers->read->method = PHP_CURL_DIRECT;
1873 ch->handlers->write_header->method = PHP_CURL_IGNORE;
1874
1875 _php_curl_set_default_options(ch);
1876
1877 if (url) {
1878 if (php_curl_option_url(ch, ZSTR_VAL(url), ZSTR_LEN(url)) == FAILURE) {
1879 zval_ptr_dtor(return_value);
1880 RETURN_FALSE;
1881 }
1882 }
1883 }
1884 /* }}} */
1885
_php_setup_easy_copy_handlers(php_curl * ch,php_curl * source)1886 void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source)
1887 {
1888 if (!Z_ISUNDEF(source->handlers->write->stream)) {
1889 Z_ADDREF(source->handlers->write->stream);
1890 }
1891 ch->handlers->write->stream = source->handlers->write->stream;
1892 ch->handlers->write->method = source->handlers->write->method;
1893 if (!Z_ISUNDEF(source->handlers->read->stream)) {
1894 Z_ADDREF(source->handlers->read->stream);
1895 }
1896 ch->handlers->read->stream = source->handlers->read->stream;
1897 ch->handlers->read->method = source->handlers->read->method;
1898 ch->handlers->write_header->method = source->handlers->write_header->method;
1899 if (!Z_ISUNDEF(source->handlers->write_header->stream)) {
1900 Z_ADDREF(source->handlers->write_header->stream);
1901 }
1902 ch->handlers->write_header->stream = source->handlers->write_header->stream;
1903
1904 ch->handlers->write->fp = source->handlers->write->fp;
1905 ch->handlers->write_header->fp = source->handlers->write_header->fp;
1906 ch->handlers->read->fp = source->handlers->read->fp;
1907 ch->handlers->read->res = source->handlers->read->res;
1908
1909 if (!Z_ISUNDEF(source->handlers->write->func_name)) {
1910 ZVAL_COPY(&ch->handlers->write->func_name, &source->handlers->write->func_name);
1911 }
1912 if (!Z_ISUNDEF(source->handlers->read->func_name)) {
1913 ZVAL_COPY(&ch->handlers->read->func_name, &source->handlers->read->func_name);
1914 }
1915 if (!Z_ISUNDEF(source->handlers->write_header->func_name)) {
1916 ZVAL_COPY(&ch->handlers->write_header->func_name, &source->handlers->write_header->func_name);
1917 }
1918
1919 curl_easy_setopt(ch->cp, CURLOPT_ERRORBUFFER, ch->err.str);
1920 curl_easy_setopt(ch->cp, CURLOPT_FILE, (void *) ch);
1921 curl_easy_setopt(ch->cp, CURLOPT_INFILE, (void *) ch);
1922 curl_easy_setopt(ch->cp, CURLOPT_WRITEHEADER, (void *) ch);
1923 curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA, (void *) ch);
1924
1925 if (source->handlers->progress) {
1926 ch->handlers->progress = ecalloc(1, sizeof(php_curl_progress));
1927 if (!Z_ISUNDEF(source->handlers->progress->func_name)) {
1928 ZVAL_COPY(&ch->handlers->progress->func_name, &source->handlers->progress->func_name);
1929 }
1930 ch->handlers->progress->method = source->handlers->progress->method;
1931 curl_easy_setopt(ch->cp, CURLOPT_PROGRESSDATA, (void *) ch);
1932 }
1933
1934 if (source->handlers->fnmatch) {
1935 ch->handlers->fnmatch = ecalloc(1, sizeof(php_curl_fnmatch));
1936 if (!Z_ISUNDEF(source->handlers->fnmatch->func_name)) {
1937 ZVAL_COPY(&ch->handlers->fnmatch->func_name, &source->handlers->fnmatch->func_name);
1938 }
1939 ch->handlers->fnmatch->method = source->handlers->fnmatch->method;
1940 curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_DATA, (void *) ch);
1941 }
1942
1943 efree(ch->to_free->slist);
1944 efree(ch->to_free);
1945 ch->to_free = source->to_free;
1946 efree(ch->clone);
1947 ch->clone = source->clone;
1948
1949 /* Keep track of cloned copies to avoid invoking curl destructors for every clone */
1950 (*source->clone)++;
1951 }
1952
1953 #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
read_cb(char * buffer,size_t size,size_t nitems,void * arg)1954 static size_t read_cb(char *buffer, size_t size, size_t nitems, void *arg) /* {{{ */
1955 {
1956 struct mime_data_cb_arg *cb_arg = (struct mime_data_cb_arg *) arg;
1957 ssize_t numread;
1958
1959 if (cb_arg->stream == NULL) {
1960 if (!(cb_arg->stream = php_stream_open_wrapper(ZSTR_VAL(cb_arg->filename), "rb", IGNORE_PATH, NULL))) {
1961 return CURL_READFUNC_ABORT;
1962 }
1963 }
1964 numread = php_stream_read(cb_arg->stream, buffer, nitems * size);
1965 if (numread < 0) {
1966 php_stream_close(cb_arg->stream);
1967 cb_arg->stream = NULL;
1968 return CURL_READFUNC_ABORT;
1969 }
1970 return numread;
1971 }
1972 /* }}} */
1973
seek_cb(void * arg,curl_off_t offset,int origin)1974 static int seek_cb(void *arg, curl_off_t offset, int origin) /* {{{ */
1975 {
1976 struct mime_data_cb_arg *cb_arg = (struct mime_data_cb_arg *) arg;
1977 int res;
1978
1979 if (cb_arg->stream == NULL) {
1980 return CURL_SEEKFUNC_CANTSEEK;
1981 }
1982 res = php_stream_seek(cb_arg->stream, offset, origin);
1983 return res == SUCCESS ? CURL_SEEKFUNC_OK : CURL_SEEKFUNC_CANTSEEK;
1984 }
1985 /* }}} */
1986
free_cb(void * arg)1987 static void free_cb(void *arg) /* {{{ */
1988 {
1989 struct mime_data_cb_arg *cb_arg = (struct mime_data_cb_arg *) arg;
1990
1991 if (cb_arg->stream != NULL) {
1992 php_stream_close(cb_arg->stream);
1993 cb_arg->stream = NULL;
1994 }
1995 }
1996 /* }}} */
1997 #endif
1998
build_mime_structure_from_hash(php_curl * ch,zval * zpostfields)1999 static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields) /* {{{ */
2000 {
2001 HashTable *postfields = Z_ARRVAL_P(zpostfields);
2002 CURLcode error = CURLE_OK;
2003 zval *current;
2004 zend_string *string_key;
2005 zend_ulong num_key;
2006 #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2007 curl_mime *mime = NULL;
2008 curl_mimepart *part;
2009 CURLcode form_error;
2010 #else
2011 struct HttpPost *first = NULL;
2012 struct HttpPost *last = NULL;
2013 CURLFORMcode form_error;
2014 #endif
2015
2016 #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2017 if (zend_hash_num_elements(postfields) > 0) {
2018 mime = curl_mime_init(ch->cp);
2019 if (mime == NULL) {
2020 return FAILURE;
2021 }
2022 }
2023 #endif
2024
2025 ZEND_HASH_FOREACH_KEY_VAL(postfields, num_key, string_key, current) {
2026 zend_string *postval, *tmp_postval;
2027 /* Pretend we have a string_key here */
2028 if (!string_key) {
2029 string_key = zend_long_to_str(num_key);
2030 } else {
2031 zend_string_addref(string_key);
2032 }
2033
2034 ZVAL_DEREF(current);
2035 if (Z_TYPE_P(current) == IS_OBJECT &&
2036 instanceof_function(Z_OBJCE_P(current), curl_CURLFile_class)) {
2037 /* new-style file upload */
2038 zval *prop, rv;
2039 char *type = NULL, *filename = NULL;
2040 #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2041 struct mime_data_cb_arg *cb_arg;
2042 php_stream *stream;
2043 php_stream_statbuf ssb;
2044 size_t filesize = -1;
2045 curl_seek_callback seekfunc = seek_cb;
2046 #endif
2047
2048 prop = zend_read_property(curl_CURLFile_class, Z_OBJ_P(current), "name", sizeof("name")-1, 0, &rv);
2049 ZVAL_DEREF(prop);
2050 if (Z_TYPE_P(prop) != IS_STRING) {
2051 php_error_docref(NULL, E_WARNING, "Invalid filename for key %s", ZSTR_VAL(string_key));
2052 } else {
2053 postval = Z_STR_P(prop);
2054
2055 if (php_check_open_basedir(ZSTR_VAL(postval))) {
2056 return 1;
2057 }
2058
2059 prop = zend_read_property(curl_CURLFile_class, Z_OBJ_P(current), "mime", sizeof("mime")-1, 0, &rv);
2060 ZVAL_DEREF(prop);
2061 if (Z_TYPE_P(prop) == IS_STRING && Z_STRLEN_P(prop) > 0) {
2062 type = Z_STRVAL_P(prop);
2063 }
2064 prop = zend_read_property(curl_CURLFile_class, Z_OBJ_P(current), "postname", sizeof("postname")-1, 0, &rv);
2065 ZVAL_DEREF(prop);
2066 if (Z_TYPE_P(prop) == IS_STRING && Z_STRLEN_P(prop) > 0) {
2067 filename = Z_STRVAL_P(prop);
2068 }
2069
2070 #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2071 zval_ptr_dtor(&ch->postfields);
2072 ZVAL_COPY(&ch->postfields, zpostfields);
2073
2074 if ((stream = php_stream_open_wrapper(ZSTR_VAL(postval), "rb", STREAM_MUST_SEEK, NULL))) {
2075 if (!stream->readfilters.head && !php_stream_stat(stream, &ssb)) {
2076 filesize = ssb.sb.st_size;
2077 }
2078 } else {
2079 seekfunc = NULL;
2080 }
2081
2082 cb_arg = emalloc(sizeof *cb_arg);
2083 cb_arg->filename = zend_string_copy(postval);
2084 cb_arg->stream = stream;
2085
2086 part = curl_mime_addpart(mime);
2087 if (part == NULL) {
2088 zend_string_release_ex(string_key, 0);
2089 return FAILURE;
2090 }
2091 if ((form_error = curl_mime_name(part, ZSTR_VAL(string_key))) != CURLE_OK
2092 || (form_error = curl_mime_data_cb(part, filesize, read_cb, seekfunc, free_cb, cb_arg)) != CURLE_OK
2093 || (form_error = curl_mime_filename(part, filename ? filename : ZSTR_VAL(postval))) != CURLE_OK
2094 || (form_error = curl_mime_type(part, type ? type : "application/octet-stream")) != CURLE_OK) {
2095 error = form_error;
2096 }
2097 zend_llist_add_element(&ch->to_free->stream, &cb_arg);
2098 #else
2099 form_error = curl_formadd(&first, &last,
2100 CURLFORM_COPYNAME, ZSTR_VAL(string_key),
2101 CURLFORM_NAMELENGTH, ZSTR_LEN(string_key),
2102 CURLFORM_FILENAME, filename ? filename : ZSTR_VAL(postval),
2103 CURLFORM_CONTENTTYPE, type ? type : "application/octet-stream",
2104 CURLFORM_FILE, ZSTR_VAL(postval),
2105 CURLFORM_END);
2106 if (form_error != CURL_FORMADD_OK) {
2107 /* Not nice to convert between enums but we only have place for one error type */
2108 error = (CURLcode)form_error;
2109 }
2110 #endif
2111 }
2112
2113 zend_string_release_ex(string_key, 0);
2114 continue;
2115 }
2116
2117 postval = zval_get_tmp_string(current, &tmp_postval);
2118
2119 #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2120 part = curl_mime_addpart(mime);
2121 if (part == NULL) {
2122 zend_tmp_string_release(tmp_postval);
2123 zend_string_release_ex(string_key, 0);
2124 return FAILURE;
2125 }
2126 if ((form_error = curl_mime_name(part, ZSTR_VAL(string_key))) != CURLE_OK
2127 || (form_error = curl_mime_data(part, ZSTR_VAL(postval), ZSTR_LEN(postval))) != CURLE_OK) {
2128 error = form_error;
2129 }
2130 #else
2131 /* The arguments after _NAMELENGTH and _CONTENTSLENGTH
2132 * must be explicitly cast to long in curl_formadd
2133 * use since curl needs a long not an int. */
2134 form_error = curl_formadd(&first, &last,
2135 CURLFORM_COPYNAME, ZSTR_VAL(string_key),
2136 CURLFORM_NAMELENGTH, ZSTR_LEN(string_key),
2137 CURLFORM_COPYCONTENTS, ZSTR_VAL(postval),
2138 CURLFORM_CONTENTSLENGTH, ZSTR_LEN(postval),
2139 CURLFORM_END);
2140
2141 if (form_error != CURL_FORMADD_OK) {
2142 /* Not nice to convert between enums but we only have place for one error type */
2143 error = (CURLcode)form_error;
2144 }
2145 #endif
2146 zend_tmp_string_release(tmp_postval);
2147 zend_string_release_ex(string_key, 0);
2148 } ZEND_HASH_FOREACH_END();
2149
2150 SAVE_CURL_ERROR(ch, error);
2151 if (error != CURLE_OK) {
2152 return FAILURE;
2153 }
2154
2155 if ((*ch->clone) == 1) {
2156 zend_llist_clean(&ch->to_free->post);
2157 }
2158 #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2159 zend_llist_add_element(&ch->to_free->post, &mime);
2160 error = curl_easy_setopt(ch->cp, CURLOPT_MIMEPOST, mime);
2161 #else
2162 zend_llist_add_element(&ch->to_free->post, &first);
2163 error = curl_easy_setopt(ch->cp, CURLOPT_HTTPPOST, first);
2164 #endif
2165
2166 SAVE_CURL_ERROR(ch, error);
2167 return error == CURLE_OK ? SUCCESS : FAILURE;
2168 }
2169 /* }}} */
2170
2171 /* {{{ Copy a cURL handle along with all of it's preferences */
PHP_FUNCTION(curl_copy_handle)2172 PHP_FUNCTION(curl_copy_handle)
2173 {
2174 php_curl *ch;
2175 CURL *cp;
2176 zval *zid;
2177 php_curl *dupch;
2178 zval *postfields;
2179
2180 ZEND_PARSE_PARAMETERS_START(1,1)
2181 Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
2182 ZEND_PARSE_PARAMETERS_END();
2183
2184 ch = Z_CURL_P(zid);
2185
2186 cp = curl_easy_duphandle(ch->cp);
2187 if (!cp) {
2188 php_error_docref(NULL, E_WARNING, "Cannot duplicate cURL handle");
2189 RETURN_FALSE;
2190 }
2191
2192 dupch = init_curl_handle_into_zval(return_value);
2193 dupch->cp = cp;
2194
2195 _php_setup_easy_copy_handlers(dupch, ch);
2196
2197 postfields = &ch->postfields;
2198 if (Z_TYPE_P(postfields) != IS_UNDEF) {
2199 if (build_mime_structure_from_hash(dupch, postfields) != SUCCESS) {
2200 zval_ptr_dtor(return_value);
2201 php_error_docref(NULL, E_WARNING, "Cannot rebuild mime structure");
2202 RETURN_FALSE;
2203 }
2204 }
2205 }
2206 /* }}} */
2207
_php_curl_setopt(php_curl * ch,zend_long option,zval * zvalue,bool is_array_config)2208 static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue, bool is_array_config) /* {{{ */
2209 {
2210 CURLcode error = CURLE_OK;
2211 zend_long lval;
2212
2213 switch (option) {
2214 /* Long options */
2215 case CURLOPT_SSL_VERIFYHOST:
2216 lval = zval_get_long(zvalue);
2217 if (lval == 1) {
2218 php_error_docref(NULL, E_NOTICE, "CURLOPT_SSL_VERIFYHOST no longer accepts the value 1, value 2 will be used instead");
2219 error = curl_easy_setopt(ch->cp, option, 2);
2220 break;
2221 }
2222 case CURLOPT_AUTOREFERER:
2223 case CURLOPT_BUFFERSIZE:
2224 case CURLOPT_CONNECTTIMEOUT:
2225 case CURLOPT_COOKIESESSION:
2226 case CURLOPT_CRLF:
2227 case CURLOPT_DNS_CACHE_TIMEOUT:
2228 case CURLOPT_DNS_USE_GLOBAL_CACHE:
2229 case CURLOPT_FAILONERROR:
2230 case CURLOPT_FILETIME:
2231 case CURLOPT_FORBID_REUSE:
2232 case CURLOPT_FRESH_CONNECT:
2233 case CURLOPT_FTP_USE_EPRT:
2234 case CURLOPT_FTP_USE_EPSV:
2235 case CURLOPT_HEADER:
2236 case CURLOPT_HTTPGET:
2237 case CURLOPT_HTTPPROXYTUNNEL:
2238 case CURLOPT_HTTP_VERSION:
2239 case CURLOPT_INFILESIZE:
2240 case CURLOPT_LOW_SPEED_LIMIT:
2241 case CURLOPT_LOW_SPEED_TIME:
2242 case CURLOPT_MAXCONNECTS:
2243 case CURLOPT_MAXREDIRS:
2244 case CURLOPT_NETRC:
2245 case CURLOPT_NOBODY:
2246 case CURLOPT_NOPROGRESS:
2247 case CURLOPT_NOSIGNAL:
2248 case CURLOPT_PORT:
2249 case CURLOPT_POST:
2250 case CURLOPT_PROXYPORT:
2251 case CURLOPT_PROXYTYPE:
2252 case CURLOPT_PUT:
2253 case CURLOPT_RESUME_FROM:
2254 case CURLOPT_SSLVERSION:
2255 case CURLOPT_SSL_VERIFYPEER:
2256 case CURLOPT_TIMECONDITION:
2257 case CURLOPT_TIMEOUT:
2258 case CURLOPT_TIMEVALUE:
2259 case CURLOPT_TRANSFERTEXT:
2260 case CURLOPT_UNRESTRICTED_AUTH:
2261 case CURLOPT_UPLOAD:
2262 case CURLOPT_VERBOSE:
2263 case CURLOPT_HTTPAUTH:
2264 case CURLOPT_FTP_CREATE_MISSING_DIRS:
2265 case CURLOPT_PROXYAUTH:
2266 case CURLOPT_FTP_RESPONSE_TIMEOUT:
2267 case CURLOPT_IPRESOLVE:
2268 case CURLOPT_MAXFILESIZE:
2269 case CURLOPT_TCP_NODELAY:
2270 case CURLOPT_FTPSSLAUTH:
2271 case CURLOPT_IGNORE_CONTENT_LENGTH:
2272 case CURLOPT_FTP_SKIP_PASV_IP:
2273 case CURLOPT_FTP_FILEMETHOD:
2274 case CURLOPT_CONNECT_ONLY:
2275 case CURLOPT_LOCALPORT:
2276 case CURLOPT_LOCALPORTRANGE:
2277 case CURLOPT_SSL_SESSIONID_CACHE:
2278 case CURLOPT_FTP_SSL_CCC:
2279 case CURLOPT_SSH_AUTH_TYPES:
2280 case CURLOPT_CONNECTTIMEOUT_MS:
2281 case CURLOPT_HTTP_CONTENT_DECODING:
2282 case CURLOPT_HTTP_TRANSFER_DECODING:
2283 case CURLOPT_TIMEOUT_MS:
2284 case CURLOPT_NEW_DIRECTORY_PERMS:
2285 case CURLOPT_NEW_FILE_PERMS:
2286 case CURLOPT_USE_SSL:
2287 case CURLOPT_APPEND:
2288 case CURLOPT_DIRLISTONLY:
2289 case CURLOPT_PROXY_TRANSFER_MODE:
2290 case CURLOPT_ADDRESS_SCOPE:
2291 case CURLOPT_CERTINFO:
2292 case CURLOPT_PROTOCOLS:
2293 case CURLOPT_REDIR_PROTOCOLS:
2294 case CURLOPT_SOCKS5_GSSAPI_NEC:
2295 case CURLOPT_TFTP_BLKSIZE:
2296 case CURLOPT_FTP_USE_PRET:
2297 case CURLOPT_RTSP_CLIENT_CSEQ:
2298 case CURLOPT_RTSP_REQUEST:
2299 case CURLOPT_RTSP_SERVER_CSEQ:
2300 case CURLOPT_WILDCARDMATCH:
2301 case CURLOPT_GSSAPI_DELEGATION:
2302 case CURLOPT_ACCEPTTIMEOUT_MS:
2303 case CURLOPT_SSL_OPTIONS:
2304 case CURLOPT_TCP_KEEPALIVE:
2305 case CURLOPT_TCP_KEEPIDLE:
2306 case CURLOPT_TCP_KEEPINTVL:
2307 #if LIBCURL_VERSION_NUM >= 0x071f00 /* Available since 7.31.0 */
2308 case CURLOPT_SASL_IR:
2309 #endif
2310 #if LIBCURL_VERSION_NUM >= 0x072400 /* Available since 7.36.0 */
2311 case CURLOPT_EXPECT_100_TIMEOUT_MS:
2312 case CURLOPT_SSL_ENABLE_ALPN:
2313 case CURLOPT_SSL_ENABLE_NPN:
2314 #endif
2315 #if LIBCURL_VERSION_NUM >= 0x072500 /* Available since 7.37.0 */
2316 case CURLOPT_HEADEROPT:
2317 #endif
2318 #if LIBCURL_VERSION_NUM >= 0x072900 /* Available since 7.41.0 */
2319 case CURLOPT_SSL_VERIFYSTATUS:
2320 #endif
2321 #if LIBCURL_VERSION_NUM >= 0x072a00 /* Available since 7.42.0 */
2322 case CURLOPT_PATH_AS_IS:
2323 case CURLOPT_SSL_FALSESTART:
2324 #endif
2325 #if LIBCURL_VERSION_NUM >= 0x072b00 /* Available since 7.43.0 */
2326 case CURLOPT_PIPEWAIT:
2327 #endif
2328 #if LIBCURL_VERSION_NUM >= 0x072e00 /* Available since 7.46.0 */
2329 case CURLOPT_STREAM_WEIGHT:
2330 #endif
2331 #if LIBCURL_VERSION_NUM >= 0x073000 /* Available since 7.48.0 */
2332 case CURLOPT_TFTP_NO_OPTIONS:
2333 #endif
2334 #if LIBCURL_VERSION_NUM >= 0x073100 /* Available since 7.49.0 */
2335 case CURLOPT_TCP_FASTOPEN:
2336 #endif
2337 #if LIBCURL_VERSION_NUM >= 0x073300 /* Available since 7.51.0 */
2338 case CURLOPT_KEEP_SENDING_ON_ERROR:
2339 #endif
2340 #if LIBCURL_VERSION_NUM >= 0x073400 /* Available since 7.52.0 */
2341 case CURLOPT_PROXY_SSL_OPTIONS:
2342 case CURLOPT_PROXY_SSL_VERIFYHOST:
2343 case CURLOPT_PROXY_SSL_VERIFYPEER:
2344 case CURLOPT_PROXY_SSLVERSION:
2345 #endif
2346 #if LIBCURL_VERSION_NUM >= 0x073600 /* Available since 7.54.0 */
2347 case CURLOPT_SUPPRESS_CONNECT_HEADERS:
2348 #endif
2349 #if LIBCURL_VERSION_NUM >= 0x073700 /* Available since 7.55.0 */
2350 case CURLOPT_SOCKS5_AUTH:
2351 #endif
2352 #if LIBCURL_VERSION_NUM >= 0x073800 /* Available since 7.56.0 */
2353 case CURLOPT_SSH_COMPRESSION:
2354 #endif
2355 #if LIBCURL_VERSION_NUM >= 0x073b00 /* Available since 7.59.0 */
2356 case CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS:
2357 #endif
2358 #if LIBCURL_VERSION_NUM >= 0x073c00 /* Available since 7.60.0 */
2359 case CURLOPT_DNS_SHUFFLE_ADDRESSES:
2360 case CURLOPT_HAPROXYPROTOCOL:
2361 #endif
2362 #if LIBCURL_VERSION_NUM >= 0x073d00 /* Available since 7.61.0 */
2363 case CURLOPT_DISALLOW_USERNAME_IN_URL:
2364 #endif
2365 #if LIBCURL_VERSION_NUM >= 0x074000 /* Available since 7.64.0 */
2366 case CURLOPT_HTTP09_ALLOWED:
2367 #endif
2368 lval = zval_get_long(zvalue);
2369 if ((option == CURLOPT_PROTOCOLS || option == CURLOPT_REDIR_PROTOCOLS) &&
2370 (PG(open_basedir) && *PG(open_basedir)) && (lval & CURLPROTO_FILE)) {
2371 php_error_docref(NULL, E_WARNING, "CURLPROTO_FILE cannot be activated when an open_basedir is set");
2372 return 1;
2373 }
2374 # if defined(ZTS)
2375 if (option == CURLOPT_DNS_USE_GLOBAL_CACHE && lval) {
2376 php_error_docref(NULL, E_WARNING, "CURLOPT_DNS_USE_GLOBAL_CACHE cannot be activated when thread safety is enabled");
2377 return 1;
2378 }
2379 # endif
2380 error = curl_easy_setopt(ch->cp, option, lval);
2381 break;
2382 case CURLOPT_SAFE_UPLOAD:
2383 if (!zend_is_true(zvalue)) {
2384 zend_value_error("%s(): Disabling safe uploads is no longer supported", get_active_function_name());
2385 return FAILURE;
2386 }
2387 break;
2388
2389 /* String options */
2390 case CURLOPT_CAINFO:
2391 case CURLOPT_CAPATH:
2392 case CURLOPT_COOKIE:
2393 case CURLOPT_EGDSOCKET:
2394 case CURLOPT_INTERFACE:
2395 case CURLOPT_PROXY:
2396 case CURLOPT_PROXYUSERPWD:
2397 case CURLOPT_REFERER:
2398 case CURLOPT_SSLCERTTYPE:
2399 case CURLOPT_SSLENGINE:
2400 case CURLOPT_SSLENGINE_DEFAULT:
2401 case CURLOPT_SSLKEY:
2402 case CURLOPT_SSLKEYPASSWD:
2403 case CURLOPT_SSLKEYTYPE:
2404 case CURLOPT_SSL_CIPHER_LIST:
2405 case CURLOPT_USERAGENT:
2406 case CURLOPT_USERPWD:
2407 case CURLOPT_COOKIELIST:
2408 case CURLOPT_FTP_ALTERNATIVE_TO_USER:
2409 case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
2410 case CURLOPT_PASSWORD:
2411 case CURLOPT_PROXYPASSWORD:
2412 case CURLOPT_PROXYUSERNAME:
2413 case CURLOPT_USERNAME:
2414 case CURLOPT_NOPROXY:
2415 case CURLOPT_SOCKS5_GSSAPI_SERVICE:
2416 case CURLOPT_MAIL_FROM:
2417 case CURLOPT_RTSP_STREAM_URI:
2418 case CURLOPT_RTSP_TRANSPORT:
2419 case CURLOPT_TLSAUTH_TYPE:
2420 case CURLOPT_TLSAUTH_PASSWORD:
2421 case CURLOPT_TLSAUTH_USERNAME:
2422 case CURLOPT_ACCEPT_ENCODING:
2423 case CURLOPT_TRANSFER_ENCODING:
2424 case CURLOPT_DNS_SERVERS:
2425 case CURLOPT_MAIL_AUTH:
2426 #if LIBCURL_VERSION_NUM >= 0x072200 /* Available since 7.34.0 */
2427 case CURLOPT_LOGIN_OPTIONS:
2428 #endif
2429 #if LIBCURL_VERSION_NUM >= 0x072700 /* Available since 7.39.0 */
2430 case CURLOPT_PINNEDPUBLICKEY:
2431 #endif
2432 #if LIBCURL_VERSION_NUM >= 0x072b00 /* Available since 7.43.0 */
2433 case CURLOPT_PROXY_SERVICE_NAME:
2434 case CURLOPT_SERVICE_NAME:
2435 #endif
2436 #if LIBCURL_VERSION_NUM >= 0x072d00 /* Available since 7.45.0 */
2437 case CURLOPT_DEFAULT_PROTOCOL:
2438 #endif
2439 #if LIBCURL_VERSION_NUM >= 0x073400 /* Available since 7.52.0 */
2440 case CURLOPT_PRE_PROXY:
2441 case CURLOPT_PROXY_CAINFO:
2442 case CURLOPT_PROXY_CAPATH:
2443 case CURLOPT_PROXY_CRLFILE:
2444 case CURLOPT_PROXY_KEYPASSWD:
2445 case CURLOPT_PROXY_PINNEDPUBLICKEY:
2446 case CURLOPT_PROXY_SSL_CIPHER_LIST:
2447 case CURLOPT_PROXY_SSLCERT:
2448 case CURLOPT_PROXY_SSLCERTTYPE:
2449 case CURLOPT_PROXY_SSLKEY:
2450 case CURLOPT_PROXY_SSLKEYTYPE:
2451 case CURLOPT_PROXY_TLSAUTH_PASSWORD:
2452 case CURLOPT_PROXY_TLSAUTH_TYPE:
2453 case CURLOPT_PROXY_TLSAUTH_USERNAME:
2454 #endif
2455 #if LIBCURL_VERSION_NUM >= 0x073500 /* Available since 7.53.0 */
2456 case CURLOPT_ABSTRACT_UNIX_SOCKET:
2457 #endif
2458 #if LIBCURL_VERSION_NUM >= 0x073700 /* Available since 7.55.0 */
2459 case CURLOPT_REQUEST_TARGET:
2460 #endif
2461 #if LIBCURL_VERSION_NUM >= 0x073d00 /* Available since 7.61.0 */
2462 case CURLOPT_PROXY_TLS13_CIPHERS:
2463 case CURLOPT_TLS13_CIPHERS:
2464 #endif
2465 {
2466 zend_string *tmp_str;
2467 zend_string *str = zval_get_tmp_string(zvalue, &tmp_str);
2468 int ret = php_curl_option_str(ch, option, ZSTR_VAL(str), ZSTR_LEN(str), 0);
2469 zend_tmp_string_release(tmp_str);
2470 return ret;
2471 }
2472
2473 /* Curl nullable string options */
2474 case CURLOPT_CUSTOMREQUEST:
2475 case CURLOPT_FTPPORT:
2476 case CURLOPT_RANGE:
2477 case CURLOPT_FTP_ACCOUNT:
2478 case CURLOPT_RTSP_SESSION_ID:
2479 #if LIBCURL_VERSION_NUM >= 0x072100 /* Available since 7.33.0 */
2480 case CURLOPT_DNS_INTERFACE:
2481 case CURLOPT_DNS_LOCAL_IP4:
2482 case CURLOPT_DNS_LOCAL_IP6:
2483 case CURLOPT_XOAUTH2_BEARER:
2484 #endif
2485 #if LIBCURL_VERSION_NUM >= 0x072800 /* Available since 7.40.0 */
2486 case CURLOPT_UNIX_SOCKET_PATH:
2487 #endif
2488 case CURLOPT_KRBLEVEL:
2489 {
2490 if (Z_ISNULL_P(zvalue)) {
2491 error = curl_easy_setopt(ch->cp, option, NULL);
2492 } else {
2493 zend_string *tmp_str;
2494 zend_string *str = zval_get_tmp_string(zvalue, &tmp_str);
2495 int ret = php_curl_option_str(ch, option, ZSTR_VAL(str), ZSTR_LEN(str), 0);
2496 zend_tmp_string_release(tmp_str);
2497 return ret;
2498 }
2499 break;
2500 }
2501
2502 /* Curl private option */
2503 case CURLOPT_PRIVATE:
2504 {
2505 zend_string *tmp_str;
2506 zend_string *str = zval_get_tmp_string(zvalue, &tmp_str);
2507 int ret = php_curl_option_str(ch, option, ZSTR_VAL(str), ZSTR_LEN(str), 1);
2508 zend_tmp_string_release(tmp_str);
2509 return ret;
2510 }
2511
2512 /* Curl url option */
2513 case CURLOPT_URL:
2514 {
2515 zend_string *tmp_str;
2516 zend_string *str = zval_get_tmp_string(zvalue, &tmp_str);
2517 int ret = php_curl_option_url(ch, ZSTR_VAL(str), ZSTR_LEN(str));
2518 zend_tmp_string_release(tmp_str);
2519 return ret;
2520 }
2521
2522 /* Curl file handle options */
2523 case CURLOPT_FILE:
2524 case CURLOPT_INFILE:
2525 case CURLOPT_STDERR:
2526 case CURLOPT_WRITEHEADER: {
2527 FILE *fp = NULL;
2528 php_stream *what = NULL;
2529
2530 if (Z_TYPE_P(zvalue) != IS_NULL) {
2531 what = (php_stream *)zend_fetch_resource2_ex(zvalue, "File-Handle", php_file_le_stream(), php_file_le_pstream());
2532 if (!what) {
2533 return FAILURE;
2534 }
2535
2536 if (FAILURE == php_stream_cast(what, PHP_STREAM_AS_STDIO, (void *) &fp, REPORT_ERRORS)) {
2537 return FAILURE;
2538 }
2539
2540 if (!fp) {
2541 return FAILURE;
2542 }
2543 }
2544
2545 error = CURLE_OK;
2546 switch (option) {
2547 case CURLOPT_FILE:
2548 if (!what) {
2549 if (!Z_ISUNDEF(ch->handlers->write->stream)) {
2550 zval_ptr_dtor(&ch->handlers->write->stream);
2551 ZVAL_UNDEF(&ch->handlers->write->stream);
2552 }
2553 ch->handlers->write->fp = NULL;
2554 ch->handlers->write->method = PHP_CURL_STDOUT;
2555 } else if (what->mode[0] != 'r' || what->mode[1] == '+') {
2556 zval_ptr_dtor(&ch->handlers->write->stream);
2557 ch->handlers->write->fp = fp;
2558 ch->handlers->write->method = PHP_CURL_FILE;
2559 ZVAL_COPY(&ch->handlers->write->stream, zvalue);
2560 } else {
2561 zend_value_error("%s(): The provided file handle must be writable", get_active_function_name());
2562 return FAILURE;
2563 }
2564 break;
2565 case CURLOPT_WRITEHEADER:
2566 if (!what) {
2567 if (!Z_ISUNDEF(ch->handlers->write_header->stream)) {
2568 zval_ptr_dtor(&ch->handlers->write_header->stream);
2569 ZVAL_UNDEF(&ch->handlers->write_header->stream);
2570 }
2571 ch->handlers->write_header->fp = NULL;
2572 ch->handlers->write_header->method = PHP_CURL_IGNORE;
2573 } else if (what->mode[0] != 'r' || what->mode[1] == '+') {
2574 zval_ptr_dtor(&ch->handlers->write_header->stream);
2575 ch->handlers->write_header->fp = fp;
2576 ch->handlers->write_header->method = PHP_CURL_FILE;
2577 ZVAL_COPY(&ch->handlers->write_header->stream, zvalue);
2578 } else {
2579 zend_value_error("%s(): The provided file handle must be writable", get_active_function_name());
2580 return FAILURE;
2581 }
2582 break;
2583 case CURLOPT_INFILE:
2584 if (!what) {
2585 if (!Z_ISUNDEF(ch->handlers->read->stream)) {
2586 zval_ptr_dtor(&ch->handlers->read->stream);
2587 ZVAL_UNDEF(&ch->handlers->read->stream);
2588 }
2589 ch->handlers->read->fp = NULL;
2590 ch->handlers->read->res = NULL;
2591 } else {
2592 zval_ptr_dtor(&ch->handlers->read->stream);
2593 ch->handlers->read->fp = fp;
2594 ch->handlers->read->res = Z_RES_P(zvalue);
2595 ZVAL_COPY(&ch->handlers->read->stream, zvalue);
2596 }
2597 break;
2598 case CURLOPT_STDERR:
2599 if (!what) {
2600 if (!Z_ISUNDEF(ch->handlers->std_err)) {
2601 zval_ptr_dtor(&ch->handlers->std_err);
2602 ZVAL_UNDEF(&ch->handlers->std_err);
2603 }
2604 } else if (what->mode[0] != 'r' || what->mode[1] == '+') {
2605 zval_ptr_dtor(&ch->handlers->std_err);
2606 ZVAL_COPY(&ch->handlers->std_err, zvalue);
2607 } else {
2608 zend_value_error("%s(): The provided file handle must be writable", get_active_function_name());
2609 return FAILURE;
2610 }
2611 /* break omitted intentionally */
2612 default:
2613 error = curl_easy_setopt(ch->cp, option, fp);
2614 break;
2615 }
2616 break;
2617 }
2618
2619 /* Curl linked list options */
2620 case CURLOPT_HTTP200ALIASES:
2621 case CURLOPT_HTTPHEADER:
2622 case CURLOPT_POSTQUOTE:
2623 case CURLOPT_PREQUOTE:
2624 case CURLOPT_QUOTE:
2625 case CURLOPT_TELNETOPTIONS:
2626 case CURLOPT_MAIL_RCPT:
2627 case CURLOPT_RESOLVE:
2628 #if LIBCURL_VERSION_NUM >= 0x072500 /* Available since 7.37.0 */
2629 case CURLOPT_PROXYHEADER:
2630 #endif
2631 #if LIBCURL_VERSION_NUM >= 0x073100 /* Available since 7.49.0 */
2632 case CURLOPT_CONNECT_TO:
2633 #endif
2634 {
2635 zval *current;
2636 HashTable *ph;
2637 zend_string *val, *tmp_val;
2638 struct curl_slist *slist = NULL;
2639
2640 if (Z_TYPE_P(zvalue) != IS_ARRAY) {
2641 char *name = NULL;
2642 switch (option) {
2643 case CURLOPT_HTTPHEADER:
2644 name = "CURLOPT_HTTPHEADER";
2645 break;
2646 case CURLOPT_QUOTE:
2647 name = "CURLOPT_QUOTE";
2648 break;
2649 case CURLOPT_HTTP200ALIASES:
2650 name = "CURLOPT_HTTP200ALIASES";
2651 break;
2652 case CURLOPT_POSTQUOTE:
2653 name = "CURLOPT_POSTQUOTE";
2654 break;
2655 case CURLOPT_PREQUOTE:
2656 name = "CURLOPT_PREQUOTE";
2657 break;
2658 case CURLOPT_TELNETOPTIONS:
2659 name = "CURLOPT_TELNETOPTIONS";
2660 break;
2661 case CURLOPT_MAIL_RCPT:
2662 name = "CURLOPT_MAIL_RCPT";
2663 break;
2664 case CURLOPT_RESOLVE:
2665 name = "CURLOPT_RESOLVE";
2666 break;
2667 #if LIBCURL_VERSION_NUM >= 0x072500 /* Available since 7.37.0 */
2668 case CURLOPT_PROXYHEADER:
2669 name = "CURLOPT_PROXYHEADER";
2670 break;
2671 #endif
2672 #if LIBCURL_VERSION_NUM >= 0x073100 /* Available since 7.49.0 */
2673 case CURLOPT_CONNECT_TO:
2674 name = "CURLOPT_CONNECT_TO";
2675 break;
2676 #endif
2677 }
2678
2679 zend_type_error("%s(): The %s option must have an array value", get_active_function_name(), name);
2680 return FAILURE;
2681 }
2682
2683 ph = Z_ARRVAL_P(zvalue);
2684 ZEND_HASH_FOREACH_VAL(ph, current) {
2685 ZVAL_DEREF(current);
2686 val = zval_get_tmp_string(current, &tmp_val);
2687 slist = curl_slist_append(slist, ZSTR_VAL(val));
2688 zend_tmp_string_release(tmp_val);
2689 if (!slist) {
2690 php_error_docref(NULL, E_WARNING, "Could not build curl_slist");
2691 return 1;
2692 }
2693 } ZEND_HASH_FOREACH_END();
2694
2695 if (slist) {
2696 if ((*ch->clone) == 1) {
2697 zend_hash_index_update_ptr(ch->to_free->slist, option, slist);
2698 } else {
2699 zend_hash_next_index_insert_ptr(ch->to_free->slist, slist);
2700 }
2701 }
2702
2703 error = curl_easy_setopt(ch->cp, option, slist);
2704
2705 break;
2706 }
2707
2708 case CURLOPT_BINARYTRANSFER:
2709 /* Do nothing, just backward compatibility */
2710 break;
2711
2712 case CURLOPT_FOLLOWLOCATION:
2713 lval = zend_is_true(zvalue);
2714 error = curl_easy_setopt(ch->cp, option, lval);
2715 break;
2716
2717 case CURLOPT_HEADERFUNCTION:
2718 if (!Z_ISUNDEF(ch->handlers->write_header->func_name)) {
2719 zval_ptr_dtor(&ch->handlers->write_header->func_name);
2720 ch->handlers->write_header->fci_cache = empty_fcall_info_cache;
2721 }
2722 ZVAL_COPY(&ch->handlers->write_header->func_name, zvalue);
2723 ch->handlers->write_header->method = PHP_CURL_USER;
2724 break;
2725
2726 case CURLOPT_POSTFIELDS:
2727 if (Z_TYPE_P(zvalue) == IS_ARRAY) {
2728 if (zend_hash_num_elements(HASH_OF(zvalue)) == 0) {
2729 /* no need to build the mime structure for empty hashtables;
2730 also works around https://github.com/curl/curl/issues/6455 */
2731 curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDS, "");
2732 error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, 0);
2733 } else {
2734 return build_mime_structure_from_hash(ch, zvalue);
2735 }
2736 } else {
2737 zend_string *tmp_str;
2738 zend_string *str = zval_get_tmp_string(zvalue, &tmp_str);
2739 /* with curl 7.17.0 and later, we can use COPYPOSTFIELDS, but we have to provide size before */
2740 error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, ZSTR_LEN(str));
2741 error = curl_easy_setopt(ch->cp, CURLOPT_COPYPOSTFIELDS, ZSTR_VAL(str));
2742 zend_tmp_string_release(tmp_str);
2743 }
2744 break;
2745
2746 case CURLOPT_PROGRESSFUNCTION:
2747 curl_easy_setopt(ch->cp, CURLOPT_PROGRESSFUNCTION, curl_progress);
2748 curl_easy_setopt(ch->cp, CURLOPT_PROGRESSDATA, ch);
2749 if (ch->handlers->progress == NULL) {
2750 ch->handlers->progress = ecalloc(1, sizeof(php_curl_progress));
2751 } else if (!Z_ISUNDEF(ch->handlers->progress->func_name)) {
2752 zval_ptr_dtor(&ch->handlers->progress->func_name);
2753 ch->handlers->progress->fci_cache = empty_fcall_info_cache;
2754 }
2755 ZVAL_COPY(&ch->handlers->progress->func_name, zvalue);
2756 ch->handlers->progress->method = PHP_CURL_USER;
2757 break;
2758
2759 case CURLOPT_READFUNCTION:
2760 if (!Z_ISUNDEF(ch->handlers->read->func_name)) {
2761 zval_ptr_dtor(&ch->handlers->read->func_name);
2762 ch->handlers->read->fci_cache = empty_fcall_info_cache;
2763 }
2764 ZVAL_COPY(&ch->handlers->read->func_name, zvalue);
2765 ch->handlers->read->method = PHP_CURL_USER;
2766 break;
2767
2768 case CURLOPT_RETURNTRANSFER:
2769 if (zend_is_true(zvalue)) {
2770 ch->handlers->write->method = PHP_CURL_RETURN;
2771 } else {
2772 ch->handlers->write->method = PHP_CURL_STDOUT;
2773 }
2774 break;
2775
2776 case CURLOPT_WRITEFUNCTION:
2777 if (!Z_ISUNDEF(ch->handlers->write->func_name)) {
2778 zval_ptr_dtor(&ch->handlers->write->func_name);
2779 ch->handlers->write->fci_cache = empty_fcall_info_cache;
2780 }
2781 ZVAL_COPY(&ch->handlers->write->func_name, zvalue);
2782 ch->handlers->write->method = PHP_CURL_USER;
2783 break;
2784
2785 /* Curl off_t options */
2786 case CURLOPT_MAX_RECV_SPEED_LARGE:
2787 case CURLOPT_MAX_SEND_SPEED_LARGE:
2788 #if LIBCURL_VERSION_NUM >= 0x073b00 /* Available since 7.59.0 */
2789 case CURLOPT_TIMEVALUE_LARGE:
2790 #endif
2791 lval = zval_get_long(zvalue);
2792 error = curl_easy_setopt(ch->cp, option, (curl_off_t)lval);
2793 break;
2794
2795 case CURLOPT_POSTREDIR:
2796 lval = zval_get_long(zvalue);
2797 error = curl_easy_setopt(ch->cp, CURLOPT_POSTREDIR, lval & CURL_REDIR_POST_ALL);
2798 break;
2799
2800 /* the following options deal with files, therefore the open_basedir check
2801 * is required.
2802 */
2803 case CURLOPT_COOKIEFILE:
2804 case CURLOPT_COOKIEJAR:
2805 case CURLOPT_RANDOM_FILE:
2806 case CURLOPT_SSLCERT:
2807 case CURLOPT_NETRC_FILE:
2808 case CURLOPT_SSH_PRIVATE_KEYFILE:
2809 case CURLOPT_SSH_PUBLIC_KEYFILE:
2810 case CURLOPT_CRLFILE:
2811 case CURLOPT_ISSUERCERT:
2812 case CURLOPT_SSH_KNOWNHOSTS:
2813 {
2814 zend_string *tmp_str;
2815 zend_string *str = zval_get_tmp_string(zvalue, &tmp_str);
2816 int ret;
2817
2818 if (ZSTR_LEN(str) && php_check_open_basedir(ZSTR_VAL(str))) {
2819 zend_tmp_string_release(tmp_str);
2820 return FAILURE;
2821 }
2822
2823 ret = php_curl_option_str(ch, option, ZSTR_VAL(str), ZSTR_LEN(str), 0);
2824 zend_tmp_string_release(tmp_str);
2825 return ret;
2826 }
2827
2828 case CURLINFO_HEADER_OUT:
2829 if (zend_is_true(zvalue)) {
2830 curl_easy_setopt(ch->cp, CURLOPT_DEBUGFUNCTION, curl_debug);
2831 curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA, (void *)ch);
2832 curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 1);
2833 } else {
2834 curl_easy_setopt(ch->cp, CURLOPT_DEBUGFUNCTION, NULL);
2835 curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA, NULL);
2836 curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 0);
2837 }
2838 break;
2839
2840 case CURLOPT_SHARE:
2841 {
2842 if (Z_TYPE_P(zvalue) == IS_OBJECT && Z_OBJCE_P(zvalue) == curl_share_ce) {
2843 php_curlsh *sh = Z_CURL_SHARE_P(zvalue);
2844 curl_easy_setopt(ch->cp, CURLOPT_SHARE, sh->share);
2845
2846 if (ch->share) {
2847 OBJ_RELEASE(&ch->share->std);
2848 }
2849 GC_ADDREF(&sh->std);
2850 ch->share = sh;
2851 }
2852 }
2853 break;
2854
2855 case CURLOPT_FNMATCH_FUNCTION:
2856 curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_FUNCTION, curl_fnmatch);
2857 curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_DATA, ch);
2858 if (ch->handlers->fnmatch == NULL) {
2859 ch->handlers->fnmatch = ecalloc(1, sizeof(php_curl_fnmatch));
2860 } else if (!Z_ISUNDEF(ch->handlers->fnmatch->func_name)) {
2861 zval_ptr_dtor(&ch->handlers->fnmatch->func_name);
2862 ch->handlers->fnmatch->fci_cache = empty_fcall_info_cache;
2863 }
2864 ZVAL_COPY(&ch->handlers->fnmatch->func_name, zvalue);
2865 ch->handlers->fnmatch->method = PHP_CURL_USER;
2866 break;
2867
2868 default:
2869 if (is_array_config) {
2870 zend_argument_value_error(2, "must contain only valid cURL options");
2871 } else {
2872 zend_argument_value_error(2, "is not a valid cURL option");
2873 }
2874 error = CURLE_UNKNOWN_OPTION;
2875 break;
2876 }
2877
2878 SAVE_CURL_ERROR(ch, error);
2879 if (error != CURLE_OK) {
2880 return FAILURE;
2881 } else {
2882 return SUCCESS;
2883 }
2884 }
2885 /* }}} */
2886
2887 /* {{{ Set an option for a cURL transfer */
PHP_FUNCTION(curl_setopt)2888 PHP_FUNCTION(curl_setopt)
2889 {
2890 zval *zid, *zvalue;
2891 zend_long options;
2892 php_curl *ch;
2893
2894 ZEND_PARSE_PARAMETERS_START(3, 3)
2895 Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
2896 Z_PARAM_LONG(options)
2897 Z_PARAM_ZVAL(zvalue)
2898 ZEND_PARSE_PARAMETERS_END();
2899
2900 ch = Z_CURL_P(zid);
2901
2902 if (_php_curl_setopt(ch, options, zvalue, 0) == SUCCESS) {
2903 RETURN_TRUE;
2904 } else {
2905 RETURN_FALSE;
2906 }
2907 }
2908 /* }}} */
2909
2910 /* {{{ Set an array of option for a cURL transfer */
PHP_FUNCTION(curl_setopt_array)2911 PHP_FUNCTION(curl_setopt_array)
2912 {
2913 zval *zid, *arr, *entry;
2914 php_curl *ch;
2915 zend_ulong option;
2916 zend_string *string_key;
2917
2918 ZEND_PARSE_PARAMETERS_START(2, 2)
2919 Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
2920 Z_PARAM_ARRAY(arr)
2921 ZEND_PARSE_PARAMETERS_END();
2922
2923 ch = Z_CURL_P(zid);
2924
2925 ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(arr), option, string_key, entry) {
2926 if (string_key) {
2927 zend_argument_value_error(2, "contains an invalid cURL option");
2928 RETURN_THROWS();
2929 }
2930
2931 ZVAL_DEREF(entry);
2932 if (_php_curl_setopt(ch, (zend_long) option, entry, 1) == FAILURE) {
2933 RETURN_FALSE;
2934 }
2935 } ZEND_HASH_FOREACH_END();
2936
2937 RETURN_TRUE;
2938 }
2939 /* }}} */
2940
2941 /* {{{ _php_curl_cleanup_handle(ch)
2942 Cleanup an execution phase */
_php_curl_cleanup_handle(php_curl * ch)2943 void _php_curl_cleanup_handle(php_curl *ch)
2944 {
2945 smart_str_free(&ch->handlers->write->buf);
2946 if (ch->header.str) {
2947 zend_string_release_ex(ch->header.str, 0);
2948 ch->header.str = NULL;
2949 }
2950
2951 memset(ch->err.str, 0, CURL_ERROR_SIZE + 1);
2952 ch->err.no = 0;
2953 }
2954 /* }}} */
2955
2956 /* {{{ Perform a cURL session */
PHP_FUNCTION(curl_exec)2957 PHP_FUNCTION(curl_exec)
2958 {
2959 CURLcode error;
2960 zval *zid;
2961 php_curl *ch;
2962
2963 ZEND_PARSE_PARAMETERS_START(1, 1)
2964 Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
2965 ZEND_PARSE_PARAMETERS_END();
2966
2967 ch = Z_CURL_P(zid);
2968
2969 _php_curl_verify_handlers(ch, 1);
2970
2971 _php_curl_cleanup_handle(ch);
2972
2973 error = curl_easy_perform(ch->cp);
2974 SAVE_CURL_ERROR(ch, error);
2975
2976 if (error != CURLE_OK) {
2977 smart_str_free(&ch->handlers->write->buf);
2978 RETURN_FALSE;
2979 }
2980
2981 if (!Z_ISUNDEF(ch->handlers->std_err)) {
2982 php_stream *stream;
2983 stream = (php_stream*)zend_fetch_resource2_ex(&ch->handlers->std_err, NULL, php_file_le_stream(), php_file_le_pstream());
2984 if (stream) {
2985 php_stream_flush(stream);
2986 }
2987 }
2988
2989 if (ch->handlers->write->method == PHP_CURL_RETURN && ch->handlers->write->buf.s) {
2990 smart_str_0(&ch->handlers->write->buf);
2991 RETURN_STR_COPY(ch->handlers->write->buf.s);
2992 }
2993
2994 /* flush the file handle, so any remaining data is synched to disk */
2995 if (ch->handlers->write->method == PHP_CURL_FILE && ch->handlers->write->fp) {
2996 fflush(ch->handlers->write->fp);
2997 }
2998 if (ch->handlers->write_header->method == PHP_CURL_FILE && ch->handlers->write_header->fp) {
2999 fflush(ch->handlers->write_header->fp);
3000 }
3001
3002 if (ch->handlers->write->method == PHP_CURL_RETURN) {
3003 RETURN_EMPTY_STRING();
3004 } else {
3005 RETURN_TRUE;
3006 }
3007 }
3008 /* }}} */
3009
3010 /* {{{ Get information regarding a specific transfer */
PHP_FUNCTION(curl_getinfo)3011 PHP_FUNCTION(curl_getinfo)
3012 {
3013 zval *zid;
3014 php_curl *ch;
3015 zend_long option;
3016 zend_bool option_is_null = 1;
3017
3018 ZEND_PARSE_PARAMETERS_START(1, 2)
3019 Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
3020 Z_PARAM_OPTIONAL
3021 Z_PARAM_LONG_OR_NULL(option, option_is_null)
3022 ZEND_PARSE_PARAMETERS_END();
3023
3024 ch = Z_CURL_P(zid);
3025
3026 if (option_is_null) {
3027 char *s_code;
3028 /* libcurl expects long datatype. So far no cases are known where
3029 it would be an issue. Using zend_long would truncate a 64-bit
3030 var on Win64, so the exact long datatype fits everywhere, as
3031 long as there's no 32-bit int overflow. */
3032 long l_code;
3033 double d_code;
3034 struct curl_certinfo *ci = NULL;
3035 zval listcode;
3036 #if LIBCURL_VERSION_NUM >= 0x073d00 /* 7.61.0 */
3037 curl_off_t co;
3038 #endif
3039
3040 array_init(return_value);
3041
3042 if (curl_easy_getinfo(ch->cp, CURLINFO_EFFECTIVE_URL, &s_code) == CURLE_OK) {
3043 CAAS("url", s_code);
3044 }
3045 if (curl_easy_getinfo(ch->cp, CURLINFO_CONTENT_TYPE, &s_code) == CURLE_OK) {
3046 if (s_code != NULL) {
3047 CAAS("content_type", s_code);
3048 } else {
3049 zval retnull;
3050 ZVAL_NULL(&retnull);
3051 CAAZ("content_type", &retnull);
3052 }
3053 }
3054 if (curl_easy_getinfo(ch->cp, CURLINFO_HTTP_CODE, &l_code) == CURLE_OK) {
3055 CAAL("http_code", l_code);
3056 }
3057 if (curl_easy_getinfo(ch->cp, CURLINFO_HEADER_SIZE, &l_code) == CURLE_OK) {
3058 CAAL("header_size", l_code);
3059 }
3060 if (curl_easy_getinfo(ch->cp, CURLINFO_REQUEST_SIZE, &l_code) == CURLE_OK) {
3061 CAAL("request_size", l_code);
3062 }
3063 if (curl_easy_getinfo(ch->cp, CURLINFO_FILETIME, &l_code) == CURLE_OK) {
3064 CAAL("filetime", l_code);
3065 }
3066 if (curl_easy_getinfo(ch->cp, CURLINFO_SSL_VERIFYRESULT, &l_code) == CURLE_OK) {
3067 CAAL("ssl_verify_result", l_code);
3068 }
3069 if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_COUNT, &l_code) == CURLE_OK) {
3070 CAAL("redirect_count", l_code);
3071 }
3072 if (curl_easy_getinfo(ch->cp, CURLINFO_TOTAL_TIME, &d_code) == CURLE_OK) {
3073 CAAD("total_time", d_code);
3074 }
3075 if (curl_easy_getinfo(ch->cp, CURLINFO_NAMELOOKUP_TIME, &d_code) == CURLE_OK) {
3076 CAAD("namelookup_time", d_code);
3077 }
3078 if (curl_easy_getinfo(ch->cp, CURLINFO_CONNECT_TIME, &d_code) == CURLE_OK) {
3079 CAAD("connect_time", d_code);
3080 }
3081 if (curl_easy_getinfo(ch->cp, CURLINFO_PRETRANSFER_TIME, &d_code) == CURLE_OK) {
3082 CAAD("pretransfer_time", d_code);
3083 }
3084 if (curl_easy_getinfo(ch->cp, CURLINFO_SIZE_UPLOAD, &d_code) == CURLE_OK) {
3085 CAAD("size_upload", d_code);
3086 }
3087 if (curl_easy_getinfo(ch->cp, CURLINFO_SIZE_DOWNLOAD, &d_code) == CURLE_OK) {
3088 CAAD("size_download", d_code);
3089 }
3090 if (curl_easy_getinfo(ch->cp, CURLINFO_SPEED_DOWNLOAD, &d_code) == CURLE_OK) {
3091 CAAD("speed_download", d_code);
3092 }
3093 if (curl_easy_getinfo(ch->cp, CURLINFO_SPEED_UPLOAD, &d_code) == CURLE_OK) {
3094 CAAD("speed_upload", d_code);
3095 }
3096 if (curl_easy_getinfo(ch->cp, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d_code) == CURLE_OK) {
3097 CAAD("download_content_length", d_code);
3098 }
3099 if (curl_easy_getinfo(ch->cp, CURLINFO_CONTENT_LENGTH_UPLOAD, &d_code) == CURLE_OK) {
3100 CAAD("upload_content_length", d_code);
3101 }
3102 if (curl_easy_getinfo(ch->cp, CURLINFO_STARTTRANSFER_TIME, &d_code) == CURLE_OK) {
3103 CAAD("starttransfer_time", d_code);
3104 }
3105 if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_TIME, &d_code) == CURLE_OK) {
3106 CAAD("redirect_time", d_code);
3107 }
3108 if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_URL, &s_code) == CURLE_OK) {
3109 CAAS("redirect_url", s_code);
3110 }
3111 if (curl_easy_getinfo(ch->cp, CURLINFO_PRIMARY_IP, &s_code) == CURLE_OK) {
3112 CAAS("primary_ip", s_code);
3113 }
3114 if (curl_easy_getinfo(ch->cp, CURLINFO_CERTINFO, &ci) == CURLE_OK) {
3115 array_init(&listcode);
3116 create_certinfo(ci, &listcode);
3117 CAAZ("certinfo", &listcode);
3118 }
3119 if (curl_easy_getinfo(ch->cp, CURLINFO_PRIMARY_PORT, &l_code) == CURLE_OK) {
3120 CAAL("primary_port", l_code);
3121 }
3122 if (curl_easy_getinfo(ch->cp, CURLINFO_LOCAL_IP, &s_code) == CURLE_OK) {
3123 CAAS("local_ip", s_code);
3124 }
3125 if (curl_easy_getinfo(ch->cp, CURLINFO_LOCAL_PORT, &l_code) == CURLE_OK) {
3126 CAAL("local_port", l_code);
3127 }
3128 #if LIBCURL_VERSION_NUM >= 0x073200 /* Available since 7.50.0 */
3129 if (curl_easy_getinfo(ch->cp, CURLINFO_HTTP_VERSION, &l_code) == CURLE_OK) {
3130 CAAL("http_version", l_code);
3131 }
3132 #endif
3133 #if LIBCURL_VERSION_NUM >= 0x073400 /* Available since 7.52.0 */
3134 if (curl_easy_getinfo(ch->cp, CURLINFO_PROTOCOL, &l_code) == CURLE_OK) {
3135 CAAL("protocol", l_code);
3136 }
3137 if (curl_easy_getinfo(ch->cp, CURLINFO_PROXY_SSL_VERIFYRESULT, &l_code) == CURLE_OK) {
3138 CAAL("ssl_verifyresult", l_code);
3139 }
3140 if (curl_easy_getinfo(ch->cp, CURLINFO_SCHEME, &s_code) == CURLE_OK) {
3141 CAAS("scheme", s_code);
3142 }
3143 #endif
3144 #if LIBCURL_VERSION_NUM >= 0x073d00 /* Available since 7.61.0 */
3145 if (curl_easy_getinfo(ch->cp, CURLINFO_APPCONNECT_TIME_T, &co) == CURLE_OK) {
3146 CAAL("appconnect_time_us", co);
3147 }
3148 if (curl_easy_getinfo(ch->cp, CURLINFO_CONNECT_TIME_T, &co) == CURLE_OK) {
3149 CAAL("connect_time_us", co);
3150 }
3151 if (curl_easy_getinfo(ch->cp, CURLINFO_NAMELOOKUP_TIME_T, &co) == CURLE_OK) {
3152 CAAL("namelookup_time_us", co);
3153 }
3154 if (curl_easy_getinfo(ch->cp, CURLINFO_PRETRANSFER_TIME_T, &co) == CURLE_OK) {
3155 CAAL("pretransfer_time_us", co);
3156 }
3157 if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_TIME_T, &co) == CURLE_OK) {
3158 CAAL("redirect_time_us", co);
3159 }
3160 if (curl_easy_getinfo(ch->cp, CURLINFO_STARTTRANSFER_TIME_T, &co) == CURLE_OK) {
3161 CAAL("starttransfer_time_us", co);
3162 }
3163 if (curl_easy_getinfo(ch->cp, CURLINFO_TOTAL_TIME_T, &co) == CURLE_OK) {
3164 CAAL("total_time_us", co);
3165 }
3166 #endif
3167 if (ch->header.str) {
3168 CAASTR("request_header", ch->header.str);
3169 }
3170 } else {
3171 switch (option) {
3172 case CURLINFO_HEADER_OUT:
3173 if (ch->header.str) {
3174 RETURN_STR_COPY(ch->header.str);
3175 } else {
3176 RETURN_FALSE;
3177 }
3178 case CURLINFO_CERTINFO: {
3179 struct curl_certinfo *ci = NULL;
3180
3181 array_init(return_value);
3182
3183 if (curl_easy_getinfo(ch->cp, CURLINFO_CERTINFO, &ci) == CURLE_OK) {
3184 create_certinfo(ci, return_value);
3185 } else {
3186 RETURN_FALSE;
3187 }
3188 break;
3189 }
3190 default: {
3191 int type = CURLINFO_TYPEMASK & option;
3192 switch (type) {
3193 case CURLINFO_STRING:
3194 {
3195 char *s_code = NULL;
3196
3197 if (curl_easy_getinfo(ch->cp, option, &s_code) == CURLE_OK && s_code) {
3198 RETURN_STRING(s_code);
3199 } else {
3200 RETURN_FALSE;
3201 }
3202 break;
3203 }
3204 case CURLINFO_LONG:
3205 {
3206 zend_long code = 0;
3207
3208 if (curl_easy_getinfo(ch->cp, option, &code) == CURLE_OK) {
3209 RETURN_LONG(code);
3210 } else {
3211 RETURN_FALSE;
3212 }
3213 break;
3214 }
3215 case CURLINFO_DOUBLE:
3216 {
3217 double code = 0.0;
3218
3219 if (curl_easy_getinfo(ch->cp, option, &code) == CURLE_OK) {
3220 RETURN_DOUBLE(code);
3221 } else {
3222 RETURN_FALSE;
3223 }
3224 break;
3225 }
3226 case CURLINFO_SLIST:
3227 {
3228 struct curl_slist *slist;
3229 if (curl_easy_getinfo(ch->cp, option, &slist) == CURLE_OK) {
3230 struct curl_slist *current = slist;
3231 array_init(return_value);
3232 while (current) {
3233 add_next_index_string(return_value, current->data);
3234 current = current->next;
3235 }
3236 curl_slist_free_all(slist);
3237 } else {
3238 RETURN_FALSE;
3239 }
3240 break;
3241 }
3242 #if LIBCURL_VERSION_NUM >= 0x073700 /* Available since 7.55.0 */
3243 case CURLINFO_OFF_T:
3244 {
3245 curl_off_t c_off;
3246 if (curl_easy_getinfo(ch->cp, option, &c_off) == CURLE_OK) {
3247 RETURN_LONG((long) c_off);
3248 } else {
3249 RETURN_FALSE;
3250 }
3251 break;
3252 }
3253 #endif
3254 default:
3255 RETURN_FALSE;
3256 }
3257 }
3258 }
3259 }
3260 }
3261 /* }}} */
3262
3263 /* {{{ Return a string contain the last error for the current session */
PHP_FUNCTION(curl_error)3264 PHP_FUNCTION(curl_error)
3265 {
3266 zval *zid;
3267 php_curl *ch;
3268
3269 ZEND_PARSE_PARAMETERS_START(1, 1)
3270 Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
3271 ZEND_PARSE_PARAMETERS_END();
3272
3273 ch = Z_CURL_P(zid);
3274
3275 if (ch->err.no) {
3276 ch->err.str[CURL_ERROR_SIZE] = 0;
3277 RETURN_STRING(ch->err.str);
3278 } else {
3279 RETURN_EMPTY_STRING();
3280 }
3281 }
3282 /* }}} */
3283
3284 /* {{{ Return an integer containing the last error number */
PHP_FUNCTION(curl_errno)3285 PHP_FUNCTION(curl_errno)
3286 {
3287 zval *zid;
3288 php_curl *ch;
3289
3290 ZEND_PARSE_PARAMETERS_START(1,1)
3291 Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
3292 ZEND_PARSE_PARAMETERS_END();
3293
3294 ch = Z_CURL_P(zid);
3295
3296 RETURN_LONG(ch->err.no);
3297 }
3298 /* }}} */
3299
3300 /* {{{ Close a cURL session */
PHP_FUNCTION(curl_close)3301 PHP_FUNCTION(curl_close)
3302 {
3303 zval *zid;
3304 php_curl *ch;
3305
3306 ZEND_PARSE_PARAMETERS_START(1, 1)
3307 Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
3308 ZEND_PARSE_PARAMETERS_END();
3309
3310 ch = Z_CURL_P(zid);
3311
3312 if (ch->in_callback) {
3313 zend_throw_error(NULL, "%s(): Attempt to close cURL handle from a callback", get_active_function_name());
3314 RETURN_THROWS();
3315 }
3316 }
3317 /* }}} */
3318
curl_free_obj(zend_object * object)3319 static void curl_free_obj(zend_object *object)
3320 {
3321 php_curl *ch = curl_from_obj(object);
3322
3323 #if PHP_CURL_DEBUG
3324 fprintf(stderr, "DTOR CALLED, ch = %x\n", ch);
3325 #endif
3326
3327 if (!ch->cp) {
3328 /* Can happen if constructor throws. */
3329 zend_object_std_dtor(&ch->std);
3330 return;
3331 }
3332
3333 _php_curl_verify_handlers(ch, 0);
3334
3335 /*
3336 * Libcurl is doing connection caching. When easy handle is cleaned up,
3337 * if the handle was previously used by the curl_multi_api, the connection
3338 * remains open un the curl multi handle is cleaned up. Some protocols are
3339 * sending content like the FTP one, and libcurl try to use the
3340 * WRITEFUNCTION or the HEADERFUNCTION. Since structures used in those
3341 * callback are freed, we need to use an other callback to which avoid
3342 * segfaults.
3343 *
3344 * Libcurl commit d021f2e8a00 fix this issue and should be part of 7.28.2
3345 */
3346 curl_easy_setopt(ch->cp, CURLOPT_HEADERFUNCTION, curl_write_nothing);
3347 curl_easy_setopt(ch->cp, CURLOPT_WRITEFUNCTION, curl_write_nothing);
3348
3349 curl_easy_cleanup(ch->cp);
3350
3351 /* cURL destructors should be invoked only by last curl handle */
3352 if (--(*ch->clone) == 0) {
3353 zend_llist_clean(&ch->to_free->str);
3354 zend_llist_clean(&ch->to_free->post);
3355 zend_llist_clean(&ch->to_free->stream);
3356 zend_hash_destroy(ch->to_free->slist);
3357 efree(ch->to_free->slist);
3358 efree(ch->to_free);
3359 efree(ch->clone);
3360 }
3361
3362 smart_str_free(&ch->handlers->write->buf);
3363 zval_ptr_dtor(&ch->handlers->write->func_name);
3364 zval_ptr_dtor(&ch->handlers->read->func_name);
3365 zval_ptr_dtor(&ch->handlers->write_header->func_name);
3366 zval_ptr_dtor(&ch->handlers->std_err);
3367 if (ch->header.str) {
3368 zend_string_release_ex(ch->header.str, 0);
3369 }
3370
3371 zval_ptr_dtor(&ch->handlers->write_header->stream);
3372 zval_ptr_dtor(&ch->handlers->write->stream);
3373 zval_ptr_dtor(&ch->handlers->read->stream);
3374
3375 efree(ch->handlers->write);
3376 efree(ch->handlers->write_header);
3377 efree(ch->handlers->read);
3378
3379 if (ch->handlers->progress) {
3380 zval_ptr_dtor(&ch->handlers->progress->func_name);
3381 efree(ch->handlers->progress);
3382 }
3383
3384 if (ch->handlers->fnmatch) {
3385 zval_ptr_dtor(&ch->handlers->fnmatch->func_name);
3386 efree(ch->handlers->fnmatch);
3387 }
3388
3389 efree(ch->handlers);
3390 zval_ptr_dtor(&ch->postfields);
3391
3392 if (ch->share) {
3393 OBJ_RELEASE(&ch->share->std);
3394 }
3395
3396 zend_object_std_dtor(&ch->std);
3397 }
3398 /* }}} */
3399
3400 /* {{{ return string describing error code */
PHP_FUNCTION(curl_strerror)3401 PHP_FUNCTION(curl_strerror)
3402 {
3403 zend_long code;
3404 const char *str;
3405
3406 ZEND_PARSE_PARAMETERS_START(1, 1)
3407 Z_PARAM_LONG(code)
3408 ZEND_PARSE_PARAMETERS_END();
3409
3410 str = curl_easy_strerror(code);
3411 if (str) {
3412 RETURN_STRING(str);
3413 } else {
3414 RETURN_NULL();
3415 }
3416 }
3417 /* }}} */
3418
3419 /* {{{ _php_curl_reset_handlers()
3420 Reset all handlers of a given php_curl */
_php_curl_reset_handlers(php_curl * ch)3421 static void _php_curl_reset_handlers(php_curl *ch)
3422 {
3423 if (!Z_ISUNDEF(ch->handlers->write->stream)) {
3424 zval_ptr_dtor(&ch->handlers->write->stream);
3425 ZVAL_UNDEF(&ch->handlers->write->stream);
3426 }
3427 ch->handlers->write->fp = NULL;
3428 ch->handlers->write->method = PHP_CURL_STDOUT;
3429
3430 if (!Z_ISUNDEF(ch->handlers->write_header->stream)) {
3431 zval_ptr_dtor(&ch->handlers->write_header->stream);
3432 ZVAL_UNDEF(&ch->handlers->write_header->stream);
3433 }
3434 ch->handlers->write_header->fp = NULL;
3435 ch->handlers->write_header->method = PHP_CURL_IGNORE;
3436
3437 if (!Z_ISUNDEF(ch->handlers->read->stream)) {
3438 zval_ptr_dtor(&ch->handlers->read->stream);
3439 ZVAL_UNDEF(&ch->handlers->read->stream);
3440 }
3441 ch->handlers->read->fp = NULL;
3442 ch->handlers->read->res = NULL;
3443 ch->handlers->read->method = PHP_CURL_DIRECT;
3444
3445 if (!Z_ISUNDEF(ch->handlers->std_err)) {
3446 zval_ptr_dtor(&ch->handlers->std_err);
3447 ZVAL_UNDEF(&ch->handlers->std_err);
3448 }
3449
3450 if (ch->handlers->progress) {
3451 zval_ptr_dtor(&ch->handlers->progress->func_name);
3452 efree(ch->handlers->progress);
3453 ch->handlers->progress = NULL;
3454 }
3455
3456 if (ch->handlers->fnmatch) {
3457 zval_ptr_dtor(&ch->handlers->fnmatch->func_name);
3458 efree(ch->handlers->fnmatch);
3459 ch->handlers->fnmatch = NULL;
3460 }
3461
3462 }
3463 /* }}} */
3464
3465 /* {{{ Reset all options of a libcurl session handle */
PHP_FUNCTION(curl_reset)3466 PHP_FUNCTION(curl_reset)
3467 {
3468 zval *zid;
3469 php_curl *ch;
3470
3471 ZEND_PARSE_PARAMETERS_START(1, 1)
3472 Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
3473 ZEND_PARSE_PARAMETERS_END();
3474
3475 ch = Z_CURL_P(zid);
3476
3477 if (ch->in_callback) {
3478 zend_throw_error(NULL, "%s(): Attempt to reset cURL handle from a callback", get_active_function_name());
3479 RETURN_THROWS();
3480 }
3481
3482 curl_easy_reset(ch->cp);
3483 _php_curl_reset_handlers(ch);
3484 _php_curl_set_default_options(ch);
3485 }
3486 /* }}} */
3487
3488 /* {{{ URL encodes the given string */
PHP_FUNCTION(curl_escape)3489 PHP_FUNCTION(curl_escape)
3490 {
3491 zend_string *str;
3492 char *res;
3493 zval *zid;
3494 php_curl *ch;
3495
3496 ZEND_PARSE_PARAMETERS_START(2,2)
3497 Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
3498 Z_PARAM_STR(str)
3499 ZEND_PARSE_PARAMETERS_END();
3500
3501 ch = Z_CURL_P(zid);
3502
3503 if (ZEND_SIZE_T_INT_OVFL(ZSTR_LEN(str))) {
3504 RETURN_FALSE;
3505 }
3506
3507 if ((res = curl_easy_escape(ch->cp, ZSTR_VAL(str), ZSTR_LEN(str)))) {
3508 RETVAL_STRING(res);
3509 curl_free(res);
3510 } else {
3511 RETURN_FALSE;
3512 }
3513 }
3514 /* }}} */
3515
3516 /* {{{ URL decodes the given string */
PHP_FUNCTION(curl_unescape)3517 PHP_FUNCTION(curl_unescape)
3518 {
3519 char *out = NULL;
3520 int out_len;
3521 zval *zid;
3522 zend_string *str;
3523 php_curl *ch;
3524
3525 ZEND_PARSE_PARAMETERS_START(2,2)
3526 Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
3527 Z_PARAM_STR(str)
3528 ZEND_PARSE_PARAMETERS_END();
3529
3530 ch = Z_CURL_P(zid);
3531
3532 if (ZEND_SIZE_T_INT_OVFL(ZSTR_LEN(str))) {
3533 RETURN_FALSE;
3534 }
3535
3536 if ((out = curl_easy_unescape(ch->cp, ZSTR_VAL(str), ZSTR_LEN(str), &out_len))) {
3537 RETVAL_STRINGL(out, out_len);
3538 curl_free(out);
3539 } else {
3540 RETURN_FALSE;
3541 }
3542 }
3543 /* }}} */
3544
3545 /* {{{ pause and unpause a connection */
PHP_FUNCTION(curl_pause)3546 PHP_FUNCTION(curl_pause)
3547 {
3548 zend_long bitmask;
3549 zval *zid;
3550 php_curl *ch;
3551
3552 ZEND_PARSE_PARAMETERS_START(2,2)
3553 Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce)
3554 Z_PARAM_LONG(bitmask)
3555 ZEND_PARSE_PARAMETERS_END();
3556
3557 ch = Z_CURL_P(zid);
3558
3559 RETURN_LONG(curl_easy_pause(ch->cp, bitmask));
3560 }
3561 /* }}} */
3562