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