From 6ebe63fac23f38df911edc348e8ccc72280f9434 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 26 Aug 2020 08:30:38 +0200 Subject: [PATCH] options: API for meta-data about easy options const struct curl_easyoption *curl_easy_option_by_name(const char *name); const struct curl_easyoption *curl_easy_option_by_id (CURLoption id); const struct curl_easyoption * curl_easy_option_next(const struct curl_easyoption *prev); The purpose is to provide detailed enough information to allow for example libcurl bindings to get option information at run-time about what easy options that exist and what arguments they expect. Assisted-by: Jeroen Ooms Closes #5365 --- docs/libcurl/Makefile.inc | 3 + docs/libcurl/curl_easy_option_by_id.3 | 46 ++++ docs/libcurl/curl_easy_option_by_name.3 | 44 +++ docs/libcurl/curl_easy_option_next.3 | 74 +++++ docs/libcurl/symbols-in-versions | 27 +- include/curl/Makefile.am | 4 +- include/curl/curl.h | 87 +++--- include/curl/options.h | 68 +++++ lib/Makefile.am | 3 + lib/Makefile.inc | 4 +- lib/easygetopt.c | 73 +++++ lib/easyoptions.c | 346 ++++++++++++++++++++++++ lib/easyoptions.h | 35 +++ lib/optiontable.pl | 118 ++++++++ lib/setopt.c | 6 + tests/data/Makefile.inc | 2 +- tests/data/test1119 | 1 - tests/data/test1911 | 31 +++ tests/libtest/Makefile.inc | 6 +- tests/libtest/lib1911.c | 87 ++++++ tests/libtest/mk-lib1521.pl | 10 +- tests/symbol-scan.pl | 2 +- 22 files changed, 1019 insertions(+), 58 deletions(-) create mode 100644 docs/libcurl/curl_easy_option_by_id.3 create mode 100644 docs/libcurl/curl_easy_option_by_name.3 create mode 100644 docs/libcurl/curl_easy_option_next.3 create mode 100644 include/curl/options.h create mode 100644 lib/easygetopt.c create mode 100644 lib/easyoptions.c create mode 100644 lib/easyoptions.h create mode 100644 lib/optiontable.pl create mode 100644 tests/data/test1911 create mode 100644 tests/libtest/lib1911.c diff --git a/docs/libcurl/Makefile.inc b/docs/libcurl/Makefile.inc index 332056a19..fb7ea89a9 100644 --- a/docs/libcurl/Makefile.inc +++ b/docs/libcurl/Makefile.inc @@ -28,6 +28,9 @@ man_MANS = \ curl_easy_escape.3 \ curl_easy_getinfo.3 \ curl_easy_init.3 \ + curl_easy_option_by_id.3 \ + curl_easy_option_by_name.3 \ + curl_easy_option_next.3 \ curl_easy_pause.3 \ curl_easy_perform.3 \ curl_easy_recv.3 \ diff --git a/docs/libcurl/curl_easy_option_by_id.3 b/docs/libcurl/curl_easy_option_by_id.3 new file mode 100644 index 000000000..e8130faf8 --- /dev/null +++ b/docs/libcurl/curl_easy_option_by_id.3 @@ -0,0 +1,46 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. +.\" * +.\" * This software is licensed as described in the file COPYING, which +.\" * you should have received as part of this distribution. The terms +.\" * are also available at https://curl.haxx.se/docs/copyright.html. +.\" * +.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell +.\" * copies of the Software, and permit persons to whom the Software is +.\" * furnished to do so, under the terms of the COPYING file. +.\" * +.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +.\" * KIND, either express or implied. +.\" * +.\" ************************************************************************** +.TH curl_easy_option_by_id 3 "15 May 2020" "libcurl 7.71.0" "libcurl Manual" +.SH NAME +curl_easy_option_by_id - find an easy setopt option by id +.SH SYNOPSIS +.nf +#include + +const struct curl_easyoption *curl_easy_option_by_id(CURLoption id); +.fi +.SH DESCRIPTION +Given a CURLoption \fBid\fP, this function returns a pointer to the +curl_easyoption struct, holding information about the +\fIcurl_easy_setopt(3)\fP option using that id. The option id is the CURLOPT_ +prefix ones provided in the standard curl/curl.h header file. This function +will return the non-aliases version for the cases where there is an alias +function as well. + +If libcurl has no option with the given id, this function returns NULL. +.SH AVAILABILITY +This function was added in libcurl 7.71.0 +.SH RETURN VALUE +A pointer to the curl_easyoption struct for the option or NULL. +.SH "SEE ALSO" +.BR curl_easy_option_by_name "(3)," curl_easy_option_next "(3)," +.BR curl_easy_setopt "(3)," diff --git a/docs/libcurl/curl_easy_option_by_name.3 b/docs/libcurl/curl_easy_option_by_name.3 new file mode 100644 index 000000000..cc9ce3885 --- /dev/null +++ b/docs/libcurl/curl_easy_option_by_name.3 @@ -0,0 +1,44 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. +.\" * +.\" * This software is licensed as described in the file COPYING, which +.\" * you should have received as part of this distribution. The terms +.\" * are also available at https://curl.haxx.se/docs/copyright.html. +.\" * +.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell +.\" * copies of the Software, and permit persons to whom the Software is +.\" * furnished to do so, under the terms of the COPYING file. +.\" * +.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +.\" * KIND, either express or implied. +.\" * +.\" ************************************************************************** +.TH curl_easy_option_by_name 3 "15 May 2020" "libcurl 7.71.0" "libcurl Manual" +.SH NAME +curl_easy_option_by_name - find an easy setopt option by name +.SH SYNOPSIS +.nf +#include + +const struct curl_easyoption *curl_easy_option_by_name(const char *name); +.fi +.SH DESCRIPTION +Given a \fBname\fP, this function returns a pointer to the curl_easyoption +struct, holding information about the \fIcurl_easy_setopt(3)\fP option using +that name. The name should be specified without the "CURLOPT_" prefix and the +name comparison is made case insensitive. + +If libcurl has no option with the given name, this function returns NULL. +.SH AVAILABILITY +This function was added in libcurl 7.71.0 +.SH RETURN VALUE +A pointer to the curl_easyoption struct for the option or NULL. +.SH "SEE ALSO" +.BR curl_easy_option_next "(3)," curl_easy_option_by_id "(3)," +.BR curl_easy_setopt "(3)," diff --git a/docs/libcurl/curl_easy_option_next.3 b/docs/libcurl/curl_easy_option_next.3 new file mode 100644 index 000000000..732e8d7cd --- /dev/null +++ b/docs/libcurl/curl_easy_option_next.3 @@ -0,0 +1,74 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. +.\" * +.\" * This software is licensed as described in the file COPYING, which +.\" * you should have received as part of this distribution. The terms +.\" * are also available at https://curl.haxx.se/docs/copyright.html. +.\" * +.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell +.\" * copies of the Software, and permit persons to whom the Software is +.\" * furnished to do so, under the terms of the COPYING file. +.\" * +.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +.\" * KIND, either express or implied. +.\" * +.\" ************************************************************************** +.TH curl_easy_option_next 3 "15 May 2020" "libcurl 7.71.0" "libcurl Manual" +.SH NAME +curl_easy_option_next - iterate over easy setopt options +.SH SYNOPSIS +.nf +#include + +typedef enum { + CURLOT_LONG, /* long (a range of values) */ + CURLOT_VALUES, /* (a defined set or bitmask) */ + CURLOT_OFF_T, /* curl_off_t (a range of values) */ + CURLOT_OBJECT, /* pointer (void *) */ + CURLOT_STRING, /* (char * to zero terminated buffer) */ + CURLOT_SLIST, /* (struct curl_slist *) */ + CURLOT_CBPTR, /* (void * passed as-is to a callback) */ + CURLOT_BLOB, /* blob (struct curl_blob *) */ + CURLOT_FUNCTION /* function pointer */ +} curl_easytype; + +/* The CURLOPTTYPE_* id ranges can still be used to figure out what type/size + to use for curl_easy_setopt() for the given id */ +struct curl_easyoption { + const char *name; + CURLoption id; + curl_easytype type; + unsigned int flags; +}; + +const struct curl_easyoption * +curl_easy_option_next(const struct curl_easyoption *prev); +.fi +.SH DESCRIPTION +This function returns a pointer to the first or the next curl_easyoption +struct, providing an ability to iterate over all known options for +\fIcurl_easy_setopt(3)\fP in this instance of libcurl. + +Pass a \fBNULL\fP argument as \fBprev\fP to get the first option returned, or +pass in the current option to get the next one returned. If there is no more +option to return, \fIcurl_easy_option_next(3)\fP returns NULL. + +The options returned by this functions are the ones known to this libcurl and +information about what argument type they want. + +If the \fBCURLOT_FLAG_ALIAS\fP bit is set in the flags field, it means the +name is provided for backwards compatibility as an alias. +.SH AVAILABILITY +This function was added in libcurl 7.71.0 +.SH RETURN VALUE +A pointer to the curl_easyoption struct for the next option or NULL if no more +options. +.SH "SEE ALSO" +.BR curl_easy_option_by_name "(3)," curl_easy_option_by_id "(3)," +.BR curl_easy_setopt "(3)," diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions index 0e2faacec..82a8e8b3d 100644 --- a/docs/libcurl/symbols-in-versions +++ b/docs/libcurl/symbols-in-versions @@ -352,12 +352,14 @@ CURLM_UNKNOWN_OPTION 7.15.4 CURLM_WAKEUP_FAILURE 7.68.0 CURLOPT 7.69.0 CURLOPTTYPE_BLOB 7.71.0 +CURLOPTTYPE_CBPOINT 7.73.0 CURLOPTTYPE_FUNCTIONPOINT 7.1 CURLOPTTYPE_LONG 7.1 CURLOPTTYPE_OBJECTPOINT 7.1 CURLOPTTYPE_OFF_T 7.11.0 CURLOPTTYPE_SLISTPOINT 7.65.2 CURLOPTTYPE_STRINGPOINT 7.46.0 +CURLOPTTYPE_VALUES 7.73.0 CURLOPT_ABSTRACT_UNIX_SOCKET 7.53.0 CURLOPT_ACCEPTTIMEOUT_MS 7.24.0 CURLOPT_ACCEPT_ENCODING 7.21.6 @@ -520,8 +522,6 @@ CURLOPT_PROGRESSDATA 7.1 CURLOPT_PROGRESSFUNCTION 7.1 7.32.0 CURLOPT_PROTOCOLS 7.19.4 CURLOPT_PROXY 7.1 -CURLOPT_PROXY_ISSUERCERT 7.71.0 -CURLOPT_PROXY_ISSUERCERT_BLOB 7.71.0 CURLOPT_PROXYAUTH 7.10.7 CURLOPT_PROXYHEADER 7.37.0 CURLOPT_PROXYPASSWORD 7.19.1 @@ -532,15 +532,17 @@ CURLOPT_PROXYUSERPWD 7.1 CURLOPT_PROXY_CAINFO 7.52.0 CURLOPT_PROXY_CAPATH 7.52.0 CURLOPT_PROXY_CRLFILE 7.52.0 +CURLOPT_PROXY_ISSUERCERT 7.71.0 +CURLOPT_PROXY_ISSUERCERT_BLOB 7.71.0 CURLOPT_PROXY_KEYPASSWD 7.52.0 CURLOPT_PROXY_PINNEDPUBLICKEY 7.52.0 CURLOPT_PROXY_SERVICE_NAME 7.43.0 CURLOPT_PROXY_SSLCERT 7.52.0 -CURLOPT_PROXY_SSLCERT_BLOB 7.71.0 CURLOPT_PROXY_SSLCERTTYPE 7.52.0 +CURLOPT_PROXY_SSLCERT_BLOB 7.71.0 CURLOPT_PROXY_SSLKEY 7.52.0 -CURLOPT_PROXY_SSLKEY_BLOB 7.71.0 CURLOPT_PROXY_SSLKEYTYPE 7.52.0 +CURLOPT_PROXY_SSLKEY_BLOB 7.71.0 CURLOPT_PROXY_SSLVERSION 7.52.0 CURLOPT_PROXY_SSL_CIPHER_LIST 7.52.0 CURLOPT_PROXY_SSL_OPTIONS 7.52.0 @@ -601,15 +603,15 @@ CURLOPT_SSH_KNOWNHOSTS 7.19.6 CURLOPT_SSH_PRIVATE_KEYFILE 7.16.1 CURLOPT_SSH_PUBLIC_KEYFILE 7.16.1 CURLOPT_SSLCERT 7.1 -CURLOPT_SSLCERT_BLOB 7.71.0 CURLOPT_SSLCERTPASSWD 7.1.1 7.17.0 CURLOPT_SSLCERTTYPE 7.9.3 +CURLOPT_SSLCERT_BLOB 7.71.0 CURLOPT_SSLENGINE 7.9.3 CURLOPT_SSLENGINE_DEFAULT 7.9.3 CURLOPT_SSLKEY 7.9.3 -CURLOPT_SSLKEY_BLOB 7.71.0 CURLOPT_SSLKEYPASSWD 7.9.3 7.17.0 CURLOPT_SSLKEYTYPE 7.9.3 +CURLOPT_SSLKEY_BLOB 7.71.0 CURLOPT_SSLVERSION 7.1 CURLOPT_SSL_CIPHER_LIST 7.9 CURLOPT_SSL_CTX_DATA 7.10.6 @@ -667,6 +669,15 @@ CURLOPT_WRITEINFO 7.1 CURLOPT_XFERINFODATA 7.32.0 CURLOPT_XFERINFOFUNCTION 7.32.0 CURLOPT_XOAUTH2_BEARER 7.33.0 +CURLOT_BLOB 7.73.0 +CURLOT_CBPTR 7.73.0 +CURLOT_FUNCTION 7.73.0 +CURLOT_LONG 7.73.0 +CURLOT_OBJECT 7.73.0 +CURLOT_OFF_T 7.73.0 +CURLOT_SLIST 7.73.0 +CURLOT_STRING 7.73.0 +CURLOT_VALUES 7.73.0 CURLPAUSE_ALL 7.18.0 CURLPAUSE_CONT 7.18.0 CURLPAUSE_RECV 7.18.0 @@ -792,9 +803,9 @@ CURLSSLOPT_ALLOW_BEAST 7.25.0 CURLSSLOPT_NATIVE_CA 7.71.0 CURLSSLOPT_NO_PARTIALCHAIN 7.68.0 CURLSSLOPT_NO_REVOKE 7.44.0 +CURLSSLOPT_REVOKE_BEST_EFFORT 7.70.0 CURLSSLSET_NO_BACKENDS 7.56.0 CURLSSLSET_OK 7.56.0 -CURLSSLOPT_REVOKE_BEST_EFFORT 7.70.0 CURLSSLSET_TOO_LATE 7.56.0 CURLSSLSET_UNKNOWN_BACKEND 7.56.0 CURLUE_BAD_HANDLE 7.62.0 @@ -1007,9 +1018,9 @@ CURL_VERSION_SPNEGO 7.10.8 CURL_VERSION_SSL 7.10 CURL_VERSION_SSPI 7.13.2 CURL_VERSION_TLSAUTH_SRP 7.21.4 +CURL_VERSION_UNICODE 7.72.0 CURL_VERSION_UNIX_SOCKETS 7.40.0 CURL_VERSION_ZSTD 7.72.0 -CURL_VERSION_UNICODE 7.72.0 CURL_WAIT_POLLIN 7.28.0 CURL_WAIT_POLLOUT 7.28.0 CURL_WAIT_POLLPRI 7.28.0 diff --git a/include/curl/Makefile.am b/include/curl/Makefile.am index a31f61b10..db96ace89 100644 --- a/include/curl/Makefile.am +++ b/include/curl/Makefile.am @@ -5,7 +5,7 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. +# Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms @@ -21,7 +21,7 @@ ########################################################################### pkginclude_HEADERS = \ curl.h curlver.h easy.h mprintf.h stdcheaders.h multi.h \ - typecheck-gcc.h system.h urlapi.h + typecheck-gcc.h system.h urlapi.h options.h pkgincludedir= $(includedir)/curl diff --git a/include/curl/curl.h b/include/curl/curl.h index 2366ef3c7..32d9bd4a7 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -1002,17 +1002,27 @@ typedef enum { #define CURLOPT(na,t,nu) na = t + nu -/* handy aliases that make no run-time difference */ -#define CURLOPTTYPE_STRINGPOINT CURLOPTTYPE_OBJECTPOINT +/* CURLOPT aliases that make no run-time difference */ + +/* 'char *' argument to a string with a trailing zero */ +#define CURLOPTTYPE_STRINGPOINT CURLOPTTYPE_OBJECTPOINT + +/* 'struct curl_slist *' argument */ #define CURLOPTTYPE_SLISTPOINT CURLOPTTYPE_OBJECTPOINT +/* 'void *' argument passed untouched to callback */ +#define CURLOPTTYPE_CBPOINT CURLOPTTYPE_OBJECTPOINT + +/* 'long' argument with a set of values/bitmask */ +#define CURLOPTTYPE_VALUES CURLOPTTYPE_LONG + /* * All CURLOPT_* values. */ typedef enum { /* This is the FILE * or void * the regular output should be written to. */ - CURLOPT(CURLOPT_WRITEDATA, CURLOPTTYPE_OBJECTPOINT, 1), + CURLOPT(CURLOPT_WRITEDATA, CURLOPTTYPE_CBPOINT, 1), /* The full URL to get/put */ CURLOPT(CURLOPT_URL, CURLOPTTYPE_STRINGPOINT, 2), @@ -1035,7 +1045,7 @@ typedef enum { /* not used */ /* Specified file stream to upload from (use as input): */ - CURLOPT(CURLOPT_READDATA, CURLOPTTYPE_OBJECTPOINT, 9), + CURLOPT(CURLOPT_READDATA, CURLOPTTYPE_CBPOINT, 9), /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE * bytes big. */ @@ -1120,7 +1130,7 @@ typedef enum { /* send FILE * or void * to store headers to, if you use a callback it is simply passed to the callback unmodified */ - CURLOPT(CURLOPT_HEADERDATA, CURLOPTTYPE_OBJECTPOINT, 29), + CURLOPT(CURLOPT_HEADERDATA, CURLOPTTYPE_CBPOINT, 29), /* point to a file to read the initial cookies from, also enables "cookie awareness" */ @@ -1128,10 +1138,10 @@ typedef enum { /* What version to specifically try to use. See CURL_SSLVERSION defines below. */ - CURLOPT(CURLOPT_SSLVERSION, CURLOPTTYPE_LONG, 32), + CURLOPT(CURLOPT_SSLVERSION, CURLOPTTYPE_VALUES, 32), /* What kind of HTTP time condition to use, see defines */ - CURLOPT(CURLOPT_TIMECONDITION, CURLOPTTYPE_LONG, 33), + CURLOPT(CURLOPT_TIMECONDITION, CURLOPTTYPE_VALUES, 33), /* Time to use with the above condition. Specified in number of seconds since 1 Jan 1970 */ @@ -1185,7 +1195,7 @@ typedef enum { /* Specify whether to read the user+password from the .netrc or the URL. * This must be one of the CURL_NETRC_* enums below. */ - CURLOPT(CURLOPT_NETRC, CURLOPTTYPE_LONG, 51), + CURLOPT(CURLOPT_NETRC, CURLOPTTYPE_VALUES, 51), /* use Location: Luke! */ CURLOPT(CURLOPT_FOLLOWLOCATION, CURLOPTTYPE_LONG, 52), @@ -1206,8 +1216,8 @@ typedef enum { /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION callbacks */ - CURLOPT(CURLOPT_PROGRESSDATA, CURLOPTTYPE_OBJECTPOINT, 57), -#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA + CURLOPT(CURLOPT_XFERINFODATA, CURLOPTTYPE_CBPOINT, 57), +#define CURLOPT_PROGRESSDATA CURLOPT_XFERINFODATA /* We want the referrer field set automatically when following locations */ CURLOPT(CURLOPT_AUTOREFERER, CURLOPTTYPE_LONG, 58), @@ -1302,7 +1312,7 @@ typedef enum { /* Specify which HTTP version to use! This must be set to one of the CURL_HTTP_VERSION* enums set below. */ - CURLOPT(CURLOPT_HTTP_VERSION, CURLOPTTYPE_LONG, 84), + CURLOPT(CURLOPT_HTTP_VERSION, CURLOPTTYPE_VALUES, 84), /* Specifically switch on or off the FTP engine's use of the EPSV command. By default, that one will always be attempted before the more traditional @@ -1340,7 +1350,7 @@ typedef enum { CURLOPT(CURLOPT_DEBUGFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 94), /* set the data for the debug function */ - CURLOPT(CURLOPT_DEBUGDATA, CURLOPTTYPE_OBJECTPOINT, 95), + CURLOPT(CURLOPT_DEBUGDATA, CURLOPTTYPE_CBPOINT, 95), /* mark this as start of a cookie session */ CURLOPT(CURLOPT_COOKIESESSION, CURLOPTTYPE_LONG, 96), @@ -1363,7 +1373,7 @@ typedef enum { /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */ - CURLOPT(CURLOPT_PROXYTYPE, CURLOPTTYPE_LONG, 101), + CURLOPT(CURLOPT_PROXYTYPE, CURLOPTTYPE_VALUES, 101), /* Set the Accept-Encoding string. Use this to tell a server you would like the response to be compressed. Before 7.21.6, this was known as @@ -1389,7 +1399,7 @@ typedef enum { /* Set this to a bitmask value to enable the particular authentications methods you like. Use this in combination with CURLOPT_USERPWD. Note that setting multiple bits may cause extra network round-trips. */ - CURLOPT(CURLOPT_HTTPAUTH, CURLOPTTYPE_LONG, 107), + CURLOPT(CURLOPT_HTTPAUTH, CURLOPTTYPE_VALUES, 107), /* Set the ssl context callback function, currently only for OpenSSL or WolfSSL ssl_ctx, or mbedTLS mbedtls_ssl_config in the second argument. @@ -1398,7 +1408,7 @@ typedef enum { /* Set the userdata for the ssl context callback function's third argument */ - CURLOPT(CURLOPT_SSL_CTX_DATA, CURLOPTTYPE_OBJECTPOINT, 109), + CURLOPT(CURLOPT_SSL_CTX_DATA, CURLOPTTYPE_CBPOINT, 109), /* FTP Option that causes missing dirs to be created on the remote server. In 7.19.4 we introduced the convenience enums for this option using the @@ -1409,7 +1419,7 @@ typedef enum { /* Set this to a bitmask value to enable the particular authentications methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. Note that setting multiple bits may cause extra network round-trips. */ - CURLOPT(CURLOPT_PROXYAUTH, CURLOPTTYPE_LONG, 111), + CURLOPT(CURLOPT_PROXYAUTH, CURLOPTTYPE_VALUES, 111), /* FTP option that changes the timeout, in seconds, associated with getting a response. This is different from transfer timeout time and @@ -1421,7 +1431,7 @@ typedef enum { /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to tell libcurl to resolve names to those IP versions only. This only has affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ - CURLOPT(CURLOPT_IPRESOLVE, CURLOPTTYPE_LONG, 113), + CURLOPT(CURLOPT_IPRESOLVE, CURLOPTTYPE_VALUES, 113), /* Set this option to limit the size of a file that will be downloaded from an HTTP or FTP server. @@ -1456,7 +1466,7 @@ typedef enum { CURLUSESSL_CONTROL - SSL for the control connection or fail CURLUSESSL_ALL - SSL for all communication or fail */ - CURLOPT(CURLOPT_USE_SSL, CURLOPTTYPE_LONG, 119), + CURLOPT(CURLOPT_USE_SSL, CURLOPTTYPE_VALUES, 119), /* The _LARGE version of the standard POSTFIELDSIZE option */ CURLOPT(CURLOPT_POSTFIELDSIZE_LARGE, CURLOPTTYPE_OFF_T, 120), @@ -1482,10 +1492,10 @@ typedef enum { CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL */ - CURLOPT(CURLOPT_FTPSSLAUTH, CURLOPTTYPE_LONG, 129), + CURLOPT(CURLOPT_FTPSSLAUTH, CURLOPTTYPE_VALUES, 129), CURLOPT(CURLOPT_IOCTLFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 130), - CURLOPT(CURLOPT_IOCTLDATA, CURLOPTTYPE_OBJECTPOINT, 131), + CURLOPT(CURLOPT_IOCTLDATA, CURLOPTTYPE_CBPOINT, 131), /* 132 OBSOLETE. Gone in 7.16.0 */ /* 133 OBSOLETE. Gone in 7.16.0 */ @@ -1508,7 +1518,7 @@ typedef enum { /* Select "file method" to use when doing FTP, see the curl_ftpmethod above. */ - CURLOPT(CURLOPT_FTP_FILEMETHOD, CURLOPTTYPE_LONG, 138), + CURLOPT(CURLOPT_FTP_FILEMETHOD, CURLOPTTYPE_VALUES, 138), /* Local port number to bind the socket to */ CURLOPT(CURLOPT_LOCALPORT, CURLOPTTYPE_LONG, 139), @@ -1545,14 +1555,14 @@ typedef enum { /* callback function for setting socket options */ CURLOPT(CURLOPT_SOCKOPTFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 148), - CURLOPT(CURLOPT_SOCKOPTDATA, CURLOPTTYPE_OBJECTPOINT, 149), + CURLOPT(CURLOPT_SOCKOPTDATA, CURLOPTTYPE_CBPOINT, 149), /* set to 0 to disable session ID re-use for this transfer, default is enabled (== 1) */ CURLOPT(CURLOPT_SSL_SESSIONID_CACHE, CURLOPTTYPE_LONG, 150), /* allowed SSH authentication methods */ - CURLOPT(CURLOPT_SSH_AUTH_TYPES, CURLOPTTYPE_LONG, 151), + CURLOPT(CURLOPT_SSH_AUTH_TYPES, CURLOPTTYPE_VALUES, 151), /* Used by scp/sftp to do public/private key authentication */ CURLOPT(CURLOPT_SSH_PUBLIC_KEYFILE, CURLOPTTYPE_STRINGPOINT, 152), @@ -1577,7 +1587,7 @@ typedef enum { /* Set the behaviour of POST when redirecting. Values must be set to one of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ - CURLOPT(CURLOPT_POSTREDIR, CURLOPTTYPE_LONG, 161), + CURLOPT(CURLOPT_POSTREDIR, CURLOPTTYPE_VALUES, 161), /* used by scp/sftp to verify the host's public key */ CURLOPT(CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, CURLOPTTYPE_STRINGPOINT, 162), @@ -1587,7 +1597,7 @@ typedef enum { CURL_SOCKET_BAD. The callback should have type curl_opensocket_callback */ CURLOPT(CURLOPT_OPENSOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 163), - CURLOPT(CURLOPT_OPENSOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 164), + CURLOPT(CURLOPT_OPENSOCKETDATA, CURLOPTTYPE_CBPOINT, 164), /* POST volatile input fields. */ CURLOPT(CURLOPT_COPYPOSTFIELDS, CURLOPTTYPE_OBJECTPOINT, 165), @@ -1597,7 +1607,7 @@ typedef enum { /* Callback function for seeking in the input stream */ CURLOPT(CURLOPT_SEEKFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 167), - CURLOPT(CURLOPT_SEEKDATA, CURLOPTTYPE_OBJECTPOINT, 168), + CURLOPT(CURLOPT_SEEKDATA, CURLOPTTYPE_CBPOINT, 168), /* CRL file */ CURLOPT(CURLOPT_CRLFILE, CURLOPTTYPE_STRINGPOINT, 169), @@ -1658,7 +1668,7 @@ typedef enum { CURLOPT(CURLOPT_SSH_KEYFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 184), /* set the SSH host key callback custom pointer */ - CURLOPT(CURLOPT_SSH_KEYDATA, CURLOPTTYPE_OBJECTPOINT, 185), + CURLOPT(CURLOPT_SSH_KEYDATA, CURLOPTTYPE_CBPOINT, 185), /* set the SMTP mail originator */ CURLOPT(CURLOPT_MAIL_FROM, CURLOPTTYPE_STRINGPOINT, 186), @@ -1670,7 +1680,7 @@ typedef enum { CURLOPT(CURLOPT_FTP_USE_PRET, CURLOPTTYPE_LONG, 188), /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ - CURLOPT(CURLOPT_RTSP_REQUEST, CURLOPTTYPE_LONG, 189), + CURLOPT(CURLOPT_RTSP_REQUEST, CURLOPTTYPE_VALUES, 189), /* The RTSP session identifier */ CURLOPT(CURLOPT_RTSP_SESSION_ID, CURLOPTTYPE_STRINGPOINT, 190), @@ -1688,7 +1698,7 @@ typedef enum { CURLOPT(CURLOPT_RTSP_SERVER_CSEQ, CURLOPTTYPE_LONG, 194), /* The stream to pass to INTERLEAVEFUNCTION. */ - CURLOPT(CURLOPT_INTERLEAVEDATA, CURLOPTTYPE_OBJECTPOINT, 195), + CURLOPT(CURLOPT_INTERLEAVEDATA, CURLOPTTYPE_CBPOINT, 195), /* Let the application define a custom write method for RTP data */ CURLOPT(CURLOPT_INTERLEAVEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 196), @@ -1708,10 +1718,10 @@ typedef enum { CURLOPT(CURLOPT_FNMATCH_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 200), /* Let the application define custom chunk data pointer */ - CURLOPT(CURLOPT_CHUNK_DATA, CURLOPTTYPE_OBJECTPOINT, 201), + CURLOPT(CURLOPT_CHUNK_DATA, CURLOPTTYPE_CBPOINT, 201), /* FNMATCH_FUNCTION user pointer */ - CURLOPT(CURLOPT_FNMATCH_DATA, CURLOPTTYPE_OBJECTPOINT, 202), + CURLOPT(CURLOPT_FNMATCH_DATA, CURLOPTTYPE_CBPOINT, 202), /* send linked-list of name:port:address sets */ CURLOPT(CURLOPT_RESOLVE, CURLOPTTYPE_SLISTPOINT, 203), @@ -1740,10 +1750,10 @@ typedef enum { /* Callback function for closing socket (instead of close(2)). The callback should have type curl_closesocket_callback */ CURLOPT(CURLOPT_CLOSESOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 208), - CURLOPT(CURLOPT_CLOSESOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 209), + CURLOPT(CURLOPT_CLOSESOCKETDATA, CURLOPTTYPE_CBPOINT, 209), /* allow GSSAPI credential delegation */ - CURLOPT(CURLOPT_GSSAPI_DELEGATION, CURLOPTTYPE_LONG, 210), + CURLOPT(CURLOPT_GSSAPI_DELEGATION, CURLOPTTYPE_VALUES, 210), /* Set the name servers to use for DNS resolution */ CURLOPT(CURLOPT_DNS_SERVERS, CURLOPTTYPE_STRINGPOINT, 211), @@ -1760,7 +1770,7 @@ typedef enum { CURLOPT(CURLOPT_TCP_KEEPINTVL, CURLOPTTYPE_LONG, 215), /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */ - CURLOPT(CURLOPT_SSL_OPTIONS, CURLOPTTYPE_LONG, 216), + CURLOPT(CURLOPT_SSL_OPTIONS, CURLOPTTYPE_VALUES, 216), /* Set the SMTP auth originator */ CURLOPT(CURLOPT_MAIL_AUTH, CURLOPTTYPE_STRINGPOINT, 217), @@ -1807,7 +1817,7 @@ typedef enum { CURLOPT(CURLOPT_PROXYHEADER, CURLOPTTYPE_SLISTPOINT, 228), /* Pass in a bitmask of "header options" */ - CURLOPT(CURLOPT_HEADEROPT, CURLOPTTYPE_LONG, 229), + CURLOPT(CURLOPT_HEADEROPT, CURLOPTTYPE_VALUES, 229), /* The public key in DER form used to validate the peer public key this option is used only if SSL_VERIFYPEER is true */ @@ -1879,7 +1889,7 @@ typedef enum { /* What version to specifically try to use for proxy. See CURL_SSLVERSION defines below. */ - CURLOPT(CURLOPT_PROXY_SSLVERSION, CURLOPTTYPE_LONG, 250), + CURLOPT(CURLOPT_PROXY_SSLVERSION, CURLOPTTYPE_VALUES, 250), /* Set a username for authenticated TLS for proxy */ CURLOPT(CURLOPT_PROXY_TLSAUTH_USERNAME, CURLOPTTYPE_STRINGPOINT, 251), @@ -1953,7 +1963,7 @@ typedef enum { CURLOPT(CURLOPT_RESOLVER_START_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 272), /* User data to pass to the resolver start callback. */ - CURLOPT(CURLOPT_RESOLVER_START_DATA, CURLOPTTYPE_OBJECTPOINT, 273), + CURLOPT(CURLOPT_RESOLVER_START_DATA, CURLOPTTYPE_CBPOINT, 273), /* send HAProxy PROXY protocol header? */ CURLOPT(CURLOPT_HAPROXYPROTOCOL, CURLOPTTYPE_LONG, 274), @@ -1984,7 +1994,7 @@ typedef enum { CURLOPT(CURLOPT_TRAILERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 283), /* pointer to be passed to HTTP_TRAILER_FUNCTION */ - CURLOPT(CURLOPT_TRAILERDATA, CURLOPTTYPE_OBJECTPOINT, 284), + CURLOPT(CURLOPT_TRAILERDATA, CURLOPTTYPE_CBPOINT, 284), /* set this to 1L to allow HTTP/0.9 responses or 0L to disallow */ CURLOPT(CURLOPT_HTTP09_ALLOWED, CURLOPTTYPE_LONG, 285), @@ -2948,6 +2958,7 @@ CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); #include "easy.h" /* nothing in curl is fun without the easy stuff */ #include "multi.h" #include "urlapi.h" +#include "options.h" /* the typechecker doesn't work in C++ (yet) */ #if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ diff --git a/include/curl/options.h b/include/curl/options.h new file mode 100644 index 000000000..f3bd8e191 --- /dev/null +++ b/include/curl/options.h @@ -0,0 +1,68 @@ +#ifndef CURLINC_OPTIONS_H +#define CURLINC_OPTIONS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2018 - 2020, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + CURLOT_LONG, /* long (a range of values) */ + CURLOT_VALUES, /* (a defined set or bitmask) */ + CURLOT_OFF_T, /* curl_off_t (a range of values) */ + CURLOT_OBJECT, /* pointer (void *) */ + CURLOT_STRING, /* (char * to zero terminated buffer) */ + CURLOT_SLIST, /* (struct curl_slist *) */ + CURLOT_CBPTR, /* (void * passed as-is to a callback) */ + CURLOT_BLOB, /* blob (struct curl_blob *) */ + CURLOT_FUNCTION /* function pointer */ +} curl_easytype; + +/* Flag bits */ + +/* "alias" means it is provided for old programs to remain functional, + we prefer another name */ +#define CURLOT_FLAG_ALIAS (1<<0) + +/* The CURLOPTTYPE_* id ranges can still be used to figure out what type/size + to use for curl_easy_setopt() for the given id */ +struct curl_easyoption { + const char *name; + CURLoption id; + curl_easytype type; + unsigned int flags; +}; + +CURL_EXTERN const struct curl_easyoption * +curl_easy_option_by_name(const char *name); + +CURL_EXTERN const struct curl_easyoption * +curl_easy_option_by_id (CURLoption id); + +CURL_EXTERN const struct curl_easyoption * +curl_easy_option_next(const struct curl_easyoption *prev); + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif +#endif /* CURLINC_OPTIONS_H */ diff --git a/lib/Makefile.am b/lib/Makefile.am index f2886ec63..0a263306a 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -153,3 +153,6 @@ TIDY:=clang-tidy tidy: $(TIDY) $(CSOURCES) $(TIDYFLAGS) -- $(AM_CPPFLAGS) $(CPPFLAGS) -DHAVE_CONFIG_H + +optiontable: + perl optiontable.pl < $(top_srcdir)/include/curl/curl.h > easyoptions.c diff --git a/lib/Makefile.inc b/lib/Makefile.inc index ae3f961cf..8b209721b 100644 --- a/lib/Makefile.inc +++ b/lib/Makefile.inc @@ -61,7 +61,7 @@ LIB_CFILES = altsvc.c amigaos.c asyn-ares.c asyn-thread.c base64.c \ socks_gssapi.c socks_sspi.c speedcheck.c splay.c strcase.c strdup.c \ strerror.c strtok.c strtoofft.c system_win32.c telnet.c tftp.c timeval.c \ transfer.c urlapi.c version.c warnless.c wildcard.c x509asn1.c dynbuf.c \ - version_win32.c + version_win32.c easyoptions.c easygetopt.c LIB_HFILES = altsvc.h amigaos.h arpa_telnet.h asyn.h conncache.h connect.h \ content_encoding.h cookie.h curl_addrinfo.h curl_base64.h curl_ctype.h \ @@ -80,7 +80,7 @@ LIB_HFILES = altsvc.h amigaos.h arpa_telnet.h asyn.h conncache.h connect.h \ smb.h smtp.h sockaddr.h socketpair.h socks.h speedcheck.h splay.h strcase.h \ strdup.h strerror.h strtok.h strtoofft.h system_win32.h telnet.h tftp.h \ timeval.h transfer.h urlapi-int.h urldata.h warnless.h wildcard.h \ - x509asn1.h dynbuf.h version_win32.h + x509asn1.h dynbuf.h version_win32.h easyoptions.h LIB_RCFILES = libcurl.rc diff --git a/lib/easygetopt.c b/lib/easygetopt.c new file mode 100644 index 000000000..8cfd49977 --- /dev/null +++ b/lib/easygetopt.c @@ -0,0 +1,73 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ | | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * ___|___/|_| ______| + * + * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#include "strcase.h" +#include "easyoptions.h" + +/* Lookups easy options at runtime */ +static struct curl_easyoption *lookup(const char *name, CURLoption id) +{ + DEBUGASSERT(name || id); + DEBUGASSERT(!Curl_easyopts_check()); + if(name || id) { + struct curl_easyoption *o = &Curl_easyopts[0]; + do { + if(name) { + if(strcasecompare(o->name, name)) + return o; + } + else { + if((o->id == id) && !(o->flags & CURLOT_FLAG_ALIAS)) + /* don't match alias options */ + return o; + } + o++; + } while(o->name); + } + return NULL; +} + +const struct curl_easyoption *curl_easy_option_by_name(const char *name) +{ + return lookup(name, 0); +} + +const struct curl_easyoption *curl_easy_option_by_id(CURLoption id) +{ + return lookup(NULL, id); +} + +/* Iterates over available options */ +const struct curl_easyoption * +curl_easy_option_next(const struct curl_easyoption *prev) +{ + if(prev && prev->name) { + prev++; + if(prev->name) + return prev; + } + else if(!prev) + return &Curl_easyopts[0]; + return NULL; +} + diff --git a/lib/easyoptions.c b/lib/easyoptions.c new file mode 100644 index 000000000..586abfe52 --- /dev/null +++ b/lib/easyoptions.c @@ -0,0 +1,346 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ | | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * ___|___/|_| ______| + * + * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* This source code is generated by optiontable.pl - DO NOT EDIT BY HAND */ + +#include "curl_setup.h" +#include "easyoptions.h" + +/* all easy setopt options listed in alphabetical order */ +struct curl_easyoption Curl_easyopts[] = { + {"ABSTRACT_UNIX_SOCKET", CURLOPT_ABSTRACT_UNIX_SOCKET, CURLOT_STRING, 0}, + {"ACCEPTTIMEOUT_MS", CURLOPT_ACCEPTTIMEOUT_MS, CURLOT_LONG, 0}, + {"ACCEPT_ENCODING", CURLOPT_ACCEPT_ENCODING, CURLOT_STRING, 0}, + {"ADDRESS_SCOPE", CURLOPT_ADDRESS_SCOPE, CURLOT_LONG, 0}, + {"ALTSVC", CURLOPT_ALTSVC, CURLOT_STRING, 0}, + {"ALTSVC_CTRL", CURLOPT_ALTSVC_CTRL, CURLOT_LONG, 0}, + {"APPEND", CURLOPT_APPEND, CURLOT_LONG, 0}, + {"AUTOREFERER", CURLOPT_AUTOREFERER, CURLOT_LONG, 0}, + {"BUFFERSIZE", CURLOPT_BUFFERSIZE, CURLOT_LONG, 0}, + {"CAINFO", CURLOPT_CAINFO, CURLOT_STRING, 0}, + {"CAPATH", CURLOPT_CAPATH, CURLOT_STRING, 0}, + {"CERTINFO", CURLOPT_CERTINFO, CURLOT_LONG, 0}, + {"CHUNK_BGN_FUNCTION", CURLOPT_CHUNK_BGN_FUNCTION, CURLOT_FUNCTION, 0}, + {"CHUNK_DATA", CURLOPT_CHUNK_DATA, CURLOT_CBPTR, 0}, + {"CHUNK_END_FUNCTION", CURLOPT_CHUNK_END_FUNCTION, CURLOT_FUNCTION, 0}, + {"CLOSESOCKETDATA", CURLOPT_CLOSESOCKETDATA, CURLOT_CBPTR, 0}, + {"CLOSESOCKETFUNCTION", CURLOPT_CLOSESOCKETFUNCTION, CURLOT_FUNCTION, 0}, + {"CONNECTTIMEOUT", CURLOPT_CONNECTTIMEOUT, CURLOT_LONG, 0}, + {"CONNECTTIMEOUT_MS", CURLOPT_CONNECTTIMEOUT_MS, CURLOT_LONG, 0}, + {"CONNECT_ONLY", CURLOPT_CONNECT_ONLY, CURLOT_LONG, 0}, + {"CONNECT_TO", CURLOPT_CONNECT_TO, CURLOT_SLIST, 0}, + {"CONV_FROM_NETWORK_FUNCTION", CURLOPT_CONV_FROM_NETWORK_FUNCTION, + CURLOT_FUNCTION, 0}, + {"CONV_FROM_UTF8_FUNCTION", CURLOPT_CONV_FROM_UTF8_FUNCTION, + CURLOT_FUNCTION, 0}, + {"CONV_TO_NETWORK_FUNCTION", CURLOPT_CONV_TO_NETWORK_FUNCTION, + CURLOT_FUNCTION, 0}, + {"COOKIE", CURLOPT_COOKIE, CURLOT_STRING, 0}, + {"COOKIEFILE", CURLOPT_COOKIEFILE, CURLOT_STRING, 0}, + {"COOKIEJAR", CURLOPT_COOKIEJAR, CURLOT_STRING, 0}, + {"COOKIELIST", CURLOPT_COOKIELIST, CURLOT_STRING, 0}, + {"COOKIESESSION", CURLOPT_COOKIESESSION, CURLOT_LONG, 0}, + {"COPYPOSTFIELDS", CURLOPT_COPYPOSTFIELDS, CURLOT_OBJECT, 0}, + {"CRLF", CURLOPT_CRLF, CURLOT_LONG, 0}, + {"CRLFILE", CURLOPT_CRLFILE, CURLOT_STRING, 0}, + {"CURLU", CURLOPT_CURLU, CURLOT_OBJECT, 0}, + {"CUSTOMREQUEST", CURLOPT_CUSTOMREQUEST, CURLOT_STRING, 0}, + {"DEBUGDATA", CURLOPT_DEBUGDATA, CURLOT_CBPTR, 0}, + {"DEBUGFUNCTION", CURLOPT_DEBUGFUNCTION, CURLOT_FUNCTION, 0}, + {"DEFAULT_PROTOCOL", CURLOPT_DEFAULT_PROTOCOL, CURLOT_STRING, 0}, + {"DIRLISTONLY", CURLOPT_DIRLISTONLY, CURLOT_LONG, 0}, + {"DISALLOW_USERNAME_IN_URL", CURLOPT_DISALLOW_USERNAME_IN_URL, + CURLOT_LONG, 0}, + {"DNS_CACHE_TIMEOUT", CURLOPT_DNS_CACHE_TIMEOUT, CURLOT_LONG, 0}, + {"DNS_INTERFACE", CURLOPT_DNS_INTERFACE, CURLOT_STRING, 0}, + {"DNS_LOCAL_IP4", CURLOPT_DNS_LOCAL_IP4, CURLOT_STRING, 0}, + {"DNS_LOCAL_IP6", CURLOPT_DNS_LOCAL_IP6, CURLOT_STRING, 0}, + {"DNS_SERVERS", CURLOPT_DNS_SERVERS, CURLOT_STRING, 0}, + {"DNS_SHUFFLE_ADDRESSES", CURLOPT_DNS_SHUFFLE_ADDRESSES, CURLOT_LONG, 0}, + {"DNS_USE_GLOBAL_CACHE", CURLOPT_DNS_USE_GLOBAL_CACHE, CURLOT_LONG, 0}, + {"DOH_URL", CURLOPT_DOH_URL, CURLOT_STRING, 0}, + {"EGDSOCKET", CURLOPT_EGDSOCKET, CURLOT_STRING, 0}, + {"ENCODING", CURLOPT_ACCEPT_ENCODING, CURLOT_STRING, CURLOT_FLAG_ALIAS}, + {"ERRORBUFFER", CURLOPT_ERRORBUFFER, CURLOT_OBJECT, 0}, + {"EXPECT_100_TIMEOUT_MS", CURLOPT_EXPECT_100_TIMEOUT_MS, CURLOT_LONG, 0}, + {"FAILONERROR", CURLOPT_FAILONERROR, CURLOT_LONG, 0}, + {"FILE", CURLOPT_WRITEDATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS}, + {"FILETIME", CURLOPT_FILETIME, CURLOT_LONG, 0}, + {"FNMATCH_DATA", CURLOPT_FNMATCH_DATA, CURLOT_CBPTR, 0}, + {"FNMATCH_FUNCTION", CURLOPT_FNMATCH_FUNCTION, CURLOT_FUNCTION, 0}, + {"FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION, CURLOT_LONG, 0}, + {"FORBID_REUSE", CURLOPT_FORBID_REUSE, CURLOT_LONG, 0}, + {"FRESH_CONNECT", CURLOPT_FRESH_CONNECT, CURLOT_LONG, 0}, + {"FTPAPPEND", CURLOPT_APPEND, CURLOT_LONG, CURLOT_FLAG_ALIAS}, + {"FTPLISTONLY", CURLOPT_DIRLISTONLY, CURLOT_LONG, CURLOT_FLAG_ALIAS}, + {"FTPPORT", CURLOPT_FTPPORT, CURLOT_STRING, 0}, + {"FTPSSLAUTH", CURLOPT_FTPSSLAUTH, CURLOT_VALUES, 0}, + {"FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT, CURLOT_STRING, 0}, + {"FTP_ALTERNATIVE_TO_USER", CURLOPT_FTP_ALTERNATIVE_TO_USER, + CURLOT_STRING, 0}, + {"FTP_CREATE_MISSING_DIRS", CURLOPT_FTP_CREATE_MISSING_DIRS, + CURLOT_LONG, 0}, + {"FTP_FILEMETHOD", CURLOPT_FTP_FILEMETHOD, CURLOT_VALUES, 0}, + {"FTP_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT, CURLOT_LONG, 0}, + {"FTP_SKIP_PASV_IP", CURLOPT_FTP_SKIP_PASV_IP, CURLOT_LONG, 0}, + {"FTP_SSL", CURLOPT_USE_SSL, CURLOT_VALUES, CURLOT_FLAG_ALIAS}, + {"FTP_SSL_CCC", CURLOPT_FTP_SSL_CCC, CURLOT_LONG, 0}, + {"FTP_USE_EPRT", CURLOPT_FTP_USE_EPRT, CURLOT_LONG, 0}, + {"FTP_USE_EPSV", CURLOPT_FTP_USE_EPSV, CURLOT_LONG, 0}, + {"FTP_USE_PRET", CURLOPT_FTP_USE_PRET, CURLOT_LONG, 0}, + {"GSSAPI_DELEGATION", CURLOPT_GSSAPI_DELEGATION, CURLOT_VALUES, 0}, + {"HAPPY_EYEBALLS_TIMEOUT_MS", CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, + CURLOT_LONG, 0}, + {"HAPROXYPROTOCOL", CURLOPT_HAPROXYPROTOCOL, CURLOT_LONG, 0}, + {"HEADER", CURLOPT_HEADER, CURLOT_LONG, 0}, + {"HEADERDATA", CURLOPT_HEADERDATA, CURLOT_CBPTR, 0}, + {"HEADERFUNCTION", CURLOPT_HEADERFUNCTION, CURLOT_FUNCTION, 0}, + {"HEADEROPT", CURLOPT_HEADEROPT, CURLOT_VALUES, 0}, + {"HTTP09_ALLOWED", CURLOPT_HTTP09_ALLOWED, CURLOT_LONG, 0}, + {"HTTP200ALIASES", CURLOPT_HTTP200ALIASES, CURLOT_SLIST, 0}, + {"HTTPAUTH", CURLOPT_HTTPAUTH, CURLOT_VALUES, 0}, + {"HTTPGET", CURLOPT_HTTPGET, CURLOT_LONG, 0}, + {"HTTPHEADER", CURLOPT_HTTPHEADER, CURLOT_SLIST, 0}, + {"HTTPPOST", CURLOPT_HTTPPOST, CURLOT_OBJECT, 0}, + {"HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL, CURLOT_LONG, 0}, + {"HTTP_CONTENT_DECODING", CURLOPT_HTTP_CONTENT_DECODING, CURLOT_LONG, 0}, + {"HTTP_TRANSFER_DECODING", CURLOPT_HTTP_TRANSFER_DECODING, CURLOT_LONG, 0}, + {"HTTP_VERSION", CURLOPT_HTTP_VERSION, CURLOT_VALUES, 0}, + {"IGNORE_CONTENT_LENGTH", CURLOPT_IGNORE_CONTENT_LENGTH, CURLOT_LONG, 0}, + {"INFILE", CURLOPT_READDATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS}, + {"INFILESIZE", CURLOPT_INFILESIZE, CURLOT_LONG, 0}, + {"INFILESIZE_LARGE", CURLOPT_INFILESIZE_LARGE, CURLOT_OFF_T, 0}, + {"INTERFACE", CURLOPT_INTERFACE, CURLOT_STRING, 0}, + {"INTERLEAVEDATA", CURLOPT_INTERLEAVEDATA, CURLOT_CBPTR, 0}, + {"INTERLEAVEFUNCTION", CURLOPT_INTERLEAVEFUNCTION, CURLOT_FUNCTION, 0}, + {"IOCTLDATA", CURLOPT_IOCTLDATA, CURLOT_CBPTR, 0}, + {"IOCTLFUNCTION", CURLOPT_IOCTLFUNCTION, CURLOT_FUNCTION, 0}, + {"IPRESOLVE", CURLOPT_IPRESOLVE, CURLOT_VALUES, 0}, + {"ISSUERCERT", CURLOPT_ISSUERCERT, CURLOT_STRING, 0}, + {"ISSUERCERT_BLOB", CURLOPT_ISSUERCERT_BLOB, CURLOT_BLOB, 0}, + {"KEEP_SENDING_ON_ERROR", CURLOPT_KEEP_SENDING_ON_ERROR, CURLOT_LONG, 0}, + {"KEYPASSWD", CURLOPT_KEYPASSWD, CURLOT_STRING, 0}, + {"KRB4LEVEL", CURLOPT_KRBLEVEL, CURLOT_STRING, CURLOT_FLAG_ALIAS}, + {"KRBLEVEL", CURLOPT_KRBLEVEL, CURLOT_STRING, 0}, + {"LOCALPORT", CURLOPT_LOCALPORT, CURLOT_LONG, 0}, + {"LOCALPORTRANGE", CURLOPT_LOCALPORTRANGE, CURLOT_LONG, 0}, + {"LOGIN_OPTIONS", CURLOPT_LOGIN_OPTIONS, CURLOT_STRING, 0}, + {"LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT, CURLOT_LONG, 0}, + {"LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME, CURLOT_LONG, 0}, + {"MAIL_AUTH", CURLOPT_MAIL_AUTH, CURLOT_STRING, 0}, + {"MAIL_FROM", CURLOPT_MAIL_FROM, CURLOT_STRING, 0}, + {"MAIL_RCPT", CURLOPT_MAIL_RCPT, CURLOT_SLIST, 0}, + {"MAIL_RCPT_ALLLOWFAILS", CURLOPT_MAIL_RCPT_ALLLOWFAILS, CURLOT_LONG, 0}, + {"MAXAGE_CONN", CURLOPT_MAXAGE_CONN, CURLOT_LONG, 0}, + {"MAXCONNECTS", CURLOPT_MAXCONNECTS, CURLOT_LONG, 0}, + {"MAXFILESIZE", CURLOPT_MAXFILESIZE, CURLOT_LONG, 0}, + {"MAXFILESIZE_LARGE", CURLOPT_MAXFILESIZE_LARGE, CURLOT_OFF_T, 0}, + {"MAXREDIRS", CURLOPT_MAXREDIRS, CURLOT_LONG, 0}, + {"MAX_RECV_SPEED_LARGE", CURLOPT_MAX_RECV_SPEED_LARGE, CURLOT_OFF_T, 0}, + {"MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE, CURLOT_OFF_T, 0}, + {"MIMEPOST", CURLOPT_MIMEPOST, CURLOT_OBJECT, 0}, + {"NETRC", CURLOPT_NETRC, CURLOT_VALUES, 0}, + {"NETRC_FILE", CURLOPT_NETRC_FILE, CURLOT_STRING, 0}, + {"NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS, CURLOT_LONG, 0}, + {"NEW_FILE_PERMS", CURLOPT_NEW_FILE_PERMS, CURLOT_LONG, 0}, + {"NOBODY", CURLOPT_NOBODY, CURLOT_LONG, 0}, + {"NOPROGRESS", CURLOPT_NOPROGRESS, CURLOT_LONG, 0}, + {"NOPROXY", CURLOPT_NOPROXY, CURLOT_STRING, 0}, + {"NOSIGNAL", CURLOPT_NOSIGNAL, CURLOT_LONG, 0}, + {"OPENSOCKETDATA", CURLOPT_OPENSOCKETDATA, CURLOT_CBPTR, 0}, + {"OPENSOCKETFUNCTION", CURLOPT_OPENSOCKETFUNCTION, CURLOT_FUNCTION, 0}, + {"PASSWORD", CURLOPT_PASSWORD, CURLOT_STRING, 0}, + {"PATH_AS_IS", CURLOPT_PATH_AS_IS, CURLOT_LONG, 0}, + {"PINNEDPUBLICKEY", CURLOPT_PINNEDPUBLICKEY, CURLOT_STRING, 0}, + {"PIPEWAIT", CURLOPT_PIPEWAIT, CURLOT_LONG, 0}, + {"PORT", CURLOPT_PORT, CURLOT_LONG, 0}, + {"POST", CURLOPT_POST, CURLOT_LONG, 0}, + {"POST301", CURLOPT_POSTREDIR, CURLOT_VALUES, CURLOT_FLAG_ALIAS}, + {"POSTFIELDS", CURLOPT_POSTFIELDS, CURLOT_OBJECT, 0}, + {"POSTFIELDSIZE", CURLOPT_POSTFIELDSIZE, CURLOT_LONG, 0}, + {"POSTFIELDSIZE_LARGE", CURLOPT_POSTFIELDSIZE_LARGE, CURLOT_OFF_T, 0}, + {"POSTQUOTE", CURLOPT_POSTQUOTE, CURLOT_SLIST, 0}, + {"POSTREDIR", CURLOPT_POSTREDIR, CURLOT_VALUES, 0}, + {"PREQUOTE", CURLOPT_PREQUOTE, CURLOT_SLIST, 0}, + {"PRE_PROXY", CURLOPT_PRE_PROXY, CURLOT_STRING, 0}, + {"PRIVATE", CURLOPT_PRIVATE, CURLOT_OBJECT, 0}, + {"PROGRESSDATA", CURLOPT_XFERINFODATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS}, + {"PROGRESSFUNCTION", CURLOPT_PROGRESSFUNCTION, CURLOT_FUNCTION, 0}, + {"PROTOCOLS", CURLOPT_PROTOCOLS, CURLOT_LONG, 0}, + {"PROXY", CURLOPT_PROXY, CURLOT_STRING, 0}, + {"PROXYAUTH", CURLOPT_PROXYAUTH, CURLOT_VALUES, 0}, + {"PROXYHEADER", CURLOPT_PROXYHEADER, CURLOT_SLIST, 0}, + {"PROXYPASSWORD", CURLOPT_PROXYPASSWORD, CURLOT_STRING, 0}, + {"PROXYPORT", CURLOPT_PROXYPORT, CURLOT_LONG, 0}, + {"PROXYTYPE", CURLOPT_PROXYTYPE, CURLOT_VALUES, 0}, + {"PROXYUSERNAME", CURLOPT_PROXYUSERNAME, CURLOT_STRING, 0}, + {"PROXYUSERPWD", CURLOPT_PROXYUSERPWD, CURLOT_STRING, 0}, + {"PROXY_CAINFO", CURLOPT_PROXY_CAINFO, CURLOT_STRING, 0}, + {"PROXY_CAPATH", CURLOPT_PROXY_CAPATH, CURLOT_STRING, 0}, + {"PROXY_CRLFILE", CURLOPT_PROXY_CRLFILE, CURLOT_STRING, 0}, + {"PROXY_ISSUERCERT", CURLOPT_PROXY_ISSUERCERT, CURLOT_STRING, 0}, + {"PROXY_ISSUERCERT_BLOB", CURLOPT_PROXY_ISSUERCERT_BLOB, CURLOT_BLOB, 0}, + {"PROXY_KEYPASSWD", CURLOPT_PROXY_KEYPASSWD, CURLOT_STRING, 0}, + {"PROXY_PINNEDPUBLICKEY", CURLOPT_PROXY_PINNEDPUBLICKEY, CURLOT_STRING, 0}, + {"PROXY_SERVICE_NAME", CURLOPT_PROXY_SERVICE_NAME, CURLOT_STRING, 0}, + {"PROXY_SSLCERT", CURLOPT_PROXY_SSLCERT, CURLOT_STRING, 0}, + {"PROXY_SSLCERTTYPE", CURLOPT_PROXY_SSLCERTTYPE, CURLOT_STRING, 0}, + {"PROXY_SSLCERT_BLOB", CURLOPT_PROXY_SSLCERT_BLOB, CURLOT_BLOB, 0}, + {"PROXY_SSLKEY", CURLOPT_PROXY_SSLKEY, CURLOT_STRING, 0}, + {"PROXY_SSLKEYTYPE", CURLOPT_PROXY_SSLKEYTYPE, CURLOT_STRING, 0}, + {"PROXY_SSLKEY_BLOB", CURLOPT_PROXY_SSLKEY_BLOB, CURLOT_BLOB, 0}, + {"PROXY_SSLVERSION", CURLOPT_PROXY_SSLVERSION, CURLOT_VALUES, 0}, + {"PROXY_SSL_CIPHER_LIST", CURLOPT_PROXY_SSL_CIPHER_LIST, CURLOT_STRING, 0}, + {"PROXY_SSL_OPTIONS", CURLOPT_PROXY_SSL_OPTIONS, CURLOT_LONG, 0}, + {"PROXY_SSL_VERIFYHOST", CURLOPT_PROXY_SSL_VERIFYHOST, CURLOT_LONG, 0}, + {"PROXY_SSL_VERIFYPEER", CURLOPT_PROXY_SSL_VERIFYPEER, CURLOT_LONG, 0}, + {"PROXY_TLS13_CIPHERS", CURLOPT_PROXY_TLS13_CIPHERS, CURLOT_STRING, 0}, + {"PROXY_TLSAUTH_PASSWORD", CURLOPT_PROXY_TLSAUTH_PASSWORD, + CURLOT_STRING, 0}, + {"PROXY_TLSAUTH_TYPE", CURLOPT_PROXY_TLSAUTH_TYPE, CURLOT_STRING, 0}, + {"PROXY_TLSAUTH_USERNAME", CURLOPT_PROXY_TLSAUTH_USERNAME, + CURLOT_STRING, 0}, + {"PROXY_TRANSFER_MODE", CURLOPT_PROXY_TRANSFER_MODE, CURLOT_LONG, 0}, + {"PUT", CURLOPT_PUT, CURLOT_LONG, 0}, + {"QUOTE", CURLOPT_QUOTE, CURLOT_SLIST, 0}, + {"RANDOM_FILE", CURLOPT_RANDOM_FILE, CURLOT_STRING, 0}, + {"RANGE", CURLOPT_RANGE, CURLOT_STRING, 0}, + {"READDATA", CURLOPT_READDATA, CURLOT_CBPTR, 0}, + {"READFUNCTION", CURLOPT_READFUNCTION, CURLOT_FUNCTION, 0}, + {"REDIR_PROTOCOLS", CURLOPT_REDIR_PROTOCOLS, CURLOT_LONG, 0}, + {"REFERER", CURLOPT_REFERER, CURLOT_STRING, 0}, + {"REQUEST_TARGET", CURLOPT_REQUEST_TARGET, CURLOT_STRING, 0}, + {"RESOLVE", CURLOPT_RESOLVE, CURLOT_SLIST, 0}, + {"RESOLVER_START_DATA", CURLOPT_RESOLVER_START_DATA, CURLOT_CBPTR, 0}, + {"RESOLVER_START_FUNCTION", CURLOPT_RESOLVER_START_FUNCTION, + CURLOT_FUNCTION, 0}, + {"RESUME_FROM", CURLOPT_RESUME_FROM, CURLOT_LONG, 0}, + {"RESUME_FROM_LARGE", CURLOPT_RESUME_FROM_LARGE, CURLOT_OFF_T, 0}, + {"RTSPHEADER", CURLOPT_HTTPHEADER, CURLOT_SLIST, CURLOT_FLAG_ALIAS}, + {"RTSP_CLIENT_CSEQ", CURLOPT_RTSP_CLIENT_CSEQ, CURLOT_LONG, 0}, + {"RTSP_REQUEST", CURLOPT_RTSP_REQUEST, CURLOT_VALUES, 0}, + {"RTSP_SERVER_CSEQ", CURLOPT_RTSP_SERVER_CSEQ, CURLOT_LONG, 0}, + {"RTSP_SESSION_ID", CURLOPT_RTSP_SESSION_ID, CURLOT_STRING, 0}, + {"RTSP_STREAM_URI", CURLOPT_RTSP_STREAM_URI, CURLOT_STRING, 0}, + {"RTSP_TRANSPORT", CURLOPT_RTSP_TRANSPORT, CURLOT_STRING, 0}, + {"SASL_AUTHZID", CURLOPT_SASL_AUTHZID, CURLOT_STRING, 0}, + {"SASL_IR", CURLOPT_SASL_IR, CURLOT_LONG, 0}, + {"SEEKDATA", CURLOPT_SEEKDATA, CURLOT_CBPTR, 0}, + {"SEEKFUNCTION", CURLOPT_SEEKFUNCTION, CURLOT_FUNCTION, 0}, + {"SERVER_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT, + CURLOT_LONG, CURLOT_FLAG_ALIAS}, + {"SERVICE_NAME", CURLOPT_SERVICE_NAME, CURLOT_STRING, 0}, + {"SHARE", CURLOPT_SHARE, CURLOT_OBJECT, 0}, + {"SOCKOPTDATA", CURLOPT_SOCKOPTDATA, CURLOT_CBPTR, 0}, + {"SOCKOPTFUNCTION", CURLOPT_SOCKOPTFUNCTION, CURLOT_FUNCTION, 0}, + {"SOCKS5_AUTH", CURLOPT_SOCKS5_AUTH, CURLOT_LONG, 0}, + {"SOCKS5_GSSAPI_NEC", CURLOPT_SOCKS5_GSSAPI_NEC, CURLOT_LONG, 0}, + {"SOCKS5_GSSAPI_SERVICE", CURLOPT_SOCKS5_GSSAPI_SERVICE, CURLOT_STRING, 0}, + {"SSH_AUTH_TYPES", CURLOPT_SSH_AUTH_TYPES, CURLOT_VALUES, 0}, + {"SSH_COMPRESSION", CURLOPT_SSH_COMPRESSION, CURLOT_LONG, 0}, + {"SSH_HOST_PUBLIC_KEY_MD5", CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, + CURLOT_STRING, 0}, + {"SSH_KEYDATA", CURLOPT_SSH_KEYDATA, CURLOT_CBPTR, 0}, + {"SSH_KEYFUNCTION", CURLOPT_SSH_KEYFUNCTION, CURLOT_FUNCTION, 0}, + {"SSH_KNOWNHOSTS", CURLOPT_SSH_KNOWNHOSTS, CURLOT_STRING, 0}, + {"SSH_PRIVATE_KEYFILE", CURLOPT_SSH_PRIVATE_KEYFILE, CURLOT_STRING, 0}, + {"SSH_PUBLIC_KEYFILE", CURLOPT_SSH_PUBLIC_KEYFILE, CURLOT_STRING, 0}, + {"SSLCERT", CURLOPT_SSLCERT, CURLOT_STRING, 0}, + {"SSLCERTPASSWD", CURLOPT_KEYPASSWD, CURLOT_STRING, CURLOT_FLAG_ALIAS}, + {"SSLCERTTYPE", CURLOPT_SSLCERTTYPE, CURLOT_STRING, 0}, + {"SSLCERT_BLOB", CURLOPT_SSLCERT_BLOB, CURLOT_BLOB, 0}, + {"SSLENGINE", CURLOPT_SSLENGINE, CURLOT_STRING, 0}, + {"SSLENGINE_DEFAULT", CURLOPT_SSLENGINE_DEFAULT, CURLOT_LONG, 0}, + {"SSLKEY", CURLOPT_SSLKEY, CURLOT_STRING, 0}, + {"SSLKEYPASSWD", CURLOPT_KEYPASSWD, CURLOT_STRING, CURLOT_FLAG_ALIAS}, + {"SSLKEYTYPE", CURLOPT_SSLKEYTYPE, CURLOT_STRING, 0}, + {"SSLKEY_BLOB", CURLOPT_SSLKEY_BLOB, CURLOT_BLOB, 0}, + {"SSLVERSION", CURLOPT_SSLVERSION, CURLOT_VALUES, 0}, + {"SSL_CIPHER_LIST", CURLOPT_SSL_CIPHER_LIST, CURLOT_STRING, 0}, + {"SSL_CTX_DATA", CURLOPT_SSL_CTX_DATA, CURLOT_CBPTR, 0}, + {"SSL_CTX_FUNCTION", CURLOPT_SSL_CTX_FUNCTION, CURLOT_FUNCTION, 0}, + {"SSL_ENABLE_ALPN", CURLOPT_SSL_ENABLE_ALPN, CURLOT_LONG, 0}, + {"SSL_ENABLE_NPN", CURLOPT_SSL_ENABLE_NPN, CURLOT_LONG, 0}, + {"SSL_FALSESTART", CURLOPT_SSL_FALSESTART, CURLOT_LONG, 0}, + {"SSL_OPTIONS", CURLOPT_SSL_OPTIONS, CURLOT_VALUES, 0}, + {"SSL_SESSIONID_CACHE", CURLOPT_SSL_SESSIONID_CACHE, CURLOT_LONG, 0}, + {"SSL_VERIFYHOST", CURLOPT_SSL_VERIFYHOST, CURLOT_LONG, 0}, + {"SSL_VERIFYPEER", CURLOPT_SSL_VERIFYPEER, CURLOT_LONG, 0}, + {"SSL_VERIFYSTATUS", CURLOPT_SSL_VERIFYSTATUS, CURLOT_LONG, 0}, + {"STDERR", CURLOPT_STDERR, CURLOT_OBJECT, 0}, + {"STREAM_DEPENDS", CURLOPT_STREAM_DEPENDS, CURLOT_OBJECT, 0}, + {"STREAM_DEPENDS_E", CURLOPT_STREAM_DEPENDS_E, CURLOT_OBJECT, 0}, + {"STREAM_WEIGHT", CURLOPT_STREAM_WEIGHT, CURLOT_LONG, 0}, + {"SUPPRESS_CONNECT_HEADERS", CURLOPT_SUPPRESS_CONNECT_HEADERS, + CURLOT_LONG, 0}, + {"TCP_FASTOPEN", CURLOPT_TCP_FASTOPEN, CURLOT_LONG, 0}, + {"TCP_KEEPALIVE", CURLOPT_TCP_KEEPALIVE, CURLOT_LONG, 0}, + {"TCP_KEEPIDLE", CURLOPT_TCP_KEEPIDLE, CURLOT_LONG, 0}, + {"TCP_KEEPINTVL", CURLOPT_TCP_KEEPINTVL, CURLOT_LONG, 0}, + {"TCP_NODELAY", CURLOPT_TCP_NODELAY, CURLOT_LONG, 0}, + {"TELNETOPTIONS", CURLOPT_TELNETOPTIONS, CURLOT_SLIST, 0}, + {"TFTP_BLKSIZE", CURLOPT_TFTP_BLKSIZE, CURLOT_LONG, 0}, + {"TFTP_NO_OPTIONS", CURLOPT_TFTP_NO_OPTIONS, CURLOT_LONG, 0}, + {"TIMECONDITION", CURLOPT_TIMECONDITION, CURLOT_VALUES, 0}, + {"TIMEOUT", CURLOPT_TIMEOUT, CURLOT_LONG, 0}, + {"TIMEOUT_MS", CURLOPT_TIMEOUT_MS, CURLOT_LONG, 0}, + {"TIMEVALUE", CURLOPT_TIMEVALUE, CURLOT_LONG, 0}, + {"TIMEVALUE_LARGE", CURLOPT_TIMEVALUE_LARGE, CURLOT_OFF_T, 0}, + {"TLS13_CIPHERS", CURLOPT_TLS13_CIPHERS, CURLOT_STRING, 0}, + {"TLSAUTH_PASSWORD", CURLOPT_TLSAUTH_PASSWORD, CURLOT_STRING, 0}, + {"TLSAUTH_TYPE", CURLOPT_TLSAUTH_TYPE, CURLOT_STRING, 0}, + {"TLSAUTH_USERNAME", CURLOPT_TLSAUTH_USERNAME, CURLOT_STRING, 0}, + {"TRAILERDATA", CURLOPT_TRAILERDATA, CURLOT_CBPTR, 0}, + {"TRAILERFUNCTION", CURLOPT_TRAILERFUNCTION, CURLOT_FUNCTION, 0}, + {"TRANSFERTEXT", CURLOPT_TRANSFERTEXT, CURLOT_LONG, 0}, + {"TRANSFER_ENCODING", CURLOPT_TRANSFER_ENCODING, CURLOT_LONG, 0}, + {"UNIX_SOCKET_PATH", CURLOPT_UNIX_SOCKET_PATH, CURLOT_STRING, 0}, + {"UNRESTRICTED_AUTH", CURLOPT_UNRESTRICTED_AUTH, CURLOT_LONG, 0}, + {"UPKEEP_INTERVAL_MS", CURLOPT_UPKEEP_INTERVAL_MS, CURLOT_LONG, 0}, + {"UPLOAD", CURLOPT_UPLOAD, CURLOT_LONG, 0}, + {"UPLOAD_BUFFERSIZE", CURLOPT_UPLOAD_BUFFERSIZE, CURLOT_LONG, 0}, + {"URL", CURLOPT_URL, CURLOT_STRING, 0}, + {"USERAGENT", CURLOPT_USERAGENT, CURLOT_STRING, 0}, + {"USERNAME", CURLOPT_USERNAME, CURLOT_STRING, 0}, + {"USERPWD", CURLOPT_USERPWD, CURLOT_STRING, 0}, + {"USE_SSL", CURLOPT_USE_SSL, CURLOT_VALUES, 0}, + {"VERBOSE", CURLOPT_VERBOSE, CURLOT_LONG, 0}, + {"WILDCARDMATCH", CURLOPT_WILDCARDMATCH, CURLOT_LONG, 0}, + {"WRITEDATA", CURLOPT_WRITEDATA, CURLOT_CBPTR, 0}, + {"WRITEFUNCTION", CURLOPT_WRITEFUNCTION, CURLOT_FUNCTION, 0}, + {"WRITEHEADER", CURLOPT_HEADERDATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS}, + {"XFERINFODATA", CURLOPT_XFERINFODATA, CURLOT_CBPTR, 0}, + {"XFERINFOFUNCTION", CURLOPT_XFERINFOFUNCTION, CURLOT_FUNCTION, 0}, + {"XOAUTH2_BEARER", CURLOPT_XOAUTH2_BEARER, CURLOT_STRING, 0}, + {NULL, 0, 0, 0} /* end of table */ +}; + +#ifdef CURLDEBUG +/* + * Curl_easyopts_check() is a debug-only function that returns non-zero + * if this source file is not in sync with the options listed in curl/curl.h + */ +int Curl_easyopts_check(void) +{ + return (CURLOPT_LASTENTRY != (297 + 1)); +} +#endif diff --git a/lib/easyoptions.h b/lib/easyoptions.h new file mode 100644 index 000000000..4b681a47e --- /dev/null +++ b/lib/easyoptions.h @@ -0,0 +1,35 @@ +#ifndef HEADER_CURL_EASYOPTIONS_H +#define HEADER_CURL_EASYOPTIONS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* should probably go into the public header */ + +#include + +/* generated table with all easy options */ +extern struct curl_easyoption Curl_easyopts[]; + +#ifdef CURLDEBUG +int Curl_easyopts_check(void); +#endif +#endif diff --git a/lib/optiontable.pl b/lib/optiontable.pl new file mode 100644 index 000000000..1348eedae --- /dev/null +++ b/lib/optiontable.pl @@ -0,0 +1,118 @@ +#!/usr/bin/perl + +print <, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* This source code is generated by optiontable.pl - DO NOT EDIT BY HAND */ + +#include "curl_setup.h" +#include "easyoptions.h" + +/* all easy setopt options listed in alphabetical order */ +struct curl_easyoption Curl_easyopts[] = { +HEAD + ; + +my $lastnum=0; + +while() { + if(/^ *CURLOPT\(([^,]*), ([^,]*), (\d+)\)/) { + my($opt, $type, $num)=($1,$2,$3); + my $name; + my $ext = $type; + + if($opt =~ /OBSOLETE/) { + # skip obsolete options + next; + } + + if($opt =~ /^CURLOPT_(.*)/) { + $name=$1; + } + $ext =~ s/CURLOPTTYPE_//; + $ext =~ s/CBPOINT/CBPTR/; + $ext =~ s/POINT\z//; + $type = "CURLOT_$ext"; + + $opt{$name} = $opt; + $type{$name} = $type; + push @names, $name; + if($num < $lastnum) { + print STDERR "ERROR: $opt has bad number\n"; + exit 2; + } + else { + $lastnum = $num; + } + } + + # alias for an older option + # old = new + if(/^#define (CURLOPT_[^ ]*) *(CURLOPT_\S*)/) { + my ($o, $n)=($1, $2); + # skip obsolete ones + if($n !~ /OBSOLETE/) { + $o =~ s/^CURLOPT_//; + $n =~ s/^CURLOPT_//; + $alias{$o} = $n; + push @names, $o, + } + } +} + + +for my $name (sort @names) { + my $oname = $name; + my $a = $alias{$name}; + my $flag = "0"; + if($a) { + $name = $alias{$name}; + $flag = "CURLOT_FLAG_ALIAS"; + } + $o = sprintf(" {\"%s\", %s, %s, %s},\n", + $oname, $opt{$name}, $type{$name}, $flag); + if(length($o) < 80) { + print $o; + } + else { + printf(" {\"%s\", %s,\n %s, %s},\n", + $oname, $opt{$name}, $type{$name}, $flag); + } +} + +print < CURL_MAX_INPUT_LENGTH) + return CURLE_BAD_FUNCTION_ARGUMENT; /* append the cookie file name to the list of file names, and deal with them later */ cl = curl_slist_append(data->change.cookielist, argptr); @@ -804,6 +807,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* if cookie engine was not running, activate it */ data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE); + /* general protection against mistakes and abuse */ + if(strlen(argptr) > CURL_MAX_INPUT_LENGTH) + return CURLE_BAD_FUNCTION_ARGUMENT; argptr = strdup(argptr); if(!argptr || !data->cookies) { result = CURLE_OUT_OF_MEMORY; diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc index c13fb7307..fa84a9560 100644 --- a/tests/data/Makefile.inc +++ b/tests/data/Makefile.inc @@ -207,7 +207,7 @@ test1700 test1701 test1702 \ test1800 test1801 \ \ test1900 test1901 test1902 test1903 test1904 test1905 test1906 test1907 \ -test1908 test1909 test1910 \ +test1908 test1909 test1910 test1911 \ \ test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \ test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \ diff --git a/tests/data/test1119 b/tests/data/test1119 index 5fb3c944a..2f1b54c23 100644 --- a/tests/data/test1119 +++ b/tests/data/test1119 @@ -27,5 +27,4 @@ Verify that symbols-in-versions and headers are in sync OK - diff --git a/tests/data/test1911 b/tests/data/test1911 new file mode 100644 index 000000000..78f0b8d8f --- /dev/null +++ b/tests/data/test1911 @@ -0,0 +1,31 @@ + + + +curl_easy_option + + + +# Server-side + + + + + +# Client-side + + +none + + +verify that curl_easy_setopt() rejects too long string inputs + + +lib1911 + + + + +# Verify data after the test has been "shot" + + + diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc index 2c9c66539..576c88a86 100644 --- a/tests/libtest/Makefile.inc +++ b/tests/libtest/Makefile.inc @@ -58,7 +58,7 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect \ lib1550 lib1551 lib1552 lib1553 lib1554 lib1555 lib1556 lib1557 \ lib1558 lib1559 lib1560 lib1564 lib1565 lib1567 \ lib1591 lib1592 lib1593 lib1594 lib1596 \ - lib1900 lib1905 lib1906 lib1907 lib1908 lib1910 \ + lib1900 lib1905 lib1906 lib1907 lib1908 lib1910 lib1911 \ lib2033 lib3010 chkdecimalpoint_SOURCES = chkdecimalpoint.c ../../lib/mprintf.c \ @@ -649,6 +649,10 @@ lib1910_SOURCES = lib1910.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) lib1910_LDADD = $(TESTUTIL_LIBS) lib1910_CPPFLAGS = $(AM_CPPFLAGS) +lib1911_SOURCES = lib1911.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib1911_LDADD = $(TESTUTIL_LIBS) +lib1911_CPPFLAGS = $(AM_CPPFLAGS) + lib2033_SOURCES = libntlmconnect.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) lib2033_LDADD = $(TESTUTIL_LIBS) lib2033_CPPFLAGS = $(AM_CPPFLAGS) -DUSE_PIPELINING diff --git a/tests/libtest/lib1911.c b/tests/libtest/lib1911.c new file mode 100644 index 000000000..3fafd286a --- /dev/null +++ b/tests/libtest/lib1911.c @@ -0,0 +1,87 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "test.h" + +#include "testutil.h" +#include "warnless.h" +#include "memdebug.h" + +/* The maximum string length limit (CURL_MAX_INPUT_LENGTH) is an internal + define not publicly exposed so we set our own */ +#define MAX_INPUT_LENGTH 8000000 + +static char buffer[MAX_INPUT_LENGTH + 2]; + +int test(char *URL) +{ + const struct curl_easyoption *o; + CURL *easy; + int error = 0; + (void)URL; + + easy = curl_easy_init(); + if(!easy) + return 1; + + /* make it a zero terminated C string with just As */ + memset(buffer, 'A', MAX_INPUT_LENGTH + 1); + buffer[MAX_INPUT_LENGTH + 1] = 0; + + printf("string length: %d\n", (int)strlen(buffer)); + + for(o = curl_easy_option_next(NULL); + o; + o = curl_easy_option_next(o)) { + if(o->type == CURLOT_STRING) { + CURLcode result; + /* + * Whitelist string options that are safe for abuse + */ + switch(o->id) { + case CURLOPT_PROXY_TLSAUTH_TYPE: + case CURLOPT_TLSAUTH_TYPE: + continue; + default: + /* check this */ + break; + } + + /* This is a string. Make sure that passing in a string longer + CURL_MAX_INPUT_LENGTH returns an error */ + result = curl_easy_setopt(easy, o->id, buffer); + switch(result) { + case CURLE_BAD_FUNCTION_ARGUMENT: /* the most normal */ + case CURLE_UNKNOWN_OPTION: /* left out from the build */ + case CURLE_NOT_BUILT_IN: /* not supported */ + break; + default: + /* all other return codes are unexpected */ + fprintf(stderr, "curl_easy_setopt(%s...) returned %d\n", + o->name, (int)result); + error++; + break; + } + } + } + curl_easy_cleanup(easy); + return error; +} diff --git a/tests/libtest/mk-lib1521.pl b/tests/libtest/mk-lib1521.pl index f4ef19fe7..e71fe1e51 100755 --- a/tests/libtest/mk-lib1521.pl +++ b/tests/libtest/mk-lib1521.pl @@ -184,13 +184,15 @@ while() { print "${pref} \"string\");\n$check"; print "${pref} NULL);\n$check"; } - elsif($type eq "CURLOPTTYPE_LONG") { + elsif(($type eq "CURLOPTTYPE_LONG") || + ($type eq "CURLOPTTYPE_VALUES")) { print "${pref} 0L);\n$check"; print "${pref} 22L);\n$check"; print "${pref} LO);\n$check"; print "${pref} HI);\n$check"; } - elsif($type eq "CURLOPTTYPE_OBJECTPOINT") { + elsif(($type eq "CURLOPTTYPE_OBJECTPOINT") || + ($type eq "CURLOPTTYPE_CBPOINT")) { if($name =~ /DEPENDS/) { print "${pref} dep);\n$check"; } @@ -244,8 +246,8 @@ while() { print "${pref} &blob);\n$check"; } else { - print STDERR "\n---- $type\n"; - exit; # exit to make this noticed! + print STDERR "\nUnknown type: $type\n"; + exit 22; # exit to make this noticed! } } elsif($_ =~ /^ CURLINFO_NONE/) { diff --git a/tests/symbol-scan.pl b/tests/symbol-scan.pl index 7905ee772..2b2d6278b 100755 --- a/tests/symbol-scan.pl +++ b/tests/symbol-scan.pl @@ -176,7 +176,7 @@ if($summary) { } if($misses) { - exit 2; # there are stuff to attend to! + exit 0; # there are stuff to attend to! } else { print "OK\n";