From 95f98ad8e82f1a5bd51eab5cb49a3547d86bb1ca Mon Sep 17 00:00:00 2001
From: 761417898 <761417898@qq.com>
Date: Wed, 16 Sep 2026 12:35:46 +0800
Subject: [PATCH 01/15] Add ODBC client and packaging CI
---
.github/scripts/native-linux-env.sh | 20 +
.../package-client-cpp-manylinux228.sh | 12 +-
.github/scripts/package-odbc-manylinux228.sh | 34 +
.github/workflows/client-cpp-package.yml | 8 +-
.github/workflows/multi-language-client.yml | 4 +-
.github/workflows/odbc-package.yml | 106 +
iotdb-client/client-cpp/CMakeLists.txt | 57 +-
.../client-cpp/cmake/FetchBoost.cmake | 4 +-
.../client-cpp/cmake/FetchBuildTools.cmake | 6 +-
.../client-cpp/cmake/FetchOpenSSL.cmake | 41 +-
.../client-cpp/cmake/FetchThrift.cmake | 20 +-
.../cmake/GenerateThriftSources.cmake | 4 +-
iotdb-client/client-cpp/src/include/Export.h | 4 +-
iotdb-client/odbc/.gitignore | 28 +
iotdb-client/odbc/CMakeLists.txt | 144 +
iotdb-client/odbc/README.md | 117 +
iotdb-client/odbc/SOURCE.md | 48 +
iotdb-client/odbc/VALIDATION.md | 73 +
.../odbc/cmake/CheckLinuxPackage.cmake | 53 +
iotdb-client/odbc/conf/odbc.ini | 29 +
iotdb-client/odbc/conf/odbcinst.ini | 20 +
.../curl-src/CMake/CMakeConfigurableFile.in | 24 +
.../curl-src/CMake/CurlSymbolHiding.cmake | 84 +
.../odbc/deps/curl-src/CMake/CurlTests.c | 515 +
.../deps/curl-src/CMake/FindBearSSL.cmake | 32 +
.../odbc/deps/curl-src/CMake/FindBrotli.cmake | 43 +
.../odbc/deps/curl-src/CMake/FindCARES.cmake | 47 +
.../odbc/deps/curl-src/CMake/FindGSS.cmake | 312 +
.../odbc/deps/curl-src/CMake/FindLibPSL.cmake | 45 +
.../deps/curl-src/CMake/FindLibSSH2.cmake | 45 +
.../odbc/deps/curl-src/CMake/FindMSH3.cmake | 70 +
.../deps/curl-src/CMake/FindMbedTLS.cmake | 36 +
.../deps/curl-src/CMake/FindNGHTTP2.cmake | 41 +
.../deps/curl-src/CMake/FindNGHTTP3.cmake | 78 +
.../odbc/deps/curl-src/CMake/FindNGTCP2.cmake | 117 +
.../odbc/deps/curl-src/CMake/FindQUICHE.cmake | 70 +
.../deps/curl-src/CMake/FindWolfSSL.cmake | 36 +
.../odbc/deps/curl-src/CMake/FindZstd.cmake | 71 +
.../odbc/deps/curl-src/CMake/Macros.cmake | 122 +
.../odbc/deps/curl-src/CMake/OtherTests.cmake | 221 +
.../deps/curl-src/CMake/PickyWarnings.cmake | 197 +
.../CMake/Platforms/WindowsCache.cmake | 133 +
.../odbc/deps/curl-src/CMake/Utilities.cmake | 35 +
.../curl-src/CMake/cmake_uninstall.cmake.in | 49 +
.../deps/curl-src/CMake/curl-config.cmake.in | 38 +
.../odbc/deps/curl-src/CMakeLists.txt | 1749 ++
iotdb-client/odbc/deps/curl-src/COPYING | 22 +
.../odbc/deps/curl-src/curl-config.in | 196 +
.../odbc/deps/curl-src/include/Makefile.am | 28 +
.../odbc/deps/curl-src/include/README.md | 20 +
.../deps/curl-src/include/curl/.gitignore | 7 +
.../deps/curl-src/include/curl/Makefile.am | 41 +
.../odbc/deps/curl-src/include/curl/curl.h | 3241 ++
.../odbc/deps/curl-src/include/curl/curlver.h | 79 +
.../odbc/deps/curl-src/include/curl/easy.h | 125 +
.../odbc/deps/curl-src/include/curl/header.h | 74 +
.../odbc/deps/curl-src/include/curl/mprintf.h | 70 +
.../odbc/deps/curl-src/include/curl/multi.h | 471 +
.../odbc/deps/curl-src/include/curl/options.h | 70 +
.../deps/curl-src/include/curl/stdcheaders.h | 35 +
.../odbc/deps/curl-src/include/curl/system.h | 521 +
.../curl-src/include/curl/typecheck-gcc.h | 717 +
.../odbc/deps/curl-src/include/curl/urlapi.h | 150 +
.../deps/curl-src/include/curl/websockets.h | 84 +
iotdb-client/odbc/deps/curl-src/lib/.checksrc | 1 +
.../odbc/deps/curl-src/lib/.gitattributes | 3 +
.../odbc/deps/curl-src/lib/.gitignore | 17 +
.../odbc/deps/curl-src/lib/CMakeLists.txt | 235 +
.../odbc/deps/curl-src/lib/Makefile.am | 149 +
.../odbc/deps/curl-src/lib/Makefile.inc | 370 +
.../odbc/deps/curl-src/lib/Makefile.mk | 426 +
.../odbc/deps/curl-src/lib/Makefile.soname | 42 +
iotdb-client/odbc/deps/curl-src/lib/altsvc.c | 719 +
iotdb-client/odbc/deps/curl-src/lib/altsvc.h | 81 +
iotdb-client/odbc/deps/curl-src/lib/amigaos.c | 247 +
iotdb-client/odbc/deps/curl-src/lib/amigaos.h | 41 +
.../odbc/deps/curl-src/lib/arpa_telnet.h | 110 +
.../odbc/deps/curl-src/lib/asyn-ares.c | 939 +
.../odbc/deps/curl-src/lib/asyn-thread.c | 760 +
iotdb-client/odbc/deps/curl-src/lib/asyn.h | 184 +
iotdb-client/odbc/deps/curl-src/lib/base64.c | 292 +
iotdb-client/odbc/deps/curl-src/lib/bufq.c | 656 +
iotdb-client/odbc/deps/curl-src/lib/bufq.h | 265 +
iotdb-client/odbc/deps/curl-src/lib/bufref.c | 129 +
iotdb-client/odbc/deps/curl-src/lib/bufref.h | 48 +
iotdb-client/odbc/deps/curl-src/lib/c-hyper.c | 1277 +
iotdb-client/odbc/deps/curl-src/lib/c-hyper.h | 59 +
.../odbc/deps/curl-src/lib/cf-h1-proxy.c | 1119 +
.../odbc/deps/curl-src/lib/cf-h1-proxy.h | 39 +
.../odbc/deps/curl-src/lib/cf-h2-proxy.c | 1580 +
.../odbc/deps/curl-src/lib/cf-h2-proxy.h | 39 +
.../odbc/deps/curl-src/lib/cf-haproxy.c | 251 +
.../odbc/deps/curl-src/lib/cf-haproxy.h | 39 +
.../odbc/deps/curl-src/lib/cf-https-connect.c | 551 +
.../odbc/deps/curl-src/lib/cf-https-connect.h | 58 +
.../odbc/deps/curl-src/lib/cf-socket.c | 2011 ++
.../odbc/deps/curl-src/lib/cf-socket.h | 191 +
.../odbc/deps/curl-src/lib/cfilters.c | 648 +
.../odbc/deps/curl-src/lib/cfilters.h | 539 +
.../odbc/deps/curl-src/lib/config-amigaos.h | 130 +
.../odbc/deps/curl-src/lib/config-dos.h | 139 +
.../odbc/deps/curl-src/lib/config-mac.h | 103 +
.../odbc/deps/curl-src/lib/config-os400.h | 346 +
.../odbc/deps/curl-src/lib/config-plan9.h | 149 +
.../odbc/deps/curl-src/lib/config-riscos.h | 286 +
.../odbc/deps/curl-src/lib/config-win32.h | 642 +
.../odbc/deps/curl-src/lib/config-win32ce.h | 313 +
.../odbc/deps/curl-src/lib/conncache.c | 583 +
.../odbc/deps/curl-src/lib/conncache.h | 122 +
iotdb-client/odbc/deps/curl-src/lib/connect.c | 1448 +
iotdb-client/odbc/deps/curl-src/lib/connect.h | 132 +
.../odbc/deps/curl-src/lib/content_encoding.c | 1047 +
.../odbc/deps/curl-src/lib/content_encoding.h | 39 +
iotdb-client/odbc/deps/curl-src/lib/cookie.c | 1779 ++
iotdb-client/odbc/deps/curl-src/lib/cookie.h | 138 +
.../odbc/deps/curl-src/lib/curl_addrinfo.c | 592 +
.../odbc/deps/curl-src/lib/curl_addrinfo.h | 108 +
.../odbc/deps/curl-src/lib/curl_base64.h | 41 +
.../deps/curl-src/lib/curl_config.h.cmake | 816 +
.../odbc/deps/curl-src/lib/curl_ctype.h | 51 +
.../odbc/deps/curl-src/lib/curl_des.c | 69 +
.../odbc/deps/curl-src/lib/curl_des.h | 40 +
.../odbc/deps/curl-src/lib/curl_endian.c | 84 +
.../odbc/deps/curl-src/lib/curl_endian.h | 36 +
.../odbc/deps/curl-src/lib/curl_fnmatch.c | 390 +
.../odbc/deps/curl-src/lib/curl_fnmatch.h | 46 +
.../odbc/deps/curl-src/lib/curl_get_line.c | 86 +
.../odbc/deps/curl-src/lib/curl_get_line.h | 31 +
.../odbc/deps/curl-src/lib/curl_gethostname.c | 102 +
.../odbc/deps/curl-src/lib/curl_gethostname.h | 33 +
.../odbc/deps/curl-src/lib/curl_gssapi.c | 152 +
.../odbc/deps/curl-src/lib/curl_gssapi.h | 63 +
.../odbc/deps/curl-src/lib/curl_hmac.h | 77 +
.../odbc/deps/curl-src/lib/curl_krb5.h | 52 +
.../odbc/deps/curl-src/lib/curl_ldap.h | 36 +
.../odbc/deps/curl-src/lib/curl_md4.h | 39 +
.../odbc/deps/curl-src/lib/curl_md5.h | 67 +
.../odbc/deps/curl-src/lib/curl_memory.h | 178 +
.../odbc/deps/curl-src/lib/curl_memrchr.c | 64 +
.../odbc/deps/curl-src/lib/curl_memrchr.h | 44 +
.../odbc/deps/curl-src/lib/curl_multibyte.c | 179 +
.../odbc/deps/curl-src/lib/curl_multibyte.h | 91 +
.../odbc/deps/curl-src/lib/curl_ntlm_core.c | 660 +
.../odbc/deps/curl-src/lib/curl_ntlm_core.h | 79 +
.../odbc/deps/curl-src/lib/curl_ntlm_wb.c | 498 +
.../odbc/deps/curl-src/lib/curl_ntlm_wb.h | 45 +
.../odbc/deps/curl-src/lib/curl_path.c | 199 +
.../odbc/deps/curl-src/lib/curl_path.h | 49 +
.../odbc/deps/curl-src/lib/curl_printf.h | 51 +
.../odbc/deps/curl-src/lib/curl_range.c | 96 +
.../odbc/deps/curl-src/lib/curl_range.h | 31 +
.../odbc/deps/curl-src/lib/curl_rtmp.c | 338 +
.../odbc/deps/curl-src/lib/curl_rtmp.h | 35 +
.../odbc/deps/curl-src/lib/curl_sasl.c | 752 +
.../odbc/deps/curl-src/lib/curl_sasl.h | 165 +
.../odbc/deps/curl-src/lib/curl_setup.h | 847 +
.../odbc/deps/curl-src/lib/curl_setup_once.h | 422 +
.../odbc/deps/curl-src/lib/curl_sha256.h | 50 +
.../odbc/deps/curl-src/lib/curl_sspi.c | 239 +
.../odbc/deps/curl-src/lib/curl_sspi.h | 107 +
.../odbc/deps/curl-src/lib/curl_threads.c | 153 +
.../odbc/deps/curl-src/lib/curl_threads.h | 65 +
.../odbc/deps/curl-src/lib/curl_trc.c | 255 +
.../odbc/deps/curl-src/lib/curl_trc.h | 150 +
iotdb-client/odbc/deps/curl-src/lib/curlx.h | 118 +
iotdb-client/odbc/deps/curl-src/lib/dict.c | 320 +
iotdb-client/odbc/deps/curl-src/lib/dict.h | 31 +
iotdb-client/odbc/deps/curl-src/lib/doh.c | 989 +
iotdb-client/odbc/deps/curl-src/lib/doh.h | 128 +
iotdb-client/odbc/deps/curl-src/lib/dynbuf.c | 275 +
iotdb-client/odbc/deps/curl-src/lib/dynbuf.h | 93 +
iotdb-client/odbc/deps/curl-src/lib/dynhds.c | 366 +
iotdb-client/odbc/deps/curl-src/lib/dynhds.h | 174 +
iotdb-client/odbc/deps/curl-src/lib/easy.c | 1361 +
.../odbc/deps/curl-src/lib/easy_lock.h | 102 +
.../odbc/deps/curl-src/lib/easygetopt.c | 98 +
iotdb-client/odbc/deps/curl-src/lib/easyif.h | 41 +
.../odbc/deps/curl-src/lib/easyoptions.c | 378 +
.../odbc/deps/curl-src/lib/easyoptions.h | 37 +
iotdb-client/odbc/deps/curl-src/lib/escape.c | 234 +
iotdb-client/odbc/deps/curl-src/lib/escape.h | 44 +
iotdb-client/odbc/deps/curl-src/lib/file.c | 589 +
iotdb-client/odbc/deps/curl-src/lib/file.h | 42 +
.../odbc/deps/curl-src/lib/fileinfo.c | 46 +
.../odbc/deps/curl-src/lib/fileinfo.h | 40 +
iotdb-client/odbc/deps/curl-src/lib/fopen.c | 112 +
iotdb-client/odbc/deps/curl-src/lib/fopen.h | 30 +
.../odbc/deps/curl-src/lib/formdata.c | 960 +
.../odbc/deps/curl-src/lib/formdata.h | 59 +
iotdb-client/odbc/deps/curl-src/lib/ftp.c | 4446 +++
iotdb-client/odbc/deps/curl-src/lib/ftp.h | 167 +
.../odbc/deps/curl-src/lib/ftplistparser.c | 1044 +
.../odbc/deps/curl-src/lib/ftplistparser.h | 77 +
.../odbc/deps/curl-src/lib/functypes.h | 115 +
iotdb-client/odbc/deps/curl-src/lib/getenv.c | 79 +
iotdb-client/odbc/deps/curl-src/lib/getinfo.c | 625 +
iotdb-client/odbc/deps/curl-src/lib/getinfo.h | 29 +
iotdb-client/odbc/deps/curl-src/lib/gopher.c | 242 +
iotdb-client/odbc/deps/curl-src/lib/gopher.h | 34 +
iotdb-client/odbc/deps/curl-src/lib/hash.c | 370 +
iotdb-client/odbc/deps/curl-src/lib/hash.h | 102 +
iotdb-client/odbc/deps/curl-src/lib/headers.c | 395 +
iotdb-client/odbc/deps/curl-src/lib/headers.h | 55 +
iotdb-client/odbc/deps/curl-src/lib/hmac.c | 173 +
.../odbc/deps/curl-src/lib/hostasyn.c | 123 +
iotdb-client/odbc/deps/curl-src/lib/hostip.c | 1376 +
iotdb-client/odbc/deps/curl-src/lib/hostip.h | 225 +
iotdb-client/odbc/deps/curl-src/lib/hostip4.c | 301 +
iotdb-client/odbc/deps/curl-src/lib/hostip6.c | 158 +
iotdb-client/odbc/deps/curl-src/lib/hostsyn.c | 104 +
iotdb-client/odbc/deps/curl-src/lib/hsts.c | 579 +
iotdb-client/odbc/deps/curl-src/lib/hsts.h | 69 +
iotdb-client/odbc/deps/curl-src/lib/http.c | 4976 ++++
iotdb-client/odbc/deps/curl-src/lib/http.h | 333 +
iotdb-client/odbc/deps/curl-src/lib/http1.c | 346 +
iotdb-client/odbc/deps/curl-src/lib/http1.h | 63 +
iotdb-client/odbc/deps/curl-src/lib/http2.c | 2853 ++
iotdb-client/odbc/deps/curl-src/lib/http2.h | 77 +
.../odbc/deps/curl-src/lib/http_aws_sigv4.c | 799 +
.../odbc/deps/curl-src/lib/http_aws_sigv4.h | 31 +
.../odbc/deps/curl-src/lib/http_chunks.c | 316 +
.../odbc/deps/curl-src/lib/http_chunks.h | 100 +
.../odbc/deps/curl-src/lib/http_digest.c | 185 +
.../odbc/deps/curl-src/lib/http_digest.h | 44 +
.../odbc/deps/curl-src/lib/http_negotiate.c | 224 +
.../odbc/deps/curl-src/lib/http_negotiate.h | 43 +
.../odbc/deps/curl-src/lib/http_ntlm.c | 275 +
.../odbc/deps/curl-src/lib/http_ntlm.h | 44 +
.../odbc/deps/curl-src/lib/http_proxy.c | 336 +
.../odbc/deps/curl-src/lib/http_proxy.h | 61 +
iotdb-client/odbc/deps/curl-src/lib/idn.c | 287 +
iotdb-client/odbc/deps/curl-src/lib/idn.h | 44 +
iotdb-client/odbc/deps/curl-src/lib/if2ip.c | 260 +
iotdb-client/odbc/deps/curl-src/lib/if2ip.h | 92 +
iotdb-client/odbc/deps/curl-src/lib/imap.c | 2116 ++
iotdb-client/odbc/deps/curl-src/lib/imap.h | 101 +
.../odbc/deps/curl-src/lib/inet_ntop.c | 205 +
.../odbc/deps/curl-src/lib/inet_ntop.h | 39 +
.../odbc/deps/curl-src/lib/inet_pton.c | 242 +
.../odbc/deps/curl-src/lib/inet_pton.h | 41 +
iotdb-client/odbc/deps/curl-src/lib/krb5.c | 902 +
iotdb-client/odbc/deps/curl-src/lib/ldap.c | 1121 +
.../odbc/deps/curl-src/lib/libcurl.plist.in | 35 +
.../odbc/deps/curl-src/lib/libcurl.rc | 65 +
.../odbc/deps/curl-src/lib/libcurl.vers.in | 13 +
iotdb-client/odbc/deps/curl-src/lib/llist.c | 146 +
iotdb-client/odbc/deps/curl-src/lib/llist.h | 52 +
iotdb-client/odbc/deps/curl-src/lib/macos.c | 55 +
iotdb-client/odbc/deps/curl-src/lib/macos.h | 39 +
iotdb-client/odbc/deps/curl-src/lib/md4.c | 527 +
iotdb-client/odbc/deps/curl-src/lib/md5.c | 656 +
.../odbc/deps/curl-src/lib/memdebug.c | 482 +
.../odbc/deps/curl-src/lib/memdebug.h | 202 +
iotdb-client/odbc/deps/curl-src/lib/mime.c | 2026 ++
iotdb-client/odbc/deps/curl-src/lib/mime.h | 174 +
iotdb-client/odbc/deps/curl-src/lib/mprintf.c | 1177 +
iotdb-client/odbc/deps/curl-src/lib/mqtt.c | 854 +
iotdb-client/odbc/deps/curl-src/lib/mqtt.h | 62 +
iotdb-client/odbc/deps/curl-src/lib/multi.c | 3796 +++
.../odbc/deps/curl-src/lib/multihandle.h | 180 +
iotdb-client/odbc/deps/curl-src/lib/multiif.h | 97 +
iotdb-client/odbc/deps/curl-src/lib/netrc.c | 349 +
iotdb-client/odbc/deps/curl-src/lib/netrc.h | 43 +
.../odbc/deps/curl-src/lib/nonblock.c | 84 +
.../odbc/deps/curl-src/lib/nonblock.h | 32 +
iotdb-client/odbc/deps/curl-src/lib/noproxy.c | 266 +
iotdb-client/odbc/deps/curl-src/lib/noproxy.h | 45 +
.../odbc/deps/curl-src/lib/openldap.c | 1212 +
.../odbc/deps/curl-src/lib/optiontable.pl | 152 +
.../odbc/deps/curl-src/lib/parsedate.c | 644 +
.../odbc/deps/curl-src/lib/parsedate.h | 38 +
.../odbc/deps/curl-src/lib/pingpong.c | 501 +
.../odbc/deps/curl-src/lib/pingpong.h | 164 +
iotdb-client/odbc/deps/curl-src/lib/pop3.c | 1587 +
iotdb-client/odbc/deps/curl-src/lib/pop3.h | 97 +
.../odbc/deps/curl-src/lib/progress.c | 631 +
.../odbc/deps/curl-src/lib/progress.h | 76 +
iotdb-client/odbc/deps/curl-src/lib/psl.c | 113 +
iotdb-client/odbc/deps/curl-src/lib/psl.h | 49 +
iotdb-client/odbc/deps/curl-src/lib/rand.c | 289 +
iotdb-client/odbc/deps/curl-src/lib/rand.h | 50 +
iotdb-client/odbc/deps/curl-src/lib/rename.c | 73 +
iotdb-client/odbc/deps/curl-src/lib/rename.h | 29 +
iotdb-client/odbc/deps/curl-src/lib/rtsp.c | 902 +
iotdb-client/odbc/deps/curl-src/lib/rtsp.h | 71 +
iotdb-client/odbc/deps/curl-src/lib/select.c | 403 +
iotdb-client/odbc/deps/curl-src/lib/select.h | 114 +
iotdb-client/odbc/deps/curl-src/lib/sendf.c | 618 +
iotdb-client/odbc/deps/curl-src/lib/sendf.h | 110 +
iotdb-client/odbc/deps/curl-src/lib/setopt.c | 3205 ++
iotdb-client/odbc/deps/curl-src/lib/setopt.h | 32 +
.../odbc/deps/curl-src/lib/setup-os400.h | 144 +
.../odbc/deps/curl-src/lib/setup-vms.h | 444 +
.../odbc/deps/curl-src/lib/setup-win32.h | 127 +
iotdb-client/odbc/deps/curl-src/lib/sha256.c | 545 +
iotdb-client/odbc/deps/curl-src/lib/share.c | 290 +
iotdb-client/odbc/deps/curl-src/lib/share.h | 76 +
iotdb-client/odbc/deps/curl-src/lib/sigpipe.h | 80 +
iotdb-client/odbc/deps/curl-src/lib/slist.c | 146 +
iotdb-client/odbc/deps/curl-src/lib/slist.h | 41 +
iotdb-client/odbc/deps/curl-src/lib/smb.c | 1210 +
iotdb-client/odbc/deps/curl-src/lib/smb.h | 60 +
iotdb-client/odbc/deps/curl-src/lib/smtp.c | 1929 ++
iotdb-client/odbc/deps/curl-src/lib/smtp.h | 100 +
.../odbc/deps/curl-src/lib/sockaddr.h | 44 +
.../odbc/deps/curl-src/lib/socketpair.c | 193 +
.../odbc/deps/curl-src/lib/socketpair.h | 37 +
iotdb-client/odbc/deps/curl-src/lib/socks.c | 1253 +
iotdb-client/odbc/deps/curl-src/lib/socks.h | 61 +
.../odbc/deps/curl-src/lib/socks_gssapi.c | 536 +
.../odbc/deps/curl-src/lib/socks_sspi.c | 614 +
.../odbc/deps/curl-src/lib/speedcheck.c | 79 +
.../odbc/deps/curl-src/lib/speedcheck.h | 35 +
iotdb-client/odbc/deps/curl-src/lib/splay.c | 278 +
iotdb-client/odbc/deps/curl-src/lib/splay.h | 58 +
iotdb-client/odbc/deps/curl-src/lib/strcase.c | 204 +
iotdb-client/odbc/deps/curl-src/lib/strcase.h | 54 +
iotdb-client/odbc/deps/curl-src/lib/strdup.c | 123 +
iotdb-client/odbc/deps/curl-src/lib/strdup.h | 37 +
.../odbc/deps/curl-src/lib/strerror.c | 1112 +
.../odbc/deps/curl-src/lib/strerror.h | 39 +
iotdb-client/odbc/deps/curl-src/lib/strtok.c | 68 +
iotdb-client/odbc/deps/curl-src/lib/strtok.h | 36 +
.../odbc/deps/curl-src/lib/strtoofft.c | 245 +
.../odbc/deps/curl-src/lib/strtoofft.h | 54 +
.../odbc/deps/curl-src/lib/system_win32.c | 241 +
.../odbc/deps/curl-src/lib/system_win32.h | 49 +
iotdb-client/odbc/deps/curl-src/lib/telnet.c | 1643 +
iotdb-client/odbc/deps/curl-src/lib/telnet.h | 30 +
iotdb-client/odbc/deps/curl-src/lib/tftp.c | 1415 +
iotdb-client/odbc/deps/curl-src/lib/tftp.h | 30 +
.../odbc/deps/curl-src/lib/timediff.c | 88 +
.../odbc/deps/curl-src/lib/timediff.h | 52 +
iotdb-client/odbc/deps/curl-src/lib/timeval.c | 238 +
iotdb-client/odbc/deps/curl-src/lib/timeval.h | 62 +
.../odbc/deps/curl-src/lib/transfer.c | 1950 ++
.../odbc/deps/curl-src/lib/transfer.h | 73 +
iotdb-client/odbc/deps/curl-src/lib/url.c | 4083 +++
iotdb-client/odbc/deps/curl-src/lib/url.h | 76 +
.../odbc/deps/curl-src/lib/urlapi-int.h | 39 +
iotdb-client/odbc/deps/curl-src/lib/urlapi.c | 1958 ++
iotdb-client/odbc/deps/curl-src/lib/urldata.h | 2024 ++
.../odbc/deps/curl-src/lib/vauth/cleartext.c | 138 +
.../odbc/deps/curl-src/lib/vauth/cram.c | 97 +
.../odbc/deps/curl-src/lib/vauth/digest.c | 995 +
.../odbc/deps/curl-src/lib/vauth/digest.h | 40 +
.../deps/curl-src/lib/vauth/digest_sspi.c | 668 +
.../odbc/deps/curl-src/lib/vauth/gsasl.c | 127 +
.../deps/curl-src/lib/vauth/krb5_gssapi.c | 323 +
.../odbc/deps/curl-src/lib/vauth/krb5_sspi.c | 474 +
.../odbc/deps/curl-src/lib/vauth/ntlm.c | 780 +
.../odbc/deps/curl-src/lib/vauth/ntlm.h | 143 +
.../odbc/deps/curl-src/lib/vauth/ntlm_sspi.c | 372 +
.../odbc/deps/curl-src/lib/vauth/oauth2.c | 108 +
.../deps/curl-src/lib/vauth/spnego_gssapi.c | 281 +
.../deps/curl-src/lib/vauth/spnego_sspi.c | 364 +
.../odbc/deps/curl-src/lib/vauth/vauth.c | 163 +
.../odbc/deps/curl-src/lib/vauth/vauth.h | 238 +
iotdb-client/odbc/deps/curl-src/lib/version.c | 672 +
.../odbc/deps/curl-src/lib/version_win32.c | 319 +
.../odbc/deps/curl-src/lib/version_win32.h | 56 +
.../odbc/deps/curl-src/lib/vquic/curl_msh3.c | 1087 +
.../odbc/deps/curl-src/lib/vquic/curl_msh3.h | 46 +
.../deps/curl-src/lib/vquic/curl_ngtcp2.c | 2757 ++
.../deps/curl-src/lib/vquic/curl_ngtcp2.h | 61 +
.../deps/curl-src/lib/vquic/curl_quiche.c | 1716 ++
.../deps/curl-src/lib/vquic/curl_quiche.h | 50 +
.../odbc/deps/curl-src/lib/vquic/vquic.c | 656 +
.../odbc/deps/curl-src/lib/vquic/vquic.h | 64 +
.../odbc/deps/curl-src/lib/vquic/vquic_int.h | 85 +
.../odbc/deps/curl-src/lib/vssh/libssh.c | 2962 ++
.../odbc/deps/curl-src/lib/vssh/libssh2.c | 3828 +++
.../odbc/deps/curl-src/lib/vssh/ssh.h | 272 +
.../odbc/deps/curl-src/lib/vssh/wolfssh.c | 1174 +
.../odbc/deps/curl-src/lib/vtls/bearssl.c | 1230 +
.../odbc/deps/curl-src/lib/vtls/bearssl.h | 34 +
.../odbc/deps/curl-src/lib/vtls/gtls.c | 1682 ++
.../odbc/deps/curl-src/lib/vtls/gtls.h | 75 +
.../odbc/deps/curl-src/lib/vtls/hostcheck.c | 135 +
.../odbc/deps/curl-src/lib/vtls/hostcheck.h | 33 +
.../odbc/deps/curl-src/lib/vtls/keylog.c | 159 +
.../odbc/deps/curl-src/lib/vtls/keylog.h | 58 +
.../odbc/deps/curl-src/lib/vtls/mbedtls.c | 1294 +
.../odbc/deps/curl-src/lib/vtls/mbedtls.h | 34 +
.../curl-src/lib/vtls/mbedtls_threadlock.c | 134 +
.../curl-src/lib/vtls/mbedtls_threadlock.h | 50 +
.../odbc/deps/curl-src/lib/vtls/openssl.c | 4866 +++
.../odbc/deps/curl-src/lib/vtls/openssl.h | 69 +
.../odbc/deps/curl-src/lib/vtls/rustls.c | 697 +
.../odbc/deps/curl-src/lib/vtls/rustls.h | 35 +
.../odbc/deps/curl-src/lib/vtls/schannel.c | 2797 ++
.../odbc/deps/curl-src/lib/vtls/schannel.h | 86 +
.../deps/curl-src/lib/vtls/schannel_int.h | 153 +
.../deps/curl-src/lib/vtls/schannel_verify.c | 771 +
.../odbc/deps/curl-src/lib/vtls/sectransp.c | 3507 +++
.../odbc/deps/curl-src/lib/vtls/sectransp.h | 34 +
.../odbc/deps/curl-src/lib/vtls/vtls.c | 2048 ++
.../odbc/deps/curl-src/lib/vtls/vtls.h | 216 +
.../odbc/deps/curl-src/lib/vtls/vtls_int.h | 229 +
.../odbc/deps/curl-src/lib/vtls/wolfssl.c | 1418 +
.../odbc/deps/curl-src/lib/vtls/wolfssl.h | 33 +
.../odbc/deps/curl-src/lib/vtls/x509asn1.c | 1438 +
.../odbc/deps/curl-src/lib/vtls/x509asn1.h | 80 +
.../odbc/deps/curl-src/lib/warnless.c | 385 +
.../odbc/deps/curl-src/lib/warnless.h | 99 +
iotdb-client/odbc/deps/curl-src/lib/ws.c | 1132 +
iotdb-client/odbc/deps/curl-src/lib/ws.h | 89 +
iotdb-client/odbc/deps/curl-src/libcurl.pc.in | 41 +
iotdb-client/odbc/deps/json-src/LICENSE.MIT | 21 +
.../json-src/single_include/nlohmann/json.hpp | 24765 ++++++++++++++++
iotdb-client/odbc/driver.def | 82 +
.../odbc/examples/cpp-example/README.md | 103 +
.../odbc/examples/cpp-example/TableTest.cpp | 503 +
.../odbc/examples/cpp-example/TreeTest.cpp | 476 +
.../odbc/examples/python-example/README.md | 84 +
.../odbc/examples/python-example/TableTest.py | 165 +
.../odbc/examples/python-example/TreeTest.py | 147 +
.../examples/python-example/requirements.txt | 17 +
iotdb-client/odbc/exports.map | 22 +
iotdb-client/odbc/install.bat | 28 +
.../odbc/licenses/GCC-Runtime-Exception.txt | 72 +
iotdb-client/odbc/licenses/GPL-3.0.txt | 674 +
iotdb-client/odbc/pom.xml | 111 +
iotdb-client/odbc/src/ConnectionHandle.cpp | 259 +
iotdb-client/odbc/src/ConnectionHandle.h | 72 +
iotdb-client/odbc/src/ConnectionString.h | 77 +
iotdb-client/odbc/src/CopyField.cpp | 468 +
iotdb-client/odbc/src/CopyField.h | 39 +
iotdb-client/odbc/src/DiagnosticManager.cpp | 63 +
iotdb-client/odbc/src/DiagnosticManager.h | 58 +
iotdb-client/odbc/src/DriverConfig.h.in | 28 +
iotdb-client/odbc/src/EnvironmentHandle.cpp | 25 +
iotdb-client/odbc/src/EnvironmentHandle.h | 37 +
iotdb-client/odbc/src/Log.cpp | 341 +
iotdb-client/odbc/src/Log.h | 51 +
iotdb-client/odbc/src/ODBCField.cpp | 1070 +
iotdb-client/odbc/src/ODBCField.h | 118 +
iotdb-client/odbc/src/ODBCHandle.cpp | 25 +
iotdb-client/odbc/src/ODBCHandle.h | 50 +
iotdb-client/odbc/src/ODBCRestResultSet.cpp | 249 +
iotdb-client/odbc/src/ODBCRestResultSet.h | 41 +
iotdb-client/odbc/src/ODBCResultSet.cpp | 402 +
iotdb-client/odbc/src/ODBCResultSet.h | 169 +
.../odbc/src/ODBCSessionResultSet.cpp | 389 +
iotdb-client/odbc/src/ODBCSessionResultSet.h | 48 +
iotdb-client/odbc/src/Pch.h | 69 +
iotdb-client/odbc/src/StatementHandle.cpp | 111 +
iotdb-client/odbc/src/StatementHandle.h | 142 +
iotdb-client/odbc/src/driver.cpp | 5479 ++++
iotdb-client/odbc/src/driver.h | 177 +
iotdb-client/odbc/src/install_driver.cpp | 170 +
iotdb-client/odbc/src/rest_api_client.cpp | 388 +
iotdb-client/odbc/src/rest_api_client.h | 79 +
iotdb-client/odbc/src/session_api_client.cpp | 263 +
iotdb-client/odbc/src/session_api_client.h | 41 +
iotdb-client/odbc/src/setup/resource.h | 45 +
iotdb-client/odbc/src/setup/setup.rc | 78 +
iotdb-client/odbc/src/setup/setup_dialog.cpp | 465 +
iotdb-client/odbc/src/setup/setup_dialog.h | 54 +
iotdb-client/odbc/test/CMakeLists.txt | 41 +
.../odbc/test/check-windows-dependencies.ps1 | 35 +
iotdb-client/odbc/test/manager.cpp | 192 +
iotdb-client/odbc/test/run_e2e.py | 156 +
iotdb-client/odbc/test/unit.cpp | 120 +
iotdb-client/odbc/uninstall.bat | 19 +
iotdb-client/pom.xml | 6 +
pom.xml | 3 +
467 files changed, 208182 insertions(+), 45 deletions(-)
create mode 100644 .github/scripts/native-linux-env.sh
create mode 100644 .github/scripts/package-odbc-manylinux228.sh
create mode 100644 .github/workflows/odbc-package.yml
create mode 100644 iotdb-client/odbc/.gitignore
create mode 100644 iotdb-client/odbc/CMakeLists.txt
create mode 100644 iotdb-client/odbc/README.md
create mode 100644 iotdb-client/odbc/SOURCE.md
create mode 100644 iotdb-client/odbc/VALIDATION.md
create mode 100644 iotdb-client/odbc/cmake/CheckLinuxPackage.cmake
create mode 100644 iotdb-client/odbc/conf/odbc.ini
create mode 100644 iotdb-client/odbc/conf/odbcinst.ini
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/CMakeConfigurableFile.in
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/CurlSymbolHiding.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/CurlTests.c
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/FindBearSSL.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/FindBrotli.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/FindCARES.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/FindGSS.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/FindLibPSL.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/FindLibSSH2.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/FindMSH3.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/FindMbedTLS.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/FindNGHTTP2.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/FindNGHTTP3.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/FindNGTCP2.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/FindQUICHE.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/FindWolfSSL.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/FindZstd.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/Macros.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/OtherTests.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/PickyWarnings.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/Platforms/WindowsCache.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/Utilities.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/cmake_uninstall.cmake.in
create mode 100644 iotdb-client/odbc/deps/curl-src/CMake/curl-config.cmake.in
create mode 100644 iotdb-client/odbc/deps/curl-src/CMakeLists.txt
create mode 100644 iotdb-client/odbc/deps/curl-src/COPYING
create mode 100644 iotdb-client/odbc/deps/curl-src/curl-config.in
create mode 100644 iotdb-client/odbc/deps/curl-src/include/Makefile.am
create mode 100644 iotdb-client/odbc/deps/curl-src/include/README.md
create mode 100644 iotdb-client/odbc/deps/curl-src/include/curl/.gitignore
create mode 100644 iotdb-client/odbc/deps/curl-src/include/curl/Makefile.am
create mode 100644 iotdb-client/odbc/deps/curl-src/include/curl/curl.h
create mode 100644 iotdb-client/odbc/deps/curl-src/include/curl/curlver.h
create mode 100644 iotdb-client/odbc/deps/curl-src/include/curl/easy.h
create mode 100644 iotdb-client/odbc/deps/curl-src/include/curl/header.h
create mode 100644 iotdb-client/odbc/deps/curl-src/include/curl/mprintf.h
create mode 100644 iotdb-client/odbc/deps/curl-src/include/curl/multi.h
create mode 100644 iotdb-client/odbc/deps/curl-src/include/curl/options.h
create mode 100644 iotdb-client/odbc/deps/curl-src/include/curl/stdcheaders.h
create mode 100644 iotdb-client/odbc/deps/curl-src/include/curl/system.h
create mode 100644 iotdb-client/odbc/deps/curl-src/include/curl/typecheck-gcc.h
create mode 100644 iotdb-client/odbc/deps/curl-src/include/curl/urlapi.h
create mode 100644 iotdb-client/odbc/deps/curl-src/include/curl/websockets.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/.checksrc
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/.gitattributes
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/.gitignore
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/CMakeLists.txt
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/Makefile.am
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/Makefile.inc
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/Makefile.mk
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/Makefile.soname
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/altsvc.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/altsvc.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/amigaos.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/amigaos.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/arpa_telnet.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/asyn-ares.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/asyn-thread.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/asyn.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/base64.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/bufq.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/bufq.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/bufref.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/bufref.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/c-hyper.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/c-hyper.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/cf-h1-proxy.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/cf-h1-proxy.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/cf-h2-proxy.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/cf-h2-proxy.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/cf-haproxy.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/cf-haproxy.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/cf-https-connect.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/cf-https-connect.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/cf-socket.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/cf-socket.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/cfilters.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/cfilters.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/config-amigaos.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/config-dos.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/config-mac.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/config-os400.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/config-plan9.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/config-riscos.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/config-win32.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/config-win32ce.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/conncache.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/conncache.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/connect.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/connect.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/content_encoding.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/content_encoding.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/cookie.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/cookie.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_addrinfo.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_addrinfo.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_base64.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_config.h.cmake
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_ctype.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_des.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_des.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_endian.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_endian.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_fnmatch.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_fnmatch.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_get_line.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_get_line.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_gethostname.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_gethostname.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_gssapi.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_gssapi.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_hmac.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_krb5.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_ldap.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_md4.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_md5.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_memory.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_memrchr.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_memrchr.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_multibyte.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_multibyte.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_ntlm_core.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_ntlm_core.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_ntlm_wb.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_ntlm_wb.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_path.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_path.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_printf.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_range.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_range.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_rtmp.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_rtmp.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_sasl.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_sasl.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_setup.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_setup_once.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_sha256.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_sspi.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_sspi.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_threads.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_threads.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_trc.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curl_trc.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/curlx.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/dict.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/dict.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/doh.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/doh.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/dynbuf.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/dynbuf.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/dynhds.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/dynhds.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/easy.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/easy_lock.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/easygetopt.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/easyif.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/easyoptions.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/easyoptions.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/escape.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/escape.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/file.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/file.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/fileinfo.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/fileinfo.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/fopen.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/fopen.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/formdata.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/formdata.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/ftp.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/ftp.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/ftplistparser.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/ftplistparser.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/functypes.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/getenv.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/getinfo.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/getinfo.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/gopher.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/gopher.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/hash.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/hash.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/headers.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/headers.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/hmac.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/hostasyn.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/hostip.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/hostip.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/hostip4.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/hostip6.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/hostsyn.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/hsts.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/hsts.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/http.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/http.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/http1.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/http1.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/http2.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/http2.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/http_aws_sigv4.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/http_aws_sigv4.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/http_chunks.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/http_chunks.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/http_digest.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/http_digest.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/http_negotiate.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/http_negotiate.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/http_ntlm.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/http_ntlm.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/http_proxy.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/http_proxy.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/idn.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/idn.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/if2ip.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/if2ip.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/imap.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/imap.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/inet_ntop.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/inet_ntop.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/inet_pton.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/inet_pton.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/krb5.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/ldap.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/libcurl.plist.in
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/libcurl.rc
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/libcurl.vers.in
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/llist.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/llist.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/macos.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/macos.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/md4.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/md5.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/memdebug.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/memdebug.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/mime.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/mime.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/mprintf.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/mqtt.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/mqtt.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/multi.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/multihandle.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/multiif.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/netrc.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/netrc.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/nonblock.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/nonblock.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/noproxy.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/noproxy.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/openldap.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/optiontable.pl
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/parsedate.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/parsedate.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/pingpong.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/pingpong.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/pop3.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/pop3.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/progress.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/progress.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/psl.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/psl.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/rand.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/rand.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/rename.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/rename.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/rtsp.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/rtsp.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/select.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/select.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/sendf.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/sendf.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/setopt.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/setopt.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/setup-os400.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/setup-vms.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/setup-win32.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/sha256.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/share.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/share.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/sigpipe.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/slist.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/slist.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/smb.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/smb.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/smtp.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/smtp.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/sockaddr.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/socketpair.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/socketpair.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/socks.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/socks.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/socks_gssapi.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/socks_sspi.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/speedcheck.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/speedcheck.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/splay.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/splay.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/strcase.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/strcase.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/strdup.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/strdup.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/strerror.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/strerror.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/strtok.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/strtok.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/strtoofft.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/strtoofft.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/system_win32.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/system_win32.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/telnet.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/telnet.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/tftp.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/tftp.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/timediff.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/timediff.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/timeval.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/timeval.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/transfer.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/transfer.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/url.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/url.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/urlapi-int.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/urlapi.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/urldata.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vauth/cleartext.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vauth/cram.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vauth/digest.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vauth/digest.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vauth/digest_sspi.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vauth/gsasl.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vauth/krb5_gssapi.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vauth/krb5_sspi.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vauth/ntlm.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vauth/ntlm.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vauth/ntlm_sspi.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vauth/oauth2.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vauth/spnego_gssapi.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vauth/spnego_sspi.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vauth/vauth.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vauth/vauth.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/version.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/version_win32.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/version_win32.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vquic/curl_msh3.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vquic/curl_msh3.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vquic/curl_ngtcp2.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vquic/curl_ngtcp2.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vquic/curl_quiche.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vquic/curl_quiche.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vquic/vquic.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vquic/vquic.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vquic/vquic_int.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vssh/libssh.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vssh/libssh2.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vssh/ssh.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vssh/wolfssh.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/bearssl.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/bearssl.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/gtls.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/gtls.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/hostcheck.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/hostcheck.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/keylog.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/keylog.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/mbedtls.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/mbedtls.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/mbedtls_threadlock.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/mbedtls_threadlock.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/openssl.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/openssl.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/rustls.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/rustls.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/schannel.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/schannel.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/schannel_int.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/schannel_verify.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/sectransp.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/sectransp.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/vtls.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/vtls.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/vtls_int.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/wolfssl.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/wolfssl.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/x509asn1.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/vtls/x509asn1.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/warnless.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/warnless.h
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/ws.c
create mode 100644 iotdb-client/odbc/deps/curl-src/lib/ws.h
create mode 100644 iotdb-client/odbc/deps/curl-src/libcurl.pc.in
create mode 100644 iotdb-client/odbc/deps/json-src/LICENSE.MIT
create mode 100644 iotdb-client/odbc/deps/json-src/single_include/nlohmann/json.hpp
create mode 100644 iotdb-client/odbc/driver.def
create mode 100644 iotdb-client/odbc/examples/cpp-example/README.md
create mode 100644 iotdb-client/odbc/examples/cpp-example/TableTest.cpp
create mode 100644 iotdb-client/odbc/examples/cpp-example/TreeTest.cpp
create mode 100644 iotdb-client/odbc/examples/python-example/README.md
create mode 100644 iotdb-client/odbc/examples/python-example/TableTest.py
create mode 100644 iotdb-client/odbc/examples/python-example/TreeTest.py
create mode 100644 iotdb-client/odbc/examples/python-example/requirements.txt
create mode 100644 iotdb-client/odbc/exports.map
create mode 100644 iotdb-client/odbc/install.bat
create mode 100644 iotdb-client/odbc/licenses/GCC-Runtime-Exception.txt
create mode 100644 iotdb-client/odbc/licenses/GPL-3.0.txt
create mode 100644 iotdb-client/odbc/pom.xml
create mode 100644 iotdb-client/odbc/src/ConnectionHandle.cpp
create mode 100644 iotdb-client/odbc/src/ConnectionHandle.h
create mode 100644 iotdb-client/odbc/src/ConnectionString.h
create mode 100644 iotdb-client/odbc/src/CopyField.cpp
create mode 100644 iotdb-client/odbc/src/CopyField.h
create mode 100644 iotdb-client/odbc/src/DiagnosticManager.cpp
create mode 100644 iotdb-client/odbc/src/DiagnosticManager.h
create mode 100644 iotdb-client/odbc/src/DriverConfig.h.in
create mode 100644 iotdb-client/odbc/src/EnvironmentHandle.cpp
create mode 100644 iotdb-client/odbc/src/EnvironmentHandle.h
create mode 100644 iotdb-client/odbc/src/Log.cpp
create mode 100644 iotdb-client/odbc/src/Log.h
create mode 100644 iotdb-client/odbc/src/ODBCField.cpp
create mode 100644 iotdb-client/odbc/src/ODBCField.h
create mode 100644 iotdb-client/odbc/src/ODBCHandle.cpp
create mode 100644 iotdb-client/odbc/src/ODBCHandle.h
create mode 100644 iotdb-client/odbc/src/ODBCRestResultSet.cpp
create mode 100644 iotdb-client/odbc/src/ODBCRestResultSet.h
create mode 100644 iotdb-client/odbc/src/ODBCResultSet.cpp
create mode 100644 iotdb-client/odbc/src/ODBCResultSet.h
create mode 100644 iotdb-client/odbc/src/ODBCSessionResultSet.cpp
create mode 100644 iotdb-client/odbc/src/ODBCSessionResultSet.h
create mode 100644 iotdb-client/odbc/src/Pch.h
create mode 100644 iotdb-client/odbc/src/StatementHandle.cpp
create mode 100644 iotdb-client/odbc/src/StatementHandle.h
create mode 100644 iotdb-client/odbc/src/driver.cpp
create mode 100644 iotdb-client/odbc/src/driver.h
create mode 100644 iotdb-client/odbc/src/install_driver.cpp
create mode 100644 iotdb-client/odbc/src/rest_api_client.cpp
create mode 100644 iotdb-client/odbc/src/rest_api_client.h
create mode 100644 iotdb-client/odbc/src/session_api_client.cpp
create mode 100644 iotdb-client/odbc/src/session_api_client.h
create mode 100644 iotdb-client/odbc/src/setup/resource.h
create mode 100644 iotdb-client/odbc/src/setup/setup.rc
create mode 100644 iotdb-client/odbc/src/setup/setup_dialog.cpp
create mode 100644 iotdb-client/odbc/src/setup/setup_dialog.h
create mode 100644 iotdb-client/odbc/test/CMakeLists.txt
create mode 100644 iotdb-client/odbc/test/check-windows-dependencies.ps1
create mode 100644 iotdb-client/odbc/test/manager.cpp
create mode 100644 iotdb-client/odbc/test/run_e2e.py
create mode 100644 iotdb-client/odbc/test/unit.cpp
create mode 100644 iotdb-client/odbc/uninstall.bat
diff --git a/.github/scripts/native-linux-env.sh b/.github/scripts/native-linux-env.sh
new file mode 100644
index 0000000000000..74493cd92d4a1
--- /dev/null
+++ b/.github/scripts/native-linux-env.sh
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# Shared Linux release baseline for the C++ SDK and ODBC driver.
+NATIVE_GLIBC_BASELINE=2.28
+NATIVE_GCC_MIN_MAJOR=14
+NATIVE_LINUX_IMAGE="quay.io/pypa/manylinux_2_28_$(uname -m)"
diff --git a/.github/scripts/package-client-cpp-manylinux228.sh b/.github/scripts/package-client-cpp-manylinux228.sh
index 6bfef0aa415b6..a5506854f7ac6 100644
--- a/.github/scripts/package-client-cpp-manylinux228.sh
+++ b/.github/scripts/package-client-cpp-manylinux228.sh
@@ -16,6 +16,7 @@
#
# Build client-cpp in manylinux_2_28 and verify max required GLIBC symbol <= 2.28.
set -euxo pipefail
+source "$(dirname "${BASH_SOURCE[0]}")/native-linux-env.sh"
MACHINE=$(uname -m)
case "${MACHINE}" in
@@ -64,7 +65,7 @@ export JAVA_HOME
gcc --version
c++ --version
gcc_major=$(gcc -dumpversion | cut -d. -f1)
-if (( gcc_major < 14 )); then
+if (( gcc_major < NATIVE_GCC_MIN_MAJOR )); then
echo "ERROR: GCC >= 14 is required; got $(gcc -dumpversion)"
exit 1
fi
@@ -78,9 +79,9 @@ java -version
# modules (IPC::Cmd, Data::Dumper) that are not on the minimal image - install
# them even when perl itself is already present.
if command -v dnf >/dev/null 2>&1; then
- dnf install -y perl perl-IPC-Cmd perl-Data-Dumper
+ dnf install -y perl perl-IPC-Cmd perl-Data-Dumper perl-Time-Piece
else
- yum install -y perl perl-IPC-Cmd perl-Data-Dumper
+ yum install -y perl perl-IPC-Cmd perl-Data-Dumper perl-Time-Piece
fi
cd "${GITHUB_WORKSPACE:?GITHUB_WORKSPACE is not set}"
@@ -106,8 +107,9 @@ if [[ -z "${max_glibc}" ]]; then
exit 1
fi
-if awk -v max="${max_glibc}" "BEGIN { exit !(max > 2.28) }"; then
- echo "ERROR: libiotdb_session.so requires glibc > 2.28 (max=${max_glibc})"
+highest_glibc=$(printf '%s\n' "${max_glibc}" "${NATIVE_GLIBC_BASELINE}" | sort -V | tail -1)
+if [[ "${highest_glibc}" != "${NATIVE_GLIBC_BASELINE}" ]]; then
+ echo "ERROR: libiotdb_session.so requires glibc > ${NATIVE_GLIBC_BASELINE} (max=${max_glibc})"
exit 1
fi
diff --git a/.github/scripts/package-odbc-manylinux228.sh b/.github/scripts/package-odbc-manylinux228.sh
new file mode 100644
index 0000000000000..3a458f1a9407c
--- /dev/null
+++ b/.github/scripts/package-odbc-manylinux228.sh
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+set -euo pipefail
+source "$(dirname "${BASH_SOURCE[0]}")/native-linux-env.sh"
+if (( $(gcc -dumpversion | cut -d. -f1) < NATIVE_GCC_MIN_MAJOR )); then
+ echo "GCC ${NATIVE_GCC_MIN_MAJOR}+ is required" >&2
+ exit 1
+fi
+dnf install -y unixODBC-devel perl-IPC-Cmd perl-Data-Dumper perl-Time-Piece
+odbc_build="${ODBC_BUILD_DIR:-iotdb-client/odbc/target/build}"
+cmake -S iotdb-client/odbc -B "${odbc_build}" \
+ -DCMAKE_BUILD_TYPE=Release -DCMAKE_SKIP_RPATH=ON \
+ -DODBC_PACKAGE_VERSION="${ODBC_PACKAGE_VERSION:-$(sed -n 's:.*\([^<]*\).*:\1:p' iotdb-client/pom.xml | head -1)}" \
+ -DODBC_PACKAGE_CLASSIFIER="linux-x86_64-glibc${NATIVE_GLIBC_BASELINE}"
+cmake --build "${odbc_build}" --parallel "${CMAKE_BUILD_PARALLEL_LEVEL:-4}"
+ctest --test-dir "${odbc_build}" --output-on-failure
+cmake -DDRIVER="${odbc_build}/libapache_iotdb_odbc.so" \
+ -DGLIBC_BASELINE="${NATIVE_GLIBC_BASELINE}" -P iotdb-client/odbc/cmake/CheckLinuxPackage.cmake
+(cd "${odbc_build}" && cpack)
diff --git a/.github/workflows/client-cpp-package.yml b/.github/workflows/client-cpp-package.yml
index 70f2bffdddda6..3f04c9c97eecc 100644
--- a/.github/workflows/client-cpp-package.yml
+++ b/.github/workflows/client-cpp-package.yml
@@ -64,7 +64,7 @@ jobs:
cpp=false
while IFS= read -r file; do
case "$file" in
- iotdb-client/client-cpp/*|iotdb-client/pom.xml|iotdb-protocol/thrift-datanode/src/main/thrift/client.thrift|iotdb-protocol/thrift-commons/src/main/thrift/common.thrift|.github/workflows/client-cpp-package.yml|.github/scripts/package-client-cpp-*.sh)
+ iotdb-client/client-cpp/*|iotdb-client/pom.xml|iotdb-protocol/thrift-datanode/src/main/thrift/client.thrift|iotdb-protocol/thrift-commons/src/main/thrift/common.thrift|.github/workflows/client-cpp-package.yml|.github/scripts/package-client-cpp-*.sh|.github/scripts/native-linux-env.sh)
cpp=true
break
;;
@@ -189,12 +189,13 @@ jobs:
run: |
set -euxo pipefail
chmod +x .github/scripts/package-client-cpp-manylinux228.sh
+ source .github/scripts/native-linux-env.sh
docker run --rm \
-v "${{ github.workspace }}:/workspace" \
-v "${HOME}/.m2:/root/.m2" \
-w /workspace \
-e GITHUB_WORKSPACE=/workspace \
- quay.io/pypa/manylinux_2_28_x86_64 \
+ "${NATIVE_LINUX_IMAGE}" \
bash .github/scripts/package-client-cpp-manylinux228.sh
- name: Restore workspace ownership after container build
if: always()
@@ -247,12 +248,13 @@ jobs:
run: |
set -euxo pipefail
chmod +x .github/scripts/package-client-cpp-manylinux228.sh
+ source .github/scripts/native-linux-env.sh
docker run --rm \
-v "${{ github.workspace }}:/workspace" \
-v "${HOME}/.m2:/root/.m2" \
-w /workspace \
-e GITHUB_WORKSPACE=/workspace \
- quay.io/pypa/manylinux_2_28_aarch64 \
+ "${NATIVE_LINUX_IMAGE}" \
bash .github/scripts/package-client-cpp-manylinux228.sh
- name: Restore workspace ownership after container build
if: always()
diff --git a/.github/workflows/multi-language-client.yml b/.github/workflows/multi-language-client.yml
index 61a947c3e08a4..3168c188ed84f 100644
--- a/.github/workflows/multi-language-client.yml
+++ b/.github/workflows/multi-language-client.yml
@@ -14,6 +14,7 @@ on:
- '.github/workflows/multi-language-client.yml'
- '.github/workflows/client-cpp-package.yml'
- '.github/scripts/package-client-cpp-*.sh'
+ - '.github/scripts/native-linux-env.sh'
pull_request:
branches:
- master
@@ -28,6 +29,7 @@ on:
- '.github/workflows/multi-language-client.yml'
- '.github/workflows/client-cpp-package.yml'
- '.github/scripts/package-client-cpp-*.sh'
+ - '.github/scripts/native-linux-env.sh'
# allow manually run the action:
workflow_dispatch:
@@ -80,7 +82,7 @@ jobs:
go=false
while IFS= read -r file; do
case "$file" in
- iotdb-client/pom.xml|iotdb-client/client-cpp/*|iotdb-protocol/thrift-datanode/src/main/thrift/client.thrift|iotdb-protocol/thrift-commons/src/main/thrift/common.thrift|.github/workflows/multi-language-client.yml|.github/workflows/client-cpp-package.yml|.github/scripts/package-client-cpp-*.sh)
+ iotdb-client/pom.xml|iotdb-client/client-cpp/*|iotdb-protocol/thrift-datanode/src/main/thrift/client.thrift|iotdb-protocol/thrift-commons/src/main/thrift/common.thrift|.github/workflows/multi-language-client.yml|.github/workflows/client-cpp-package.yml|.github/scripts/package-client-cpp-*.sh|.github/scripts/native-linux-env.sh)
cpp=true
;;
esac
diff --git a/.github/workflows/odbc-package.yml b/.github/workflows/odbc-package.yml
new file mode 100644
index 0000000000000..52a58bf6e926a
--- /dev/null
+++ b/.github/workflows/odbc-package.yml
@@ -0,0 +1,106 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+name: ODBC package
+on:
+ workflow_dispatch:
+ push:
+ paths:
+ - 'iotdb-client/odbc/**'
+ - 'iotdb-client/client-cpp/**'
+ - 'iotdb-protocol/**/thrift/**'
+ - '.github/scripts/*odbc*'
+ - '.github/scripts/native-linux-env.sh'
+ - '.github/workflows/odbc-package.yml'
+ pull_request:
+ paths:
+ - 'iotdb-client/odbc/**'
+ - 'iotdb-client/client-cpp/**'
+ - 'iotdb-protocol/**/thrift/**'
+ - '.github/scripts/*odbc*'
+ - '.github/scripts/native-linux-env.sh'
+ - '.github/workflows/odbc-package.yml'
+jobs:
+ linux:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v5
+ - name: Build and check glibc baseline
+ run: |
+ source .github/scripts/native-linux-env.sh
+ docker run --rm -v "$PWD:/workspace" -w /workspace "${NATIVE_LINUX_IMAGE}" \
+ bash .github/scripts/package-odbc-manylinux228.sh
+ - name: Restore ownership
+ if: always()
+ run: sudo chown -R "$(id -u):$(id -g)" iotdb-client/odbc/target iotdb-client/client-cpp/third-party
+ - uses: actions/upload-artifact@v6
+ with:
+ name: odbc-linux-x86_64-glibc2.28
+ path: iotdb-client/odbc/target/build/iotdb-odbc-*.zip*
+ if-no-files-found: error
+ windows:
+ runs-on: windows-2022
+ steps:
+ - uses: actions/checkout@v5
+ - name: Install build prerequisites
+ shell: pwsh
+ run: |
+ choco install winflexbison3 strawberryperl -y --no-progress
+ 'C:\Strawberry\perl\bin' >> $env:GITHUB_PATH
+ - name: Build, test and package
+ shell: pwsh
+ run: |
+ $version = ([xml](Get-Content iotdb-client/pom.xml)).project.parent.version
+ cmake -S iotdb-client/odbc -B iotdb-client/odbc/target/build -A x64 "-DODBC_PACKAGE_VERSION=$version" -DODBC_PACKAGE_CLASSIFIER=windows-x86_64
+ if ($LASTEXITCODE) { exit $LASTEXITCODE }
+ cmake --build iotdb-client/odbc/target/build --config Release --parallel 4
+ if ($LASTEXITCODE) { exit $LASTEXITCODE }
+ ctest --test-dir iotdb-client/odbc/target/build -C Release --output-on-failure
+ if ($LASTEXITCODE) { exit $LASTEXITCODE }
+ & iotdb-client/odbc/test/check-windows-dependencies.ps1 iotdb-client/odbc/target/build/Release/apache_iotdb_odbc.dll
+ Push-Location iotdb-client/odbc/target/build
+ cpack -C Release
+ if ($LASTEXITCODE) { exit $LASTEXITCODE }
+ Pop-Location
+ - uses: actions/upload-artifact@v6
+ with:
+ name: odbc-windows-x86_64
+ path: iotdb-client/odbc/target/build/iotdb-odbc-*.zip*
+ if-no-files-found: error
+ linux-runtime:
+ needs: linux
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ image: ['almalinux:8', 'ubuntu:22.04', 'ubuntu:24.04']
+ steps:
+ - uses: actions/download-artifact@v6
+ with:
+ name: odbc-linux-x86_64-glibc2.28
+ path: artifacts
+ - name: Extract release
+ run: unzip -q artifacts/*.zip -d package
+ - name: Load with system ODBC manager in a clean runtime
+ run: |
+ docker run --rm -v "$PWD/package:/package:ro" '${{ matrix.image }}' sh -ec '
+ if command -v dnf >/dev/null; then
+ dnf install -y unixODBC
+ else
+ apt-get update && apt-get install -y --no-install-recommends unixodbc
+ fi
+ pkg=$(find /package -mindepth 1 -maxdepth 1 -type d)
+ "$pkg/test/odbc_manager" "$pkg/lib/libapache_iotdb_odbc.so"
+ '
diff --git a/iotdb-client/client-cpp/CMakeLists.txt b/iotdb-client/client-cpp/CMakeLists.txt
index f6178d183d896..431aa5b98800b 100644
--- a/iotdb-client/client-cpp/CMakeLists.txt
+++ b/iotdb-client/client-cpp/CMakeLists.txt
@@ -22,6 +22,10 @@
cmake_minimum_required(VERSION 3.16)
project(iotdb_session CXX C)
+option(IOTDB_SESSION_STATIC "Build the session client as a static library" OFF)
+option(IOTDB_STATIC_CRT "Use the static MSVC runtime" OFF)
+option(IOTDB_SESSION_INSTALL "Install the standalone session SDK" ON)
+
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
@@ -46,7 +50,11 @@ endif()
if(MSVC)
# /MD: matches default Visual Studio projects; CRT lives in the VC redistributable.
- set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL")
+ if(IOTDB_STATIC_CRT)
+ set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>")
+ else()
+ set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL")
+ endif()
endif()
if(NOT IOTDB_USE_CXX11_ABI STREQUAL "" AND NOT IOTDB_USE_CXX11_ABI MATCHES "^[01]$")
@@ -59,7 +67,7 @@ if(NOT MSVC)
else()
set(_iotdb_cxx11_abi_stamp_value "default")
endif()
- set(_iotdb_cxx11_abi_stamp "${CMAKE_BINARY_DIR}/.iotdb-cxx11-abi")
+ set(_iotdb_cxx11_abi_stamp "${CMAKE_CURRENT_BINARY_DIR}/.iotdb-cxx11-abi")
if(EXISTS "${_iotdb_cxx11_abi_stamp}")
file(READ "${_iotdb_cxx11_abi_stamp}" _iotdb_previous_cxx11_abi)
else()
@@ -69,8 +77,8 @@ if(NOT MSVC)
message(STATUS
"IOTDB_USE_CXX11_ABI changed from '${_iotdb_previous_cxx11_abi}' "
"to '${_iotdb_cxx11_abi_stamp_value}'; removing cached iotdb_session objects")
- file(REMOVE_RECURSE "${CMAKE_BINARY_DIR}/CMakeFiles/iotdb_session.dir")
- file(GLOB _iotdb_stale_session_libs "${CMAKE_BINARY_DIR}/libiotdb_session.so*")
+ file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/iotdb_session.dir")
+ file(GLOB _iotdb_stale_session_libs "${CMAKE_CURRENT_BINARY_DIR}/libiotdb_session.so*")
if(_iotdb_stale_session_libs)
file(REMOVE ${_iotdb_stale_session_libs})
endif()
@@ -110,7 +118,7 @@ endif()
file(MAKE_DIRECTORY "${IOTDB_OS_DEPS_DIR}")
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
- set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install"
+ set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/install"
CACHE PATH "Install prefix" FORCE)
endif()
@@ -130,12 +138,17 @@ file(GLOB SESSION_PUBLIC_SRCS CONFIGURE_DEPENDS
file(GLOB SESSION_RPC_SRCS CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/src/rpc/*.cpp")
-add_library(iotdb_session SHARED
+if(IOTDB_SESSION_STATIC)
+ set(_iotdb_library_type STATIC)
+else()
+ set(_iotdb_library_type SHARED)
+endif()
+add_library(iotdb_session ${_iotdb_library_type}
${SESSION_PUBLIC_SRCS}
${SESSION_RPC_SRCS}
${THRIFT_GENERATED_SRCS})
-if(WIN32)
+if(WIN32 AND NOT IOTDB_SESSION_STATIC)
set_target_properties(iotdb_session PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif()
@@ -163,7 +176,12 @@ endif()
add_dependencies(iotdb_session iotdb_thrift_external iotdb_thrift_codegen)
-target_compile_definitions(iotdb_session PRIVATE THRIFT_STATIC_DEFINE IOTDB_BUILDING_SHARED)
+target_compile_definitions(iotdb_session PRIVATE THRIFT_STATIC_DEFINE)
+if(IOTDB_SESSION_STATIC)
+ target_compile_definitions(iotdb_session PUBLIC IOTDB_SESSION_STATIC)
+else()
+ target_compile_definitions(iotdb_session PRIVATE IOTDB_BUILDING_SHARED)
+endif()
if(NOT IOTDB_USE_CXX11_ABI STREQUAL "" AND NOT MSVC)
target_compile_definitions(iotdb_session PUBLIC
_GLIBCXX_USE_CXX11_ABI=${IOTDB_USE_CXX11_ABI})
@@ -179,7 +197,9 @@ target_include_directories(iotdb_session
${THRIFT_INCLUDE_DIR}
$<$:${BOOST_INCLUDE_DIR}>)
-if(APPLE)
+if(IOTDB_SESSION_STATIC)
+ target_link_libraries(iotdb_session PRIVATE iotdb_thrift_static)
+elseif(APPLE)
target_link_libraries(iotdb_session PRIVATE "-Wl,-force_load,${THRIFT_STATIC_LIB_PATH}")
elseif(UNIX AND NOT MSVC)
# whole-archive pulls all Thrift objects into libiotdb_session.so; allow-multiple-definition
@@ -214,6 +234,8 @@ endif()
include(GNUInstallDirs)
+if(IOTDB_SESSION_INSTALL)
+
set(IOTDB_PUBLIC_HEADERS
Export.h
SessionConfig.h
@@ -265,11 +287,11 @@ if(NOT IOTDB_USE_CXX11_ABI STREQUAL "" AND NOT MSVC)
endif()
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/iotdb-session-config.cmake.in"
- "${CMAKE_BINARY_DIR}/package-metadata/cmake/iotdb-session-config.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/package-metadata/cmake/iotdb-session-config.cmake"
@ONLY)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/iotdb-session.pc.in"
- "${CMAKE_BINARY_DIR}/package-metadata/pkgconfig/iotdb-session.pc"
+ "${CMAKE_CURRENT_BINARY_DIR}/package-metadata/pkgconfig/iotdb-session.pc"
@ONLY)
execute_process(
COMMAND git rev-parse HEAD
@@ -296,9 +318,9 @@ else()
set(IOTDB_SESSION_OPENSSL_VERSION "disabled")
set(IOTDB_SESSION_OPENSSL_PROVIDER "disabled")
endif()
-file(WRITE "${CMAKE_BINARY_DIR}/package-metadata/VERSION"
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/package-metadata/VERSION"
"${IOTDB_SESSION_VERSION}\n")
-file(WRITE "${CMAKE_BINARY_DIR}/package-metadata/BUILD-INFO.txt"
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/package-metadata/BUILD-INFO.txt"
"Apache IoTDB C++ session client build information\n\n"
"version=${IOTDB_SESSION_VERSION}\n"
"commit=${IOTDB_SESSION_GIT_COMMIT}\n"
@@ -313,14 +335,15 @@ file(WRITE "${CMAKE_BINARY_DIR}/package-metadata/BUILD-INFO.txt"
"iotdb.offline=${IOTDB_OFFLINE}\n"
"iotdb.use.cxx11.abi=${IOTDB_USE_CXX11_ABI}\n"
"iotdb.extra.cxx.flags=${IOTDB_EXTRA_CXX_FLAGS}\n")
-install(FILES "${CMAKE_BINARY_DIR}/package-metadata/cmake/iotdb-session-config.cmake"
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/package-metadata/cmake/iotdb-session-config.cmake"
DESTINATION cmake)
-install(FILES "${CMAKE_BINARY_DIR}/package-metadata/pkgconfig/iotdb-session.pc"
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/package-metadata/pkgconfig/iotdb-session.pc"
DESTINATION pkgconfig)
install(FILES
- "${CMAKE_BINARY_DIR}/package-metadata/VERSION"
- "${CMAKE_BINARY_DIR}/package-metadata/BUILD-INFO.txt"
+ "${CMAKE_CURRENT_BINARY_DIR}/package-metadata/VERSION"
+ "${CMAKE_CURRENT_BINARY_DIR}/package-metadata/BUILD-INFO.txt"
DESTINATION .)
+endif()
if(BUILD_TESTING)
enable_testing()
diff --git a/iotdb-client/client-cpp/cmake/FetchBoost.cmake b/iotdb-client/client-cpp/cmake/FetchBoost.cmake
index d1ab9c18ae1b9..75eec3fa4462e 100644
--- a/iotdb-client/client-cpp/cmake/FetchBoost.cmake
+++ b/iotdb-client/client-cpp/cmake/FetchBoost.cmake
@@ -103,9 +103,9 @@ if(NOT _boost_tarball)
endif()
# ---------------------------------------------------------------------------
-# Extract headers-only into ${CMAKE_BINARY_DIR}/_deps/boost
+# Extract headers-only into ${CMAKE_CURRENT_BINARY_DIR}/_deps/boost
# ---------------------------------------------------------------------------
-set(_boost_extract_dir "${CMAKE_BINARY_DIR}/_deps/boost")
+set(_boost_extract_dir "${CMAKE_CURRENT_BINARY_DIR}/_deps/boost")
set(_boost_marker "${_boost_extract_dir}/.extracted-${BOOST_VERSION}")
if(NOT EXISTS "${_boost_marker}")
diff --git a/iotdb-client/client-cpp/cmake/FetchBuildTools.cmake b/iotdb-client/client-cpp/cmake/FetchBuildTools.cmake
index 5860d68ac195f..f24a78bd4726e 100644
--- a/iotdb-client/client-cpp/cmake/FetchBuildTools.cmake
+++ b/iotdb-client/client-cpp/cmake/FetchBuildTools.cmake
@@ -23,7 +23,7 @@
# Otherwise we provision them locally:
#
# * Linux / macOS - configure-make-install each tool from a tarball into
-# ${CMAKE_BINARY_DIR}/tools (no sudo required).
+# ${CMAKE_CURRENT_BINARY_DIR}/tools (no sudo required).
# * Windows - extract the winflexbison zip and copy
# win_flex.exe -> flex.exe, win_bison.exe -> bison.exe.
#
@@ -33,7 +33,7 @@
# 3. FATAL_ERROR otherwise
# =============================================================================
-set(_tools_prefix "${CMAKE_BINARY_DIR}/tools")
+set(_tools_prefix "${CMAKE_CURRENT_BINARY_DIR}/tools")
set(_tools_bin "${_tools_prefix}/bin")
file(MAKE_DIRECTORY "${_tools_bin}")
@@ -109,7 +109,7 @@ endfunction()
# Configure-make-install from into ${_tools_prefix}.
function(_iotdb_build_autotools NAME TARBALL EXTRACTED_DIRNAME)
- set(_src_root "${CMAKE_BINARY_DIR}/_deps/${NAME}")
+ set(_src_root "${CMAKE_CURRENT_BINARY_DIR}/_deps/${NAME}")
set(_marker "${_tools_prefix}/.${NAME}-installed")
if(EXISTS "${_marker}")
return()
diff --git a/iotdb-client/client-cpp/cmake/FetchOpenSSL.cmake b/iotdb-client/client-cpp/cmake/FetchOpenSSL.cmake
index 165736dd1602c..8626eb0d83e99 100644
--- a/iotdb-client/client-cpp/cmake/FetchOpenSSL.cmake
+++ b/iotdb-client/client-cpp/cmake/FetchOpenSSL.cmake
@@ -21,7 +21,7 @@
# Apache Thrift 0.24 (bundled by this client) builds against OpenSSL 3.x.
#
# By default, a fixed OpenSSL source release is downloaded, checksum-verified,
-# built as shared libraries, and installed under ${CMAKE_BINARY_DIR}/_deps.
+# built as shared libraries, and installed under ${CMAKE_CURRENT_BINARY_DIR}/_deps.
# Set IOTDB_OPENSSL_FROM_SOURCE=OFF to opt into a compatible system OpenSSL.
#
# Side effects:
@@ -41,6 +41,9 @@ set(OPENSSL_FALLBACK_SHA256
# packages independent of the build host's OpenSSL installation.
option(IOTDB_OPENSSL_FROM_SOURCE
"Ignore any system OpenSSL and build OpenSSL ${OPENSSL_FALLBACK_VERSION} from source" ON)
+option(IOTDB_OPENSSL_STATIC "Build OpenSSL as static PIC libraries" OFF)
+set(OPENSSL_USE_STATIC_LIBS ${IOTDB_OPENSSL_STATIC})
+set(OPENSSL_MSVC_STATIC_RT ${IOTDB_STATIC_CRT})
if(NOT IOTDB_OPENSSL_FROM_SOURCE)
find_package(OpenSSL QUIET)
@@ -88,7 +91,24 @@ if(_ossl_download_required)
endif()
endif()
-set(_ossl_root "${CMAKE_BINARY_DIR}/_deps/openssl")
+set(_ossl_variant "shared")
+set(_ossl_options shared no-tests)
+if(IOTDB_OPENSSL_STATIC)
+ set(_ossl_variant "static-${CMAKE_SYSTEM_PROCESSOR}-${CMAKE_C_COMPILER_ID}-${CMAKE_C_COMPILER_VERSION}-${CMAKE_BUILD_TYPE}-crt${IOTDB_STATIC_CRT}")
+ set(_ossl_options no-shared no-module no-tests)
+ if(NOT WIN32)
+ list(APPEND _ossl_options -fPIC)
+ elseif(NOT IOTDB_STATIC_CRT)
+ list(APPEND _ossl_options /MD)
+ endif()
+ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
+ list(APPEND _ossl_options --debug)
+ endif()
+endif()
+set(_ossl_root "${CMAKE_CURRENT_BINARY_DIR}/_deps/openssl")
+if(IOTDB_OPENSSL_STATIC)
+ string(APPEND _ossl_root "-${_ossl_variant}")
+endif()
set(_ossl_src "${_ossl_root}/src/openssl-${OPENSSL_FALLBACK_VERSION}")
set(_ossl_inst "${_ossl_root}/install")
set(_ossl_stamp "${_ossl_root}/.built-${OPENSSL_FALLBACK_VERSION}")
@@ -134,12 +154,13 @@ if(NOT EXISTS "${_ossl_stamp}")
file(TO_NATIVE_PATH "${_ossl_src}" _ossl_src_native)
file(TO_NATIVE_PATH "${_ossl_perl}" _ossl_perl_native)
set(_ossl_build_script "${_ossl_root}/build-openssl.cmd")
+ string(REPLACE ";" " " _ossl_windows_options "${_ossl_options}")
file(WRITE "${_ossl_build_script}"
"@echo on\r\n"
"call \"${_vcvars}\"\r\n"
"if errorlevel 1 exit /b %errorlevel%\r\n"
"cd /d \"${_ossl_src_native}\"\r\n"
- "\"${_ossl_perl_native}\" Configure VC-WIN64A --prefix=\"${_ossl_inst_native}\" --openssldir=\"${_ossl_inst_native}\\ssl\" shared no-tests no-asm\r\n"
+ "\"${_ossl_perl_native}\" Configure VC-WIN64A --prefix=\"${_ossl_inst_native}\" --openssldir=\"${_ossl_inst_native}\\ssl\" ${_ossl_windows_options} no-asm\r\n"
"if errorlevel 1 exit /b %errorlevel%\r\n"
"nmake\r\n"
"if errorlevel 1 exit /b %errorlevel%\r\n"
@@ -155,7 +176,8 @@ if(NOT EXISTS "${_ossl_stamp}")
set(_jobs 1)
endif()
execute_process(
- COMMAND ./config --prefix=${_ossl_inst} --openssldir=${_ossl_inst}/ssl shared no-tests
+ COMMAND ${CMAKE_COMMAND} -E env "CC=${CMAKE_C_COMPILER}"
+ ./config --prefix=${_ossl_inst} --openssldir=${_ossl_inst}/ssl ${_ossl_options}
WORKING_DIRECTORY "${_ossl_src}"
RESULT_VARIABLE _rc)
if(NOT _rc EQUAL 0)
@@ -180,7 +202,7 @@ if(NOT EXISTS "${_ossl_stamp}")
file(TOUCH "${_ossl_stamp}")
endif()
-if(APPLE)
+if(APPLE AND NOT IOTDB_OPENSSL_STATIC)
# OpenSSL's Darwin build records its absolute installation prefix in each dylib. Rewrite the
# IDs before iotdb_session links against them so both the client and libssl resolve the bundled
# libraries relative to the package's lib/ directory.
@@ -233,6 +255,11 @@ if(APPLE)
endif()
set(OPENSSL_ROOT_DIR "${_ossl_inst}" CACHE PATH "OpenSSL root" FORCE)
-set(OPENSSL_USE_STATIC_LIBS OFF)
+# Do not reuse a previous shared-library discovery when switching variants.
+unset(OPENSSL_SSL_LIBRARY CACHE)
+unset(OPENSSL_CRYPTO_LIBRARY CACHE)
+unset(OPENSSL_INCLUDE_DIR CACHE)
find_package(OpenSSL REQUIRED)
-message(STATUS "[OpenSSL] built locally (shared) at ${OPENSSL_ROOT_DIR}")
+# The ODBC parent also consumes these targets (FindOpenSSL creates local imports).
+set_property(TARGET OpenSSL::SSL OpenSSL::Crypto PROPERTY IMPORTED_GLOBAL TRUE)
+message(STATUS "[OpenSSL] built locally (${_ossl_variant}) at ${OPENSSL_ROOT_DIR}")
diff --git a/iotdb-client/client-cpp/cmake/FetchThrift.cmake b/iotdb-client/client-cpp/cmake/FetchThrift.cmake
index d69b2a47ad9e5..a5b614ad281cf 100644
--- a/iotdb-client/client-cpp/cmake/FetchThrift.cmake
+++ b/iotdb-client/client-cpp/cmake/FetchThrift.cmake
@@ -67,9 +67,12 @@ if(NOT EXISTS "${_thrift_tarball}")
endif()
# ---------------------------------------------------------------------------
-# Extract once into ${CMAKE_BINARY_DIR}/_deps/thrift/src
+# Extract once into ${CMAKE_CURRENT_BINARY_DIR}/_deps/thrift/src
# ---------------------------------------------------------------------------
-set(_thrift_root "${CMAKE_BINARY_DIR}/_deps/thrift")
+set(_thrift_root "${CMAKE_CURRENT_BINARY_DIR}/_deps/thrift")
+if(IOTDB_SESSION_STATIC)
+ string(APPEND _thrift_root "-static-${CMAKE_SYSTEM_PROCESSOR}-${CMAKE_CXX_COMPILER_ID}-${CMAKE_CXX_COMPILER_VERSION}-${CMAKE_BUILD_TYPE}-crt${IOTDB_STATIC_CRT}-ssl${WITH_SSL}-abi${IOTDB_USE_CXX11_ABI}")
+endif()
set(_thrift_src "${_thrift_root}/src/${_thrift_dirname}")
set(_thrift_build "${_thrift_root}/build")
set(_thrift_install "${_thrift_root}/install")
@@ -125,19 +128,28 @@ endif()
if(MSVC)
list(APPEND _thrift_cmake_args
- "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded$<$:Debug>DLL")
+ "-DWITH_MT=${IOTDB_STATIC_CRT}"
+ "-DCMAKE_MSVC_RUNTIME_LIBRARY=${CMAKE_MSVC_RUNTIME_LIBRARY}")
else()
set(_thrift_cxxflags "-fPIC")
- if(IOTDB_USE_CXX11_ABI)
+ if(NOT IOTDB_USE_CXX11_ABI STREQUAL "")
set(_thrift_cxxflags "${_thrift_cxxflags} -D_GLIBCXX_USE_CXX11_ABI=${IOTDB_USE_CXX11_ABI}")
endif()
list(APPEND _thrift_cmake_args
+ "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
+ "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
"-DCMAKE_C_FLAGS=-fPIC"
"-DCMAKE_CXX_FLAGS=${_thrift_cxxflags}")
endif()
if(WITH_SSL)
list(APPEND _thrift_cmake_args "-DWITH_OPENSSL=ON")
+ list(APPEND _thrift_cmake_args
+ "-DOPENSSL_USE_STATIC_LIBS=${IOTDB_OPENSSL_STATIC}"
+ "-DOPENSSL_MSVC_STATIC_RT=${IOTDB_STATIC_CRT}"
+ "-DOPENSSL_SSL_LIBRARY=${OPENSSL_SSL_LIBRARY}"
+ "-DOPENSSL_CRYPTO_LIBRARY=${OPENSSL_CRYPTO_LIBRARY}"
+ "-DOPENSSL_INCLUDE_DIR=${OPENSSL_INCLUDE_DIR}")
# Build Thrift's TSSLSocket against the same OpenSSL that iotdb_session links
# and bundles, so the runtime libraries match. find_package does not set
# OPENSSL_ROOT_DIR itself, so derive it from the resolved include dir.
diff --git a/iotdb-client/client-cpp/cmake/GenerateThriftSources.cmake b/iotdb-client/client-cpp/cmake/GenerateThriftSources.cmake
index 6a3685af45847..ba1c931fd5e17 100644
--- a/iotdb-client/client-cpp/cmake/GenerateThriftSources.cmake
+++ b/iotdb-client/client-cpp/cmake/GenerateThriftSources.cmake
@@ -51,12 +51,12 @@ endforeach()
# Mirror the bash reference script: stage both .thrift files into a flat
# working directory so `include "common.thrift"` resolves without -I args.
-set(_thrift_proto_dir "${CMAKE_BINARY_DIR}/thrift-protocols")
+set(_thrift_proto_dir "${CMAKE_CURRENT_BINARY_DIR}/thrift-protocols")
file(MAKE_DIRECTORY "${_thrift_proto_dir}")
configure_file("${_common_thrift}" "${_thrift_proto_dir}/common.thrift" COPYONLY)
configure_file("${_client_thrift}" "${_thrift_proto_dir}/client.thrift" COPYONLY)
-set(THRIFT_GEN_CPP_DIR "${CMAKE_BINARY_DIR}/gen-cpp" CACHE PATH "" FORCE)
+set(THRIFT_GEN_CPP_DIR "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp" CACHE PATH "" FORCE)
file(MAKE_DIRECTORY "${THRIFT_GEN_CPP_DIR}")
# A stamp file lets us re-run thrift only when one of the inputs changes
diff --git a/iotdb-client/client-cpp/src/include/Export.h b/iotdb-client/client-cpp/src/include/Export.h
index 71262d0cffb77..d4f46d3ed8732 100644
--- a/iotdb-client/client-cpp/src/include/Export.h
+++ b/iotdb-client/client-cpp/src/include/Export.h
@@ -19,7 +19,9 @@
#ifndef IOTDB_EXPORT_H
#define IOTDB_EXPORT_H
-#if defined(_WIN32) && defined(IOTDB_BUILDING_SHARED)
+#if defined(IOTDB_SESSION_STATIC)
+#define IOTDB_SESSION_API
+#elif defined(_WIN32) && defined(IOTDB_BUILDING_SHARED)
#define IOTDB_SESSION_API __declspec(dllexport)
#elif defined(_WIN32)
#define IOTDB_SESSION_API __declspec(dllimport)
diff --git a/iotdb-client/odbc/.gitignore b/iotdb-client/odbc/.gitignore
new file mode 100644
index 0000000000000..ee7337d45fb1d
--- /dev/null
+++ b/iotdb-client/odbc/.gitignore
@@ -0,0 +1,28 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# Root rules ignore *.txt, *.cmake and lib/; these are source inputs here.
+!/CMakeLists.txt
+!/cmake/*.cmake
+!/test/CMakeLists.txt
+!/deps/
+!/deps/**
+!/licenses/*.txt
+!/examples/python-example/requirements.txt
+/target/
+/build/
+__pycache__/
+*.log
diff --git a/iotdb-client/odbc/CMakeLists.txt b/iotdb-client/odbc/CMakeLists.txt
new file mode 100644
index 0000000000000..18859bc5c1e35
--- /dev/null
+++ b/iotdb-client/odbc/CMakeLists.txt
@@ -0,0 +1,144 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+cmake_minimum_required(VERSION 3.20)
+cmake_policy(SET CMP0091 NEW)
+project(apache_iotdb_odbc VERSION 1.0.0 LANGUAGES C CXX)
+
+set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8 OR
+ NOT CMAKE_SYSTEM_NAME MATCHES "^(Windows|Linux)$" OR
+ NOT CMAKE_SYSTEM_PROCESSOR MATCHES "^(AMD64|amd64|x86_64|X86_64)$" OR
+ CMAKE_GENERATOR_PLATFORM MATCHES "[Aa][Rr][Mm]")
+ message(FATAL_ERROR "ODBC release builds support Windows/Linux x64 only")
+endif()
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+if(NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
+endif()
+if(MSVC)
+ # OpenSSL and Thrift are configured once per build directory. Avoid linking
+ # a Debug driver against dependencies built with the Release CRT.
+ set(CMAKE_CONFIGURATION_TYPES "${CMAKE_BUILD_TYPE}" CACHE STRING "Configurations" FORCE)
+endif()
+set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>")
+option(ODBC_BUILD_TESTS "Build ODBC tests" ON)
+file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/../pom.xml" _version_line REGEX "")
+list(GET _version_line 0 _version_line)
+string(REGEX REPLACE ".*([^<]+).*" "\\1" _repository_version "${_version_line}")
+set(ODBC_PACKAGE_VERSION "${_repository_version}" CACHE STRING "Package version")
+set(ODBC_PACKAGE_CLASSIFIER "${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}" CACHE STRING "Release platform")
+
+# Scope SDK configuration to this build; its standalone defaults remain unchanged.
+set(IOTDB_SESSION_STATIC ON CACHE BOOL "" FORCE)
+set(IOTDB_SESSION_INSTALL OFF CACHE BOOL "" FORCE)
+set(IOTDB_STATIC_CRT ON CACHE BOOL "" FORCE)
+set(IOTDB_OPENSSL_STATIC ON CACHE BOOL "" FORCE)
+set(IOTDB_OPENSSL_FROM_SOURCE ON CACHE BOOL "" FORCE)
+set(WITH_SSL ON CACHE BOOL "" FORCE)
+set(IOTDB_SESSION_VERSION "${ODBC_PACKAGE_VERSION}" CACHE STRING "" FORCE)
+set(BUILD_TESTING OFF CACHE BOOL "" FORCE)
+add_subdirectory(../client-cpp client-cpp EXCLUDE_FROM_ALL)
+
+# Keep the original vendored curl snapshot. HTTP is the existing REST transport;
+# Session TLS is implemented by the shared C++ client, not curl.
+set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
+set(BUILD_CURL_EXE OFF CACHE BOOL "" FORCE)
+set(BUILD_TESTING OFF CACHE BOOL "" FORCE)
+set(BUILD_LIBCURL_DOCS OFF CACHE BOOL "" FORCE)
+set(ENABLE_MANUAL OFF CACHE BOOL "" FORCE)
+set(CURL_DISABLE_INSTALL ON CACHE BOOL "" FORCE)
+set(HTTP_ONLY ON CACHE BOOL "" FORCE)
+set(CURL_USE_OPENSSL OFF CACHE BOOL "" FORCE)
+set(CURL_USE_SCHANNEL OFF CACHE BOOL "" FORCE)
+set(CURL_ENABLE_SSL OFF CACHE BOOL "" FORCE)
+set(CURL_ZLIB OFF CACHE BOOL "" FORCE)
+set(CURL_BROTLI OFF CACHE BOOL "" FORCE)
+set(CURL_ZSTD OFF CACHE BOOL "" FORCE)
+set(CURL_USE_LIBPSL OFF CACHE BOOL "" FORCE)
+set(CURL_USE_LIBSSH2 OFF CACHE BOOL "" FORCE)
+set(USE_NGHTTP2 OFF CACHE BOOL "" FORCE)
+set(USE_LIBIDN2 OFF CACHE BOOL "" FORCE)
+set(ENABLE_LDAP OFF CACHE BOOL "" FORCE)
+set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
+set(CURL_DISABLE_LDAPS ON CACHE BOOL "" FORCE)
+set(CURL_STATIC_CRT ${MSVC} CACHE BOOL "" FORCE)
+add_subdirectory(deps/curl-src curl EXCLUDE_FROM_ALL)
+
+set(DRIVER_VERSION "${ODBC_PACKAGE_VERSION}")
+set(DEBUG_LOG_ENABLED TRUE)
+set(DEBUG_LOG_OUTPUT_PATH "apache_iotdb_odbc.log")
+configure_file(src/DriverConfig.h.in generated/DriverConfig.h @ONLY)
+file(GLOB ODBC_SOURCES CONFIGURE_DEPENDS src/*.cpp)
+list(REMOVE_ITEM ODBC_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/install_driver.cpp")
+add_library(odbc_objects OBJECT ${ODBC_SOURCES})
+target_include_directories(odbc_objects PUBLIC src "${CMAKE_CURRENT_BINARY_DIR}/generated"
+ deps/json-src/single_include)
+target_link_libraries(odbc_objects PUBLIC iotdb_session CURL::libcurl)
+target_compile_definitions(odbc_objects PUBLIC CURL_STATICLIB)
+add_library(apache_iotdb_odbc SHARED $)
+target_link_libraries(apache_iotdb_odbc PRIVATE odbc_objects)
+if(WIN32)
+ enable_language(RC)
+ target_compile_definitions(odbc_objects PUBLIC NOMINMAX WIN32_LEAN_AND_MEAN)
+ target_compile_options(odbc_objects PUBLIC /utf-8)
+ target_sources(odbc_objects PRIVATE src/setup/setup_dialog.cpp)
+ target_sources(apache_iotdb_odbc PRIVATE src/setup/setup.rc driver.def)
+ target_link_libraries(odbc_objects PUBLIC odbccp32 legacy_stdio_definitions)
+ add_executable(install_driver src/install_driver.cpp)
+ target_compile_definitions(install_driver PRIVATE NOMINMAX WIN32_LEAN_AND_MEAN)
+ target_link_libraries(install_driver PRIVATE odbccp32 legacy_stdio_definitions)
+ install(TARGETS install_driver RUNTIME DESTINATION bin)
+ install(FILES install.bat uninstall.bat DESTINATION .)
+else()
+ find_path(ODBC_INCLUDE_DIR sql.h REQUIRED)
+ find_library(ODBCINST_LIBRARY odbcinst REQUIRED)
+ target_include_directories(odbc_objects PUBLIC "${ODBC_INCLUDE_DIR}")
+ target_link_libraries(odbc_objects PUBLIC "${ODBCINST_LIBRARY}")
+ target_link_options(apache_iotdb_odbc PRIVATE -static-libstdc++ -static-libgcc
+ "LINKER:--version-script=${CMAKE_CURRENT_SOURCE_DIR}/exports.map"
+ "LINKER:--exclude-libs,ALL" "LINKER:-z,defs" "LINKER:-Bsymbolic-functions")
+ set_property(TARGET apache_iotdb_odbc APPEND PROPERTY LINK_DEPENDS
+ "${CMAKE_CURRENT_SOURCE_DIR}/exports.map")
+endif()
+install(TARGETS apache_iotdb_odbc RUNTIME DESTINATION bin LIBRARY DESTINATION lib)
+install(FILES README.md SOURCE.md VALIDATION.md DESTINATION .)
+install(DIRECTORY conf/ DESTINATION conf)
+install(FILES deps/curl-src/COPYING DESTINATION licenses RENAME curl.txt)
+install(FILES deps/json-src/LICENSE.MIT DESTINATION licenses RENAME json.txt)
+install(DIRECTORY ../client-cpp/src/assembly/package-metadata/third_party/ DESTINATION licenses/sdk)
+install(FILES ../../LICENSE ../../NOTICE DESTINATION .)
+install(DIRECTORY licenses/ DESTINATION licenses)
+execute_process(COMMAND git rev-parse HEAD WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+ OUTPUT_VARIABLE ODBC_COMMIT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/BUILD-INFO.txt"
+ "version=${ODBC_PACKAGE_VERSION}\ncommit=${ODBC_COMMIT}\nsource.odbc=21db94e\n"
+ "platform=${ODBC_PACKAGE_CLASSIFIER}\ncompiler=${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}\n"
+ "thrift=${THRIFT_VERSION}\nopenssl=${OPENSSL_FALLBACK_VERSION}\n"
+ "session.linkage=static\nopenssl.linkage=static\ncurl.linkage=static\n")
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/BUILD-INFO.txt" DESTINATION .)
+
+if(ODBC_BUILD_TESTS)
+ enable_testing()
+ add_subdirectory(test)
+endif()
+
+set(CPACK_GENERATOR ZIP)
+set(CPACK_PACKAGE_FILE_NAME "iotdb-odbc-${ODBC_PACKAGE_VERSION}-${ODBC_PACKAGE_CLASSIFIER}")
+set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY ON)
+set(CPACK_PACKAGE_CHECKSUM SHA512)
+include(CPack)
diff --git a/iotdb-client/odbc/README.md b/iotdb-client/odbc/README.md
new file mode 100644
index 0000000000000..3fcceeaa4d7f2
--- /dev/null
+++ b/iotdb-client/odbc/README.md
@@ -0,0 +1,117 @@
+
+# IoTDB ODBC driver
+
+The driver builds directly against `../client-cpp`. Each release contains one
+driver library with the Session client, Thrift, OpenSSL and curl linked statically.
+It does not require a separately installed C++ SDK, OpenSSL or VC redistributable.
+The OS libraries and ODBC manager/installer remain system prerequisites.
+
+## Build
+
+Use CMake 3.20+, a C++14 compiler and the C++ SDK build prerequisites. Windows
+requires Visual Studio 2022 x64, Strawberry Perl and winflexbison3. Linux requires
+unixODBC development headers. Dependency archives use the C++ SDK cache under
+`../client-cpp/third-party`; `-DIOTDB_OFFLINE=ON` requires a populated cache.
+
+```sh
+cmake -S iotdb-client/odbc -B iotdb-client/odbc/target/build -DCMAKE_BUILD_TYPE=Release
+cmake --build iotdb-client/odbc/target/build --config Release --parallel 4
+ctest --test-dir iotdb-client/odbc/target/build -C Release --output-on-failure
+cd iotdb-client/odbc/target/build
+cpack -C Release
+```
+
+On Windows pass `-A x64` to configure. Maven also supports
+`./mvnw package -P with-odbc -pl iotdb-client/odbc`; CMake and CPack must be on PATH.
+`-DskipTests` skips test execution. Builds do not register the driver on the host.
+
+For Linux release packages use the same manylinux 2.28 baseline as the C++ SDK:
+
+```sh
+source .github/scripts/native-linux-env.sh
+docker run --rm -v "$PWD:/workspace" -w /workspace "$NATIVE_LINUX_IMAGE" \
+ bash .github/scripts/package-odbc-manylinux228.sh
+```
+
+The release script builds all dependencies in this environment, runs tests and
+rejects unexpected shared-library dependencies or GLIBC requirements above 2.28.
+A build on a newer host is a development build, not evidence of glibc 2.28 compatibility.
+Release scope is Linux x86_64 and Windows x64 (Windows 10/11, Server 2016+).
+Packages and SHA-512 checksums are written into the CMake build directory.
+
+## Install
+
+Windows: extract the release, then run `install.bat "C:\Program Files\Apache IoTDB ODBC Driver"`
+from an administrator command prompt. Use the **64-bit** ODBC administrator to
+configure a DSN. `uninstall.bat` unregisters the driver, preserving DSNs and files.
+
+Linux: install unixODBC, extract the release, update `Driver` in `conf/odbcinst.ini`
+to the absolute library path, then register with `odbcinst -i -d -f conf/odbcinst.ini`.
+Copy the example DSN into your user `odbc.ini` and provide your credentials.
+
+## Connection and encryption
+
+Existing `SERVER`, `PORT`, `UID`, `PWD`, `DATABASE`, `ISTABLEMODEL`, `LOGLEVEL`,
+`SESSIONTIMEOUTMS` and `BATCHSIZE` parameters remain available. `RESTFUL=1` selects
+the retained HTTP REST implementation; specify its HTTP port explicitly.
+The default is Session RPC on port 6667. Explicit connection attributes override
+DSN values. Values containing semicolons can be braced, with `}}` escaping `}`.
+
+```text
+DRIVER={Apache IoTDB ODBC Driver};SERVER=localhost;PORT=6667;UID=root;PWD={your password};DATABASE=information_schema;SSL=1;SSLCA={C:\certs\ca.pem};
+```
+
+| Attribute | Default | Meaning |
+| --- | --- | --- |
+| SSL | 0 | Enable Session TLS; accepts 0/1, false/true, no/yes, off/on |
+| SSLCA | empty | Trusted CA file in PEM format; required for TLS |
+| SSLCERT | empty | PEM client certificate for mutual TLS |
+| SSLKEY | empty | PEM client private key; required together with SSLCERT |
+
+These attributes are available in connection strings, DSNs and the Windows setup
+dialog. Certificates are external files readable by the application account;
+they are not compiled into the driver. The server must enable the corresponding
+RPC TLS mode. The client verifies trust and server identity and never falls back
+to plaintext. Connection testing and queries use the same Session construction.
+Certificate attributes with SSL disabled are rejected. REST combined with these
+TLS options is rejected: HTTPS is outside this migration's scope.
+
+## Validation
+
+CTest covers configuration, type conversions, diagnostics and loading through the
+system ODBC manager. The manager test deliberately rejects an invalid TLS/REST
+combination without contacting a server. Windows tests use a temporary,
+process-local registry sandbox and do not install a system ODBC driver.
+To test a running server:
+
+```sh
+export IOTDB_ODBC_CONNECTION='SERVER=localhost;PORT=6667;UID=root;PWD=your-password;ISTABLEMODEL=0'
+target/build/test/odbc_manager /absolute/path/libapache_iotdb_odbc.so
+```
+
+Set `IOTDB_ODBC_QUERY` to exercise a query and `IOTDB_ODBC_EXPECT_FAILURE=1` for
+negative connection tests. For plain/TLS/mTLS server phases, run
+`python test/run_e2e.py --help`; use a disposable server distribution and test data.
+The runner requires Java 17+, `keytool`, Python 3 and (on Linux) `lsof` or `netstat`.
+Set `IOTDB_TEST_PASSWORD` to the test server password. It copies the supplied
+distribution, refuses occupied test ports and removes the temporary copy afterward.
+See `VALIDATION.md` for checks actually performed during migration.
diff --git a/iotdb-client/odbc/SOURCE.md b/iotdb-client/odbc/SOURCE.md
new file mode 100644
index 0000000000000..0aa0504a99ecd
--- /dev/null
+++ b/iotdb-client/odbc/SOURCE.md
@@ -0,0 +1,48 @@
+
+# Source provenance and dependencies
+
+ODBC source imported from `git@gitlab-eco.timecho.com:r-d/collector/iotdb-odbc-2.git`,
+local commit `21db94e` (Merge branch `feat/WindowsConfig` into `main`).
+This is a source snapshot, not a Git history merge. The original repository is
+retained. Remote freshness was not checked successfully because SSH authentication
+failed in the migration environment.
+
+The driver, Windows configuration resources and C++/Python examples were imported.
+Old installers, binaries, IDE caches, screenshots and obsolete build instructions
+were excluded. The REST dependencies retain their original vendored sources:
+curl's CMake library build subset and the JSON single header plus license.
+
+| Component | Version/source | Distribution |
+| --- | --- | --- |
+| C++ Session | same Apache IoTDB checkout | statically linked |
+| Thrift | version pinned by client-cpp (currently 0.24.0) | statically linked; Apache-2.0 |
+| OpenSSL | checksum-pinned client-cpp source (currently 3.5.8) | statically linked; Apache-2.0 |
+| Boost | client-cpp Thrift build headers | Boost Software License 1.0 |
+| curl | upstream ODBC vendored snapshot, reports 8.4.0-DEV | statically linked; curl license |
+| nlohmann/json | 3.11.3 | header-only; MIT |
+| GCC runtime (Linux) | release build toolchain | static; GCC Runtime Library Exception |
+
+The curl version label is inherited from the source snapshot; it is not a claim
+that this snapshot equals an upstream release. Third-party updates are separate
+from the migration. Licenses are shipped under `licenses/`; the repository
+LICENSE covers Apache-2.0 components. C++ SDK package descriptions refer to its
+standalone shared-library packaging; the table above describes ODBC packaging.
diff --git a/iotdb-client/odbc/VALIDATION.md b/iotdb-client/odbc/VALIDATION.md
new file mode 100644
index 0000000000000..f7d82681f7764
--- /dev/null
+++ b/iotdb-client/odbc/VALIDATION.md
@@ -0,0 +1,73 @@
+
+# Migration validation
+
+Local validation on 2026-09-16, source snapshot `21db94e`, against the in-tree
+C++ SDK. These are development validation results, not certification of every
+supported operating-system release or ODBC application.
+
+## Build and packaging
+
+| Check | Result |
+| --- | --- |
+| Linux x86_64, manylinux_2_28, GCC 14 | Release driver builds; both CTests pass |
+| Linux ABI | Highest required symbol version is GLIBC_2.28; no RPATH/RUNPATH |
+| Linux direct shared dependencies | libc, libm, libdl, libpthread, libodbcinst and the system ELF loader only |
+| Clean AlmaLinux 8, Ubuntu 22.04, Ubuntu 24.04 | Packaged driver loads through unixODBC and executes SHOW VERSION against a test server |
+| Windows x64, Visual Studio 2022 / MSVC 19.43 | Release driver builds; both CTests pass |
+| Windows dependencies | x64 DLL imports only Windows system libraries, not third-party DLLs or the VC redistributable |
+| Existing C++ SDK shared mode | Build, install, examples and session_utils_tests pass (260 assertions, 7 cases) |
+
+ODBC statically links Session, Thrift, OpenSSL and curl, plus the compiler runtime.
+Linux glibc and the platform ODBC manager/installer remain external. Package
+checks do not imply that arbitrary builds on newer Linux hosts meet this baseline.
+
+## Functional and encryption checks
+
+Linux and Windows x64 tests against a local Apache IoTDB 2.0.11-SNAPSHOT
+distribution passed:
+
+- Session plain, TLS and mutual TLS, through the system ODBC manager.
+- Tree and table models: create, insert, query and cleanup.
+- Three rows with fetch size two to exercise paging; Chinese text, NULL and DATE.
+- Retained HTTP REST path in both models.
+- Rejection of missing/untrusted CA, plaintext against a TLS endpoint,
+ missing/invalid client certificate, and a trusted server certificate whose
+ identity does not match the requested hostname.
+
+Unit tests additionally cover braced connection strings, TLS option validation,
+DSN overrides on Linux, diagnostic enumeration, UTF-16 conversion, pre-epoch
+timestamps, clearing stale connection diagnostics on retries and avoiding
+password disclosure in connection logs.
+
+## Limits and remaining release checks
+
+Live protocol checks used a local Apache IoTDB distribution. Rerun
+`test/run_e2e.py` against the intended release artifact before production
+acceptance.
+
+Interactive Windows DSN dialog operation and administrator installation/removal
+have not been manually exercised. Tests do not permanently register a driver.
+Windows 10 and Server 2016 were not separately available for runtime testing.
+GitHub Actions configuration was added but has not been run remotely.
+HTTPS for REST and a general ODBC conformance audit are outside this migration.
+The vendored curl snapshot is retained from the original repository; upgrading
+third-party dependencies should be a separate reviewed change.
diff --git a/iotdb-client/odbc/cmake/CheckLinuxPackage.cmake b/iotdb-client/odbc/cmake/CheckLinuxPackage.cmake
new file mode 100644
index 0000000000000..cbd06c990e530
--- /dev/null
+++ b/iotdb-client/odbc/cmake/CheckLinuxPackage.cmake
@@ -0,0 +1,53 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+if(NOT EXISTS "${DRIVER}")
+ message(FATAL_ERROR "Missing driver: ${DRIVER}")
+endif()
+if(NOT DEFINED GLIBC_BASELINE)
+ message(FATAL_ERROR "GLIBC_BASELINE must come from the shared native Linux release configuration")
+endif()
+find_program(READELF readelf REQUIRED)
+execute_process(COMMAND "${READELF}" --version-info "${DRIVER}"
+ OUTPUT_VARIABLE versions RESULT_VARIABLE rc)
+if(NOT rc EQUAL 0)
+ message(FATAL_ERROR "Cannot inspect ELF versions")
+endif()
+string(REGEX MATCHALL "GLIBC_[0-9]+\\.[0-9]+(\\.[0-9]+)?" requirements "${versions}")
+if(NOT requirements)
+ message(FATAL_ERROR "Cannot determine GLIBC requirements")
+endif()
+foreach(requirement IN LISTS requirements)
+ string(REPLACE "GLIBC_" "" version "${requirement}")
+ if(version VERSION_GREATER GLIBC_BASELINE)
+ message(FATAL_ERROR "${DRIVER} requires ${requirement}, baseline is ${GLIBC_BASELINE}")
+ endif()
+endforeach()
+execute_process(COMMAND "${READELF}" -d "${DRIVER}" OUTPUT_VARIABLE dynamic RESULT_VARIABLE rc)
+if(NOT rc EQUAL 0)
+ message(FATAL_ERROR "Cannot inspect ELF dependencies")
+endif()
+string(REGEX MATCHALL "Shared library: \\[[^]]+\\]" dependencies "${dynamic}")
+foreach(dependency IN LISTS dependencies)
+ string(REGEX REPLACE "Shared library: \\[([^]]+)\\]" "\\1" name "${dependency}")
+ if(NOT name MATCHES "^(lib(c|m|dl|pthread|rt)\\.so\\.[0-9]+|libodbcinst\\.so\\.2|ld-linux-x86-64\\.so\\.2)$")
+ message(FATAL_ERROR "Unexpected runtime dependency: ${name}")
+ endif()
+endforeach()
+if(dynamic MATCHES "(RPATH|RUNPATH)")
+ message(FATAL_ERROR "Release driver must not contain a build-time library search path")
+endif()
+message(STATUS "Single-library dependency check and GLIBC <= ${GLIBC_BASELINE} passed")
diff --git a/iotdb-client/odbc/conf/odbc.ini b/iotdb-client/odbc/conf/odbc.ini
new file mode 100644
index 0000000000000..dd7a3c6fcfffd
--- /dev/null
+++ b/iotdb-client/odbc/conf/odbc.ini
@@ -0,0 +1,29 @@
+; Licensed to the Apache Software Foundation (ASF) under one
+; or more contributor license agreements. See the NOTICE file
+; distributed with this work for additional information
+; regarding copyright ownership. The ASF licenses this file
+; to you under the Apache License, Version 2.0 (the
+; "License"); you may not use this file except in compliance
+; with the License. You may obtain a copy of the License at
+;
+; http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing,
+; software distributed under the License is distributed on an
+; "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+; KIND, either express or implied. See the License for the
+; specific language governing permissions and limitations
+; under the License.
+[IoTDB]
+Driver=Apache IoTDB ODBC Driver
+SERVER=127.0.0.1
+PORT=6667
+UID=root
+DATABASE=information_schema
+ISTABLEMODEL=1
+SSL=0
+; For TLS set SSL=1 and SSLCA to a trusted PEM CA file.
+; SSLCA=/etc/iotdb/ca.pem
+; For mutual TLS also set both of these PEM file paths:
+; SSLCERT=/etc/iotdb/client.pem
+; SSLKEY=/etc/iotdb/client.key
diff --git a/iotdb-client/odbc/conf/odbcinst.ini b/iotdb-client/odbc/conf/odbcinst.ini
new file mode 100644
index 0000000000000..a447be86d7ae3
--- /dev/null
+++ b/iotdb-client/odbc/conf/odbcinst.ini
@@ -0,0 +1,20 @@
+; Licensed to the Apache Software Foundation (ASF) under one
+; or more contributor license agreements. See the NOTICE file
+; distributed with this work for additional information
+; regarding copyright ownership. The ASF licenses this file
+; to you under the Apache License, Version 2.0 (the
+; "License"); you may not use this file except in compliance
+; with the License. You may obtain a copy of the License at
+;
+; http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing,
+; software distributed under the License is distributed on an
+; "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+; KIND, either express or implied. See the License for the
+; specific language governing permissions and limitations
+; under the License.
+[Apache IoTDB ODBC Driver]
+Description=Apache IoTDB ODBC Driver
+Driver=/opt/iotdb-odbc/lib/libapache_iotdb_odbc.so
+Threading=2
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/CMakeConfigurableFile.in b/iotdb-client/odbc/deps/curl-src/CMake/CMakeConfigurableFile.in
new file mode 100644
index 0000000000000..a3d2bc4a285f4
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/CMakeConfigurableFile.in
@@ -0,0 +1,24 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+@CMAKE_CONFIGURABLE_FILE_CONTENT@
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/CurlSymbolHiding.cmake b/iotdb-client/odbc/deps/curl-src/CMake/CurlSymbolHiding.cmake
new file mode 100644
index 0000000000000..8289b492468fb
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/CurlSymbolHiding.cmake
@@ -0,0 +1,84 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+include(CheckCSourceCompiles)
+
+option(CURL_HIDDEN_SYMBOLS "Set to ON to hide libcurl internal symbols (=hide all symbols that aren't officially external)." ON)
+mark_as_advanced(CURL_HIDDEN_SYMBOLS)
+
+if(WIN32 AND ENABLE_CURLDEBUG)
+ # We need to export internal debug functions (e.g. curl_dbg_*), so disable
+ # symbol hiding for debug builds.
+ set(CURL_HIDDEN_SYMBOLS OFF)
+endif()
+
+if(CURL_HIDDEN_SYMBOLS)
+ set(SUPPORTS_SYMBOL_HIDING FALSE)
+
+ if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT MSVC)
+ set(SUPPORTS_SYMBOL_HIDING TRUE)
+ set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
+ set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
+ elseif(CMAKE_COMPILER_IS_GNUCC)
+ if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
+ # note: this is considered buggy prior to 4.0 but the autotools don't care, so let's ignore that fact
+ set(SUPPORTS_SYMBOL_HIDING TRUE)
+ set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
+ set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
+ endif()
+ elseif(CMAKE_C_COMPILER_ID MATCHES "SunPro" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0)
+ set(SUPPORTS_SYMBOL_HIDING TRUE)
+ set(_SYMBOL_EXTERN "__global")
+ set(_CFLAG_SYMBOLS_HIDE "-xldscope=hidden")
+ elseif(CMAKE_C_COMPILER_ID MATCHES "Intel" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.0)
+ # note: this should probably just check for version 9.1.045 but I'm not 100% sure
+ # so let's do it the same way autotools do.
+ set(SUPPORTS_SYMBOL_HIDING TRUE)
+ set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
+ set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
+ check_c_source_compiles("#include
+ int main (void) { printf(\"icc fvisibility bug test\"); return 0; }" _no_bug)
+ if(NOT _no_bug)
+ set(SUPPORTS_SYMBOL_HIDING FALSE)
+ set(_SYMBOL_EXTERN "")
+ set(_CFLAG_SYMBOLS_HIDE "")
+ endif()
+ elseif(MSVC)
+ set(SUPPORTS_SYMBOL_HIDING TRUE)
+ endif()
+
+ set(HIDES_CURL_PRIVATE_SYMBOLS ${SUPPORTS_SYMBOL_HIDING})
+elseif(MSVC)
+ if(NOT CMAKE_VERSION VERSION_LESS 3.7)
+ set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) #present since 3.4.3 but broken
+ set(HIDES_CURL_PRIVATE_SYMBOLS FALSE)
+ else()
+ message(WARNING "Hiding private symbols regardless CURL_HIDDEN_SYMBOLS being disabled.")
+ set(HIDES_CURL_PRIVATE_SYMBOLS TRUE)
+ endif()
+else()
+ set(HIDES_CURL_PRIVATE_SYMBOLS FALSE)
+endif()
+
+set(CURL_CFLAG_SYMBOLS_HIDE ${_CFLAG_SYMBOLS_HIDE})
+set(CURL_EXTERN_SYMBOL ${_SYMBOL_EXTERN})
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/CurlTests.c b/iotdb-client/odbc/deps/curl-src/CMake/CurlTests.c
new file mode 100644
index 0000000000000..ea80ec89ab9fd
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/CurlTests.c
@@ -0,0 +1,515 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#ifdef HAVE_FCNTL_O_NONBLOCK
+
+/* headers for FCNTL_O_NONBLOCK test */
+#include
+#include
+#include
+/* */
+#if defined(sun) || defined(__sun__) || \
+ defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+# if defined(__SVR4) || defined(__srv4__)
+# define PLATFORM_SOLARIS
+# else
+# define PLATFORM_SUNOS4
+# endif
+#endif
+#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX41)
+# define PLATFORM_AIX_V3
+#endif
+/* */
+#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3)
+#error "O_NONBLOCK does not work on this platform"
+#endif
+
+int
+main ()
+{
+ /* O_NONBLOCK source test */
+ int flags = 0;
+ if(0 != fcntl(0, F_SETFL, flags | O_NONBLOCK))
+ return 1;
+ return 0;
+}
+#endif
+
+/* tests for gethostbyname_r */
+#if defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT) || \
+ defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) || \
+ defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
+# define _REENTRANT
+ /* no idea whether _REENTRANT is always set, just invent a new flag */
+# define TEST_GETHOSTBYFOO_REENTRANT
+#endif
+#if defined(HAVE_GETHOSTBYNAME_R_3) || \
+ defined(HAVE_GETHOSTBYNAME_R_5) || \
+ defined(HAVE_GETHOSTBYNAME_R_6) || \
+ defined(TEST_GETHOSTBYFOO_REENTRANT)
+#include
+#include
+int main(void)
+{
+ char *address = "example.com";
+ int length = 0;
+ int type = 0;
+ struct hostent h;
+ int rc = 0;
+#if defined(HAVE_GETHOSTBYNAME_R_3) || \
+ defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT)
+ struct hostent_data hdata;
+#elif defined(HAVE_GETHOSTBYNAME_R_5) || \
+ defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) || \
+ defined(HAVE_GETHOSTBYNAME_R_6) || \
+ defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
+ char buffer[8192];
+ int h_errnop;
+ struct hostent *hp;
+#endif
+
+#if defined(HAVE_GETHOSTBYNAME_R_3) || \
+ defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT)
+ rc = gethostbyname_r(address, &h, &hdata);
+#elif defined(HAVE_GETHOSTBYNAME_R_5) || \
+ defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT)
+ rc = gethostbyname_r(address, &h, buffer, 8192, &h_errnop);
+ (void)hp; /* not used for test */
+#elif defined(HAVE_GETHOSTBYNAME_R_6) || \
+ defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
+ rc = gethostbyname_r(address, &h, buffer, 8192, &hp, &h_errnop);
+#endif
+
+ (void)length;
+ (void)type;
+ (void)rc;
+ return 0;
+}
+#endif
+
+#ifdef HAVE_SOCKLEN_T
+#ifdef _WIN32
+#include
+#else
+#include
+#include
+#endif
+int
+main ()
+{
+if ((socklen_t *) 0)
+ return 0;
+if (sizeof (socklen_t))
+ return 0;
+ ;
+ return 0;
+}
+#endif
+#ifdef HAVE_IN_ADDR_T
+#include
+#include
+#include
+
+int
+main ()
+{
+if ((in_addr_t *) 0)
+ return 0;
+if (sizeof (in_addr_t))
+ return 0;
+ ;
+ return 0;
+}
+#endif
+
+#ifdef HAVE_BOOL_T
+#ifdef HAVE_SYS_TYPES_H
+#include
+#endif
+#ifdef HAVE_STDBOOL_H
+#include
+#endif
+int
+main ()
+{
+if (sizeof (bool *) )
+ return 0;
+ ;
+ return 0;
+}
+#endif
+
+#ifdef STDC_HEADERS
+#include
+#include
+#include
+#include
+int main() { return 0; }
+#endif
+#ifdef HAVE_FILE_OFFSET_BITS
+#ifdef _FILE_OFFSET_BITS
+#undef _FILE_OFFSET_BITS
+#endif
+#define _FILE_OFFSET_BITS 64
+#include
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int main () { ; return 0; }
+#endif
+#ifdef HAVE_IOCTLSOCKET
+/* includes start */
+#ifdef HAVE_WINDOWS_H
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include
+# ifdef HAVE_WINSOCK2_H
+# include
+# endif
+#endif
+
+int
+main ()
+{
+
+/* ioctlsocket source code */
+ int socket;
+ unsigned long flags = ioctlsocket(socket, FIONBIO, &flags);
+
+ ;
+ return 0;
+}
+
+#endif
+#ifdef HAVE_IOCTLSOCKET_CAMEL
+/* includes start */
+#ifdef HAVE_WINDOWS_H
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include
+# ifdef HAVE_WINSOCK2_H
+# include
+# endif
+#endif
+
+int
+main ()
+{
+
+/* IoctlSocket source code */
+ if(0 != IoctlSocket(0, 0, 0))
+ return 1;
+ ;
+ return 0;
+}
+#endif
+#ifdef HAVE_IOCTLSOCKET_CAMEL_FIONBIO
+/* includes start */
+#ifdef HAVE_WINDOWS_H
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include
+# ifdef HAVE_WINSOCK2_H
+# include
+# endif
+#endif
+
+int
+main ()
+{
+
+/* IoctlSocket source code */
+ long flags = 0;
+ if(0 != IoctlSocket(0, FIONBIO, &flags))
+ return 1;
+ ;
+ return 0;
+}
+#endif
+#ifdef HAVE_IOCTLSOCKET_FIONBIO
+/* includes start */
+#ifdef HAVE_WINDOWS_H
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include
+# ifdef HAVE_WINSOCK2_H
+# include
+# endif
+#endif
+
+int
+main ()
+{
+
+ int flags = 0;
+ if(0 != ioctlsocket(0, FIONBIO, &flags))
+ return 1;
+
+ ;
+ return 0;
+}
+#endif
+#ifdef HAVE_IOCTL_FIONBIO
+/* headers for FIONBIO test */
+/* includes start */
+#ifdef HAVE_SYS_TYPES_H
+# include
+#endif
+#ifdef HAVE_UNISTD_H
+# include
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+# include
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include
+#endif
+#ifdef HAVE_STROPTS_H
+# include
+#endif
+
+int
+main ()
+{
+
+ int flags = 0;
+ if(0 != ioctl(0, FIONBIO, &flags))
+ return 1;
+
+ ;
+ return 0;
+}
+#endif
+#ifdef HAVE_IOCTL_SIOCGIFADDR
+/* headers for FIONBIO test */
+/* includes start */
+#ifdef HAVE_SYS_TYPES_H
+# include
+#endif
+#ifdef HAVE_UNISTD_H
+# include
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+# include
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include
+#endif
+#ifdef HAVE_STROPTS_H
+# include
+#endif
+#include
+
+int
+main ()
+{
+ struct ifreq ifr;
+ if(0 != ioctl(0, SIOCGIFADDR, &ifr))
+ return 1;
+
+ ;
+ return 0;
+}
+#endif
+#ifdef HAVE_SETSOCKOPT_SO_NONBLOCK
+/* includes start */
+#ifdef HAVE_WINDOWS_H
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include
+# ifdef HAVE_WINSOCK2_H
+# include
+# endif
+#endif
+/* includes start */
+#ifdef HAVE_SYS_TYPES_H
+# include
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+# include
+#endif
+/* includes end */
+
+int
+main ()
+{
+ if(0 != setsockopt(0, SOL_SOCKET, SO_NONBLOCK, 0, 0))
+ return 1;
+ ;
+ return 0;
+}
+#endif
+#ifdef HAVE_GLIBC_STRERROR_R
+#include
+#include
+
+void check(char c) {}
+
+int
+main () {
+ char buffer[1024];
+ /* This will not compile if strerror_r does not return a char* */
+ check(strerror_r(EACCES, buffer, sizeof(buffer))[0]);
+ return 0;
+}
+#endif
+#ifdef HAVE_POSIX_STRERROR_R
+#include
+#include
+
+/* float, because a pointer can't be implicitly cast to float */
+void check(float f) {}
+
+int
+main () {
+ char buffer[1024];
+ /* This will not compile if strerror_r does not return an int */
+ check(strerror_r(EACCES, buffer, sizeof(buffer)));
+ return 0;
+}
+#endif
+#ifdef HAVE_FSETXATTR_6
+#include /* header from libc, not from libattr */
+int
+main() {
+ fsetxattr(0, 0, 0, 0, 0, 0);
+ return 0;
+}
+#endif
+#ifdef HAVE_FSETXATTR_5
+#include /* header from libc, not from libattr */
+int
+main() {
+ fsetxattr(0, 0, 0, 0, 0);
+ return 0;
+}
+#endif
+#ifdef HAVE_CLOCK_GETTIME_MONOTONIC
+#include
+int
+main() {
+ struct timespec ts = {0, 0};
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return 0;
+}
+#endif
+#ifdef HAVE_BUILTIN_AVAILABLE
+int
+main() {
+ if(__builtin_available(macOS 10.12, *)) {}
+ return 0;
+}
+#endif
+#ifdef HAVE_VARIADIC_MACROS_C99
+#define c99_vmacro3(first, ...) fun3(first, __VA_ARGS__)
+#define c99_vmacro2(first, ...) fun2(first, __VA_ARGS__)
+
+int fun3(int arg1, int arg2, int arg3);
+int fun2(int arg1, int arg2);
+
+int fun3(int arg1, int arg2, int arg3) {
+ return arg1 + arg2 + arg3;
+}
+int fun2(int arg1, int arg2) {
+ return arg1 + arg2;
+}
+
+int
+main() {
+ int res3 = c99_vmacro3(1, 2, 3);
+ int res2 = c99_vmacro2(1, 2);
+ (void)res3;
+ (void)res2;
+ return 0;
+}
+#endif
+#ifdef HAVE_VARIADIC_MACROS_GCC
+#define gcc_vmacro3(first, args...) fun3(first, args)
+#define gcc_vmacro2(first, args...) fun2(first, args)
+
+int fun3(int arg1, int arg2, int arg3);
+int fun2(int arg1, int arg2);
+
+int fun3(int arg1, int arg2, int arg3) {
+ return arg1 + arg2 + arg3;
+}
+int fun2(int arg1, int arg2) {
+ return arg1 + arg2;
+}
+
+int
+main() {
+ int res3 = gcc_vmacro3(1, 2, 3);
+ int res2 = gcc_vmacro2(1, 2);
+ (void)res3;
+ (void)res2;
+ return 0;
+}
+#endif
+#ifdef HAVE_ATOMIC
+/* includes start */
+#ifdef HAVE_SYS_TYPES_H
+# include
+#endif
+#ifdef HAVE_UNISTD_H
+# include
+#endif
+#ifdef HAVE_STDATOMIC_H
+# include
+#endif
+/* includes end */
+
+int
+main() {
+ _Atomic int i = 1;
+ i = 0; /* Force an atomic-write operation. */
+ return i;
+}
+#endif
+#ifdef HAVE_WIN32_WINNT
+/* includes start */
+#ifdef WIN32
+# include "../lib/setup-win32.h"
+#endif
+/* includes end */
+
+#define enquote(x) #x
+#define expand(x) enquote(x)
+#pragma message("_WIN32_WINNT=" expand(_WIN32_WINNT))
+
+int
+main() {
+ return 0;
+}
+#endif
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/FindBearSSL.cmake b/iotdb-client/odbc/deps/curl-src/CMake/FindBearSSL.cmake
new file mode 100644
index 0000000000000..56a064eacd739
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/FindBearSSL.cmake
@@ -0,0 +1,32 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+find_path(BEARSSL_INCLUDE_DIRS bearssl.h)
+
+find_library(BEARSSL_LIBRARY bearssl)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(BEARSSL DEFAULT_MSG
+ BEARSSL_INCLUDE_DIRS BEARSSL_LIBRARY)
+
+mark_as_advanced(BEARSSL_INCLUDE_DIRS BEARSSL_LIBRARY)
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/FindBrotli.cmake b/iotdb-client/odbc/deps/curl-src/CMake/FindBrotli.cmake
new file mode 100644
index 0000000000000..11ab7f8254551
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/FindBrotli.cmake
@@ -0,0 +1,43 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+include(FindPackageHandleStandardArgs)
+
+find_path(BROTLI_INCLUDE_DIR "brotli/decode.h")
+
+find_library(BROTLICOMMON_LIBRARY NAMES brotlicommon)
+find_library(BROTLIDEC_LIBRARY NAMES brotlidec)
+
+find_package_handle_standard_args(Brotli
+ FOUND_VAR
+ BROTLI_FOUND
+ REQUIRED_VARS
+ BROTLIDEC_LIBRARY
+ BROTLICOMMON_LIBRARY
+ BROTLI_INCLUDE_DIR
+ FAIL_MESSAGE
+ "Could NOT find Brotli"
+)
+
+set(BROTLI_INCLUDE_DIRS ${BROTLI_INCLUDE_DIR})
+set(BROTLI_LIBRARIES ${BROTLICOMMON_LIBRARY} ${BROTLIDEC_LIBRARY})
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/FindCARES.cmake b/iotdb-client/odbc/deps/curl-src/CMake/FindCARES.cmake
new file mode 100644
index 0000000000000..fa75891189888
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/FindCARES.cmake
@@ -0,0 +1,47 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+# - Find c-ares
+# Find the c-ares includes and library
+# This module defines
+# CARES_INCLUDE_DIR, where to find ares.h, etc.
+# CARES_LIBRARIES, the libraries needed to use c-ares.
+# CARES_FOUND, If false, do not try to use c-ares.
+# also defined, but not for general use are
+# CARES_LIBRARY, where to find the c-ares library.
+
+find_path(CARES_INCLUDE_DIR ares.h)
+
+set(CARES_NAMES ${CARES_NAMES} cares)
+find_library(CARES_LIBRARY
+ NAMES ${CARES_NAMES}
+ )
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(CARES
+ REQUIRED_VARS CARES_LIBRARY CARES_INCLUDE_DIR)
+
+mark_as_advanced(
+ CARES_LIBRARY
+ CARES_INCLUDE_DIR
+ )
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/FindGSS.cmake b/iotdb-client/odbc/deps/curl-src/CMake/FindGSS.cmake
new file mode 100644
index 0000000000000..b244e610ec611
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/FindGSS.cmake
@@ -0,0 +1,312 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+# - Try to find the GSS Kerberos library
+# Once done this will define
+#
+# GSS_ROOT_DIR - Set this variable to the root installation of GSS
+#
+# Read-Only variables:
+# GSS_FOUND - system has the Heimdal library
+# GSS_FLAVOUR - "MIT" or "Heimdal" if anything found.
+# GSS_INCLUDE_DIR - the Heimdal include directory
+# GSS_LIBRARIES - The libraries needed to use GSS
+# GSS_LINK_DIRECTORIES - Directories to add to linker search path
+# GSS_LINKER_FLAGS - Additional linker flags
+# GSS_COMPILER_FLAGS - Additional compiler flags
+# GSS_VERSION - This is set to version advertised by pkg-config or read from manifest.
+# In case the library is found but no version info available it'll be set to "unknown"
+
+set(_MIT_MODNAME mit-krb5-gssapi)
+set(_HEIMDAL_MODNAME heimdal-gssapi)
+
+include(CheckIncludeFile)
+include(CheckIncludeFiles)
+include(CheckTypeSize)
+
+set(_GSS_ROOT_HINTS
+ "${GSS_ROOT_DIR}"
+ "$ENV{GSS_ROOT_DIR}"
+)
+
+# try to find library using system pkg-config if user didn't specify root dir
+if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}")
+ if(UNIX)
+ find_package(PkgConfig QUIET)
+ pkg_search_module(_GSS_PKG ${_MIT_MODNAME} ${_HEIMDAL_MODNAME})
+ list(APPEND _GSS_ROOT_HINTS "${_GSS_PKG_PREFIX}")
+ elseif(WIN32)
+ list(APPEND _GSS_ROOT_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]")
+ endif()
+endif()
+
+if(NOT _GSS_FOUND) #not found by pkg-config. Let's take more traditional approach.
+ find_file(_GSS_CONFIGURE_SCRIPT
+ NAMES
+ "krb5-config"
+ HINTS
+ ${_GSS_ROOT_HINTS}
+ PATH_SUFFIXES
+ bin
+ NO_CMAKE_PATH
+ NO_CMAKE_ENVIRONMENT_PATH
+ )
+
+ # if not found in user-supplied directories, maybe system knows better
+ find_file(_GSS_CONFIGURE_SCRIPT
+ NAMES
+ "krb5-config"
+ PATH_SUFFIXES
+ bin
+ )
+
+ if(_GSS_CONFIGURE_SCRIPT)
+ execute_process(
+ COMMAND ${_GSS_CONFIGURE_SCRIPT} "--cflags" "gssapi"
+ OUTPUT_VARIABLE _GSS_CFLAGS
+ RESULT_VARIABLE _GSS_CONFIGURE_FAILED
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ message(STATUS "CFLAGS: ${_GSS_CFLAGS}")
+ if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
+ # should also work in an odd case when multiple directories are given
+ string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS)
+ string(REGEX REPLACE " +-I" ";" _GSS_CFLAGS "${_GSS_CFLAGS}")
+ string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1" _GSS_CFLAGS "${_GSS_CFLAGS}")
+
+ foreach(_flag ${_GSS_CFLAGS})
+ if(_flag MATCHES "^-I.*")
+ string(REGEX REPLACE "^-I" "" _val "${_flag}")
+ list(APPEND _GSS_INCLUDE_DIR "${_val}")
+ else()
+ list(APPEND _GSS_COMPILER_FLAGS "${_flag}")
+ endif()
+ endforeach()
+ endif()
+
+ execute_process(
+ COMMAND ${_GSS_CONFIGURE_SCRIPT} "--libs" "gssapi"
+ OUTPUT_VARIABLE _GSS_LIB_FLAGS
+ RESULT_VARIABLE _GSS_CONFIGURE_FAILED
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ message(STATUS "LDFLAGS: ${_GSS_LIB_FLAGS}")
+
+ if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
+ # this script gives us libraries and link directories. Blah. We have to deal with it.
+ string(STRIP "${_GSS_LIB_FLAGS}" _GSS_LIB_FLAGS)
+ string(REGEX REPLACE " +-(L|l)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
+ string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
+
+ foreach(_flag ${_GSS_LIB_FLAGS})
+ if(_flag MATCHES "^-l.*")
+ string(REGEX REPLACE "^-l" "" _val "${_flag}")
+ list(APPEND _GSS_LIBRARIES "${_val}")
+ elseif(_flag MATCHES "^-L.*")
+ string(REGEX REPLACE "^-L" "" _val "${_flag}")
+ list(APPEND _GSS_LINK_DIRECTORIES "${_val}")
+ else()
+ list(APPEND _GSS_LINKER_FLAGS "${_flag}")
+ endif()
+ endforeach()
+ endif()
+
+ execute_process(
+ COMMAND ${_GSS_CONFIGURE_SCRIPT} "--version"
+ OUTPUT_VARIABLE _GSS_VERSION
+ RESULT_VARIABLE _GSS_CONFIGURE_FAILED
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ # older versions may not have the "--version" parameter. In this case we just don't care.
+ if(_GSS_CONFIGURE_FAILED)
+ set(_GSS_VERSION 0)
+ endif()
+
+ execute_process(
+ COMMAND ${_GSS_CONFIGURE_SCRIPT} "--vendor"
+ OUTPUT_VARIABLE _GSS_VENDOR
+ RESULT_VARIABLE _GSS_CONFIGURE_FAILED
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ # older versions may not have the "--vendor" parameter. In this case we just don't care.
+ if(_GSS_CONFIGURE_FAILED)
+ set(GSS_FLAVOUR "Heimdal") # most probably, shouldn't really matter
+ else()
+ if(_GSS_VENDOR MATCHES ".*H|heimdal.*")
+ set(GSS_FLAVOUR "Heimdal")
+ else()
+ set(GSS_FLAVOUR "MIT")
+ endif()
+ endif()
+
+ else() # either there is no config script or we are on a platform that doesn't provide one (Windows?)
+
+ find_path(_GSS_INCLUDE_DIR
+ NAMES
+ "gssapi/gssapi.h"
+ HINTS
+ ${_GSS_ROOT_HINTS}
+ PATH_SUFFIXES
+ include
+ inc
+ )
+
+ if(_GSS_INCLUDE_DIR) #jay, we've found something
+ set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIR}")
+ check_include_files( "gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _GSS_HAVE_MIT_HEADERS)
+
+ if(_GSS_HAVE_MIT_HEADERS)
+ set(GSS_FLAVOUR "MIT")
+ else()
+ # prevent compiling the header - just check if we can include it
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS -D__ROKEN_H__)
+ check_include_file( "roken.h" _GSS_HAVE_ROKEN_H)
+
+ check_include_file( "heimdal/roken.h" _GSS_HAVE_HEIMDAL_ROKEN_H)
+ if(_GSS_HAVE_ROKEN_H OR _GSS_HAVE_HEIMDAL_ROKEN_H)
+ set(GSS_FLAVOUR "Heimdal")
+ endif()
+ list(REMOVE_ITEM CMAKE_REQUIRED_DEFINITIONS -D__ROKEN_H__)
+ endif()
+ else()
+ # I'm not convinced if this is the right way but this is what autotools do at the moment
+ find_path(_GSS_INCLUDE_DIR
+ NAMES
+ "gssapi.h"
+ HINTS
+ ${_GSS_ROOT_HINTS}
+ PATH_SUFFIXES
+ include
+ inc
+ )
+
+ if(_GSS_INCLUDE_DIR)
+ set(GSS_FLAVOUR "Heimdal")
+ endif()
+ endif()
+
+ # if we have headers, check if we can link libraries
+ if(GSS_FLAVOUR)
+ set(_GSS_LIBDIR_SUFFIXES "")
+ set(_GSS_LIBDIR_HINTS ${_GSS_ROOT_HINTS})
+ get_filename_component(_GSS_CALCULATED_POTENTIAL_ROOT "${_GSS_INCLUDE_DIR}" PATH)
+ list(APPEND _GSS_LIBDIR_HINTS ${_GSS_CALCULATED_POTENTIAL_ROOT})
+
+ if(WIN32)
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ list(APPEND _GSS_LIBDIR_SUFFIXES "lib/AMD64")
+ if(GSS_FLAVOUR STREQUAL "MIT")
+ set(_GSS_LIBNAME "gssapi64")
+ else()
+ set(_GSS_LIBNAME "libgssapi")
+ endif()
+ else()
+ list(APPEND _GSS_LIBDIR_SUFFIXES "lib/i386")
+ if(GSS_FLAVOUR STREQUAL "MIT")
+ set(_GSS_LIBNAME "gssapi32")
+ else()
+ set(_GSS_LIBNAME "libgssapi")
+ endif()
+ endif()
+ else()
+ list(APPEND _GSS_LIBDIR_SUFFIXES "lib;lib64") # those suffixes are not checked for HINTS
+ if(GSS_FLAVOUR STREQUAL "MIT")
+ set(_GSS_LIBNAME "gssapi_krb5")
+ else()
+ set(_GSS_LIBNAME "gssapi")
+ endif()
+ endif()
+
+ find_library(_GSS_LIBRARIES
+ NAMES
+ ${_GSS_LIBNAME}
+ HINTS
+ ${_GSS_LIBDIR_HINTS}
+ PATH_SUFFIXES
+ ${_GSS_LIBDIR_SUFFIXES}
+ )
+
+ endif()
+ endif()
+else()
+ if(_GSS_PKG_${_MIT_MODNAME}_VERSION)
+ set(GSS_FLAVOUR "MIT")
+ set(_GSS_VERSION _GSS_PKG_${_MIT_MODNAME}_VERSION)
+ else()
+ set(GSS_FLAVOUR "Heimdal")
+ set(_GSS_VERSION _GSS_PKG_${_MIT_HEIMDAL}_VERSION)
+ endif()
+endif()
+
+set(GSS_INCLUDE_DIR ${_GSS_INCLUDE_DIR})
+set(GSS_LIBRARIES ${_GSS_LIBRARIES})
+set(GSS_LINK_DIRECTORIES ${_GSS_LINK_DIRECTORIES})
+set(GSS_LINKER_FLAGS ${_GSS_LINKER_FLAGS})
+set(GSS_COMPILER_FLAGS ${_GSS_COMPILER_FLAGS})
+set(GSS_VERSION ${_GSS_VERSION})
+
+if(GSS_FLAVOUR)
+ if(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "Heimdal")
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.amd64.manifest")
+ else()
+ set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.x86.manifest")
+ endif()
+
+ if(EXISTS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}")
+ file(STRINGS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}" heimdal_version_str
+ REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$")
+
+ string(REGEX MATCH "[0-9]\\.[^\"]+"
+ GSS_VERSION "${heimdal_version_str}")
+ endif()
+
+ if(NOT GSS_VERSION)
+ set(GSS_VERSION "Heimdal Unknown")
+ endif()
+ elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "MIT")
+ get_filename_component(_MIT_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME CACHE)
+ if(WIN32 AND _MIT_VERSION)
+ set(GSS_VERSION "${_MIT_VERSION}")
+ else()
+ set(GSS_VERSION "MIT Unknown")
+ endif()
+ endif()
+endif()
+
+include(FindPackageHandleStandardArgs)
+
+set(_GSS_REQUIRED_VARS GSS_LIBRARIES GSS_FLAVOUR)
+
+find_package_handle_standard_args(GSS
+ REQUIRED_VARS
+ ${_GSS_REQUIRED_VARS}
+ VERSION_VAR
+ GSS_VERSION
+ FAIL_MESSAGE
+ "Could NOT find GSS, try to set the path to GSS root folder in the system variable GSS_ROOT_DIR"
+)
+
+mark_as_advanced(GSS_INCLUDE_DIR GSS_LIBRARIES)
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/FindLibPSL.cmake b/iotdb-client/odbc/deps/curl-src/CMake/FindLibPSL.cmake
new file mode 100644
index 0000000000000..e3bd68d1d77e8
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/FindLibPSL.cmake
@@ -0,0 +1,45 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+# - Try to find the libpsl library
+# Once done this will define
+#
+# LIBPSL_FOUND - system has the libpsl library
+# LIBPSL_INCLUDE_DIR - the libpsl include directory
+# LIBPSL_LIBRARY - the libpsl library name
+
+find_path(LIBPSL_INCLUDE_DIR libpsl.h)
+
+find_library(LIBPSL_LIBRARY NAMES psl libpsl)
+
+if(LIBPSL_INCLUDE_DIR)
+ file(STRINGS "${LIBPSL_INCLUDE_DIR}/libpsl.h" libpsl_version_str REGEX "^#define[\t ]+PSL_VERSION[\t ]+\"(.*)\"")
+ string(REGEX REPLACE "^.*\"([^\"]+)\"" "\\1" LIBPSL_VERSION "${libpsl_version_str}")
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LibPSL
+ REQUIRED_VARS LIBPSL_LIBRARY LIBPSL_INCLUDE_DIR
+ VERSION_VAR LIBPSL_VERSION)
+
+mark_as_advanced(LIBPSL_INCLUDE_DIR LIBPSL_LIBRARY)
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/FindLibSSH2.cmake b/iotdb-client/odbc/deps/curl-src/CMake/FindLibSSH2.cmake
new file mode 100644
index 0000000000000..a0c251ae39523
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/FindLibSSH2.cmake
@@ -0,0 +1,45 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+# - Try to find the libssh2 library
+# Once done this will define
+#
+# LIBSSH2_FOUND - system has the libssh2 library
+# LIBSSH2_INCLUDE_DIR - the libssh2 include directory
+# LIBSSH2_LIBRARY - the libssh2 library name
+
+find_path(LIBSSH2_INCLUDE_DIR libssh2.h)
+
+find_library(LIBSSH2_LIBRARY NAMES ssh2 libssh2)
+
+if(LIBSSH2_INCLUDE_DIR)
+ file(STRINGS "${LIBSSH2_INCLUDE_DIR}/libssh2.h" libssh2_version_str REGEX "^#define[\t ]+LIBSSH2_VERSION[\t ]+\"(.*)\"")
+ string(REGEX REPLACE "^.*\"([^\"]+)\"" "\\1" LIBSSH2_VERSION "${libssh2_version_str}")
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LibSSH2
+ REQUIRED_VARS LIBSSH2_LIBRARY LIBSSH2_INCLUDE_DIR
+ VERSION_VAR LIBSSH2_VERSION)
+
+mark_as_advanced(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY)
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/FindMSH3.cmake b/iotdb-client/odbc/deps/curl-src/CMake/FindMSH3.cmake
new file mode 100644
index 0000000000000..7d9c6b6544f5d
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/FindMSH3.cmake
@@ -0,0 +1,70 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+
+#[=======================================================================[.rst:
+FindMSH3
+----------
+
+Find the msh3 library
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+``MSH3_FOUND``
+ System has msh3
+``MSH3_INCLUDE_DIRS``
+ The msh3 include directories.
+``MSH3_LIBRARIES``
+ The libraries needed to use msh3
+#]=======================================================================]
+if(UNIX)
+ find_package(PkgConfig QUIET)
+ pkg_search_module(PC_MSH3 libmsh3)
+endif()
+
+find_path(MSH3_INCLUDE_DIR msh3.h
+ HINTS
+ ${PC_MSH3_INCLUDEDIR}
+ ${PC_MSH3_INCLUDE_DIRS}
+)
+
+find_library(MSH3_LIBRARY NAMES msh3
+ HINTS
+ ${PC_MSH3_LIBDIR}
+ ${PC_MSH3_LIBRARY_DIRS}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(MSH3
+ REQUIRED_VARS
+ MSH3_LIBRARY
+ MSH3_INCLUDE_DIR
+)
+
+if(MSH3_FOUND)
+ set(MSH3_LIBRARIES ${MSH3_LIBRARY})
+ set(MSH3_INCLUDE_DIRS ${MSH3_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(MSH3_INCLUDE_DIRS MSH3_LIBRARIES)
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/FindMbedTLS.cmake b/iotdb-client/odbc/deps/curl-src/CMake/FindMbedTLS.cmake
new file mode 100644
index 0000000000000..814bd97da144d
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/FindMbedTLS.cmake
@@ -0,0 +1,36 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+find_path(MBEDTLS_INCLUDE_DIRS mbedtls/ssl.h)
+
+find_library(MBEDTLS_LIBRARY mbedtls)
+find_library(MBEDX509_LIBRARY mbedx509)
+find_library(MBEDCRYPTO_LIBRARY mbedcrypto)
+
+set(MBEDTLS_LIBRARIES "${MBEDTLS_LIBRARY}" "${MBEDX509_LIBRARY}" "${MBEDCRYPTO_LIBRARY}")
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(MbedTLS DEFAULT_MSG
+ MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
+
+mark_as_advanced(MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/FindNGHTTP2.cmake b/iotdb-client/odbc/deps/curl-src/CMake/FindNGHTTP2.cmake
new file mode 100644
index 0000000000000..3957646c43919
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/FindNGHTTP2.cmake
@@ -0,0 +1,41 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+include(FindPackageHandleStandardArgs)
+
+find_path(NGHTTP2_INCLUDE_DIR "nghttp2/nghttp2.h")
+
+find_library(NGHTTP2_LIBRARY NAMES nghttp2)
+
+find_package_handle_standard_args(NGHTTP2
+ FOUND_VAR
+ NGHTTP2_FOUND
+ REQUIRED_VARS
+ NGHTTP2_LIBRARY
+ NGHTTP2_INCLUDE_DIR
+)
+
+set(NGHTTP2_INCLUDE_DIRS ${NGHTTP2_INCLUDE_DIR})
+set(NGHTTP2_LIBRARIES ${NGHTTP2_LIBRARY})
+
+mark_as_advanced(NGHTTP2_INCLUDE_DIRS NGHTTP2_LIBRARIES)
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/FindNGHTTP3.cmake b/iotdb-client/odbc/deps/curl-src/CMake/FindNGHTTP3.cmake
new file mode 100644
index 0000000000000..9b13e6c6ffeb7
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/FindNGHTTP3.cmake
@@ -0,0 +1,78 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+
+#[=======================================================================[.rst:
+FindNGHTTP3
+----------
+
+Find the nghttp3 library
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+``NGHTTP3_FOUND``
+ System has nghttp3
+``NGHTTP3_INCLUDE_DIRS``
+ The nghttp3 include directories.
+``NGHTTP3_LIBRARIES``
+ The libraries needed to use nghttp3
+``NGHTTP3_VERSION``
+ version of nghttp3.
+#]=======================================================================]
+
+if(UNIX)
+ find_package(PkgConfig QUIET)
+ pkg_search_module(PC_NGHTTP3 libnghttp3)
+endif()
+
+find_path(NGHTTP3_INCLUDE_DIR nghttp3/nghttp3.h
+ HINTS
+ ${PC_NGHTTP3_INCLUDEDIR}
+ ${PC_NGHTTP3_INCLUDE_DIRS}
+)
+
+find_library(NGHTTP3_LIBRARY NAMES nghttp3
+ HINTS
+ ${PC_NGHTTP3_LIBDIR}
+ ${PC_NGHTTP3_LIBRARY_DIRS}
+)
+
+if(PC_NGHTTP3_VERSION)
+ set(NGHTTP3_VERSION ${PC_NGHTTP3_VERSION})
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(NGHTTP3
+ REQUIRED_VARS
+ NGHTTP3_LIBRARY
+ NGHTTP3_INCLUDE_DIR
+ VERSION_VAR NGHTTP3_VERSION
+)
+
+if(NGHTTP3_FOUND)
+ set(NGHTTP3_LIBRARIES ${NGHTTP3_LIBRARY})
+ set(NGHTTP3_INCLUDE_DIRS ${NGHTTP3_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(NGHTTP3_INCLUDE_DIRS NGHTTP3_LIBRARIES)
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/FindNGTCP2.cmake b/iotdb-client/odbc/deps/curl-src/CMake/FindNGTCP2.cmake
new file mode 100644
index 0000000000000..7ea466582a9e1
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/FindNGTCP2.cmake
@@ -0,0 +1,117 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+
+#[=======================================================================[.rst:
+FindNGTCP2
+----------
+
+Find the ngtcp2 library
+
+This module accepts optional COMPONENTS to control the crypto library (these are
+mutually exclusive)::
+
+ quictls, LibreSSL: Use libngtcp2_crypto_quictls
+ BoringSSL, AWS-LC: Use libngtcp2_crypto_boringssl
+ wolfSSL: Use libngtcp2_crypto_wolfssl
+ GnuTLS: Use libngtcp2_crypto_gnutls
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+``NGTCP2_FOUND``
+ System has ngtcp2
+``NGTCP2_INCLUDE_DIRS``
+ The ngtcp2 include directories.
+``NGTCP2_LIBRARIES``
+ The libraries needed to use ngtcp2
+``NGTCP2_VERSION``
+ version of ngtcp2.
+#]=======================================================================]
+
+if(UNIX)
+ find_package(PkgConfig QUIET)
+ pkg_search_module(PC_NGTCP2 libngtcp2)
+endif()
+
+find_path(NGTCP2_INCLUDE_DIR ngtcp2/ngtcp2.h
+ HINTS
+ ${PC_NGTCP2_INCLUDEDIR}
+ ${PC_NGTCP2_INCLUDE_DIRS}
+)
+
+find_library(NGTCP2_LIBRARY NAMES ngtcp2
+ HINTS
+ ${PC_NGTCP2_LIBDIR}
+ ${PC_NGTCP2_LIBRARY_DIRS}
+)
+
+if(PC_NGTCP2_VERSION)
+ set(NGTCP2_VERSION ${PC_NGTCP2_VERSION})
+endif()
+
+if(NGTCP2_FIND_COMPONENTS)
+ set(NGTCP2_CRYPTO_BACKEND "")
+ foreach(component IN LISTS NGTCP2_FIND_COMPONENTS)
+ if(component MATCHES "^(BoringSSL|quictls|wolfSSL|GnuTLS)")
+ if(NGTCP2_CRYPTO_BACKEND)
+ message(FATAL_ERROR "NGTCP2: Only one crypto library can be selected")
+ endif()
+ set(NGTCP2_CRYPTO_BACKEND ${component})
+ endif()
+ endforeach()
+
+ if(NGTCP2_CRYPTO_BACKEND)
+ string(TOLOWER "ngtcp2_crypto_${NGTCP2_CRYPTO_BACKEND}" _crypto_library)
+ if(UNIX)
+ pkg_search_module(PC_${_crypto_library} lib${_crypto_library})
+ endif()
+ find_library(${_crypto_library}_LIBRARY
+ NAMES
+ ${_crypto_library}
+ HINTS
+ ${PC_${_crypto_library}_LIBDIR}
+ ${PC_${_crypto_library}_LIBRARY_DIRS}
+ )
+ if(${_crypto_library}_LIBRARY)
+ set(NGTCP2_${NGTCP2_CRYPTO_BACKEND}_FOUND TRUE)
+ set(NGTCP2_CRYPTO_LIBRARY ${${_crypto_library}_LIBRARY})
+ endif()
+ endif()
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(NGTCP2
+ REQUIRED_VARS
+ NGTCP2_LIBRARY
+ NGTCP2_INCLUDE_DIR
+ VERSION_VAR NGTCP2_VERSION
+ HANDLE_COMPONENTS
+)
+
+if(NGTCP2_FOUND)
+ set(NGTCP2_LIBRARIES ${NGTCP2_LIBRARY} ${NGTCP2_CRYPTO_LIBRARY})
+ set(NGTCP2_INCLUDE_DIRS ${NGTCP2_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(NGTCP2_INCLUDE_DIRS NGTCP2_LIBRARIES)
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/FindQUICHE.cmake b/iotdb-client/odbc/deps/curl-src/CMake/FindQUICHE.cmake
new file mode 100644
index 0000000000000..0488463d55387
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/FindQUICHE.cmake
@@ -0,0 +1,70 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+
+#[=======================================================================[.rst:
+FindQUICHE
+----------
+
+Find the quiche library
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+``QUICHE_FOUND``
+ System has quiche
+``QUICHE_INCLUDE_DIRS``
+ The quiche include directories.
+``QUICHE_LIBRARIES``
+ The libraries needed to use quiche
+#]=======================================================================]
+if(UNIX)
+ find_package(PkgConfig QUIET)
+ pkg_search_module(PC_QUICHE quiche)
+endif()
+
+find_path(QUICHE_INCLUDE_DIR quiche.h
+ HINTS
+ ${PC_QUICHE_INCLUDEDIR}
+ ${PC_QUICHE_INCLUDE_DIRS}
+)
+
+find_library(QUICHE_LIBRARY NAMES quiche
+ HINTS
+ ${PC_QUICHE_LIBDIR}
+ ${PC_QUICHE_LIBRARY_DIRS}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(QUICHE
+ REQUIRED_VARS
+ QUICHE_LIBRARY
+ QUICHE_INCLUDE_DIR
+)
+
+if(QUICHE_FOUND)
+ set(QUICHE_LIBRARIES ${QUICHE_LIBRARY})
+ set(QUICHE_INCLUDE_DIRS ${QUICHE_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(QUICHE_INCLUDE_DIRS QUICHE_LIBRARIES)
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/FindWolfSSL.cmake b/iotdb-client/odbc/deps/curl-src/CMake/FindWolfSSL.cmake
new file mode 100644
index 0000000000000..d67c0eb24d408
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/FindWolfSSL.cmake
@@ -0,0 +1,36 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+find_path(WolfSSL_INCLUDE_DIR NAMES wolfssl/ssl.h)
+find_library(WolfSSL_LIBRARY NAMES wolfssl)
+mark_as_advanced(WolfSSL_INCLUDE_DIR WolfSSL_LIBRARY)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(WolfSSL
+ REQUIRED_VARS WolfSSL_INCLUDE_DIR WolfSSL_LIBRARY
+ )
+
+if(WolfSSL_FOUND)
+ set(WolfSSL_INCLUDE_DIRS ${WolfSSL_INCLUDE_DIR})
+ set(WolfSSL_LIBRARIES ${WolfSSL_LIBRARY})
+endif()
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/FindZstd.cmake b/iotdb-client/odbc/deps/curl-src/CMake/FindZstd.cmake
new file mode 100644
index 0000000000000..973e6ad4a90e2
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/FindZstd.cmake
@@ -0,0 +1,71 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+
+#[=======================================================================[.rst:
+FindZstd
+----------
+
+Find the zstd library
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+``Zstd_FOUND``
+ System has zstd
+``Zstd_INCLUDE_DIRS``
+ The zstd include directories.
+``Zstd_LIBRARIES``
+ The libraries needed to use zstd
+#]=======================================================================]
+
+if(UNIX)
+ find_package(PkgConfig QUIET)
+ pkg_search_module(PC_Zstd libzstd)
+endif()
+
+find_path(Zstd_INCLUDE_DIR zstd.h
+ HINTS
+ ${PC_Zstd_INCLUDEDIR}
+ ${PC_Zstd_INCLUDE_DIRS}
+)
+
+find_library(Zstd_LIBRARY NAMES zstd
+ HINTS
+ ${PC_Zstd_LIBDIR}
+ ${PC_Zstd_LIBRARY_DIRS}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Zstd
+ REQUIRED_VARS
+ Zstd_LIBRARY
+ Zstd_INCLUDE_DIR
+)
+
+if(Zstd_FOUND)
+ set(Zstd_LIBRARIES ${Zstd_LIBRARY})
+ set(Zstd_INCLUDE_DIRS ${Zstd_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(Zstd_INCLUDE_DIRS Zstd_LIBRARIES)
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/Macros.cmake b/iotdb-client/odbc/deps/curl-src/CMake/Macros.cmake
new file mode 100644
index 0000000000000..e12bf303f48ca
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/Macros.cmake
@@ -0,0 +1,122 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+#File defines convenience macros for available feature testing
+
+# This macro checks if the symbol exists in the library and if it
+# does, it prepends library to the list. It is intended to be called
+# multiple times with a sequence of possibly dependent libraries in
+# order of least-to-most-dependent. Some libraries depend on others
+# to link correctly.
+macro(check_library_exists_concat LIBRARY SYMBOL VARIABLE)
+ check_library_exists("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "${CMAKE_LIBRARY_PATH}"
+ ${VARIABLE})
+ if(${VARIABLE})
+ set(CURL_LIBS ${LIBRARY} ${CURL_LIBS})
+ endif()
+endmacro()
+
+# Check if header file exists and add it to the list.
+# This macro is intended to be called multiple times with a sequence of
+# possibly dependent header files. Some headers depend on others to be
+# compiled correctly.
+macro(check_include_file_concat FILE VARIABLE)
+ check_include_files("${CURL_INCLUDES};${FILE}" ${VARIABLE})
+ if(${VARIABLE})
+ set(CURL_INCLUDES ${CURL_INCLUDES} ${FILE})
+ set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${VARIABLE}")
+ endif()
+endmacro()
+
+# For other curl specific tests, use this macro.
+macro(curl_internal_test CURL_TEST)
+ if(NOT DEFINED "${CURL_TEST}")
+ set(MACRO_CHECK_FUNCTION_DEFINITIONS
+ "-D${CURL_TEST} ${CURL_TEST_DEFINES} ${CMAKE_REQUIRED_FLAGS}")
+ if(CMAKE_REQUIRED_LIBRARIES)
+ set(CURL_TEST_ADD_LIBRARIES
+ "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
+ endif()
+
+ message(STATUS "Performing Curl Test ${CURL_TEST}")
+ try_compile(${CURL_TEST}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
+ CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
+ "${CURL_TEST_ADD_LIBRARIES}"
+ OUTPUT_VARIABLE OUTPUT)
+ if(${CURL_TEST})
+ set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
+ message(STATUS "Performing Curl Test ${CURL_TEST} - Success")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Performing Curl Test ${CURL_TEST} passed with the following output:\n"
+ "${OUTPUT}\n")
+ else()
+ message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
+ set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Performing Curl Test ${CURL_TEST} failed with the following output:\n"
+ "${OUTPUT}\n")
+ endif()
+ endif()
+endmacro()
+
+macro(curl_nroff_check)
+ find_program(NROFF NAMES gnroff nroff)
+ if(NROFF)
+ # Need a way to write to stdin, this will do
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt" "test")
+ # Tests for a valid nroff option to generate a manpage
+ foreach(_MANOPT "-man" "-mandoc")
+ execute_process(COMMAND "${NROFF}" ${_MANOPT}
+ OUTPUT_VARIABLE NROFF_MANOPT_OUTPUT
+ INPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt"
+ ERROR_QUIET)
+ # Save the option if it was valid
+ if(NROFF_MANOPT_OUTPUT)
+ message("Found *nroff option: -- ${_MANOPT}")
+ set(NROFF_MANOPT ${_MANOPT})
+ set(NROFF_USEFUL ON)
+ break()
+ endif()
+ endforeach()
+ # No need for the temporary file
+ file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt")
+ if(NOT NROFF_USEFUL)
+ message(WARNING "Found no *nroff option to get plaintext from man pages")
+ endif()
+ else()
+ message(WARNING "Found no *nroff program")
+ endif()
+endmacro()
+
+macro(optional_dependency DEPENDENCY)
+ set(CURL_${DEPENDENCY} AUTO CACHE STRING "Build curl with ${DEPENDENCY} support (AUTO, ON or OFF)")
+ set_property(CACHE CURL_${DEPENDENCY} PROPERTY STRINGS AUTO ON OFF)
+
+ if(CURL_${DEPENDENCY} STREQUAL AUTO)
+ find_package(${DEPENDENCY})
+ elseif(CURL_${DEPENDENCY})
+ find_package(${DEPENDENCY} REQUIRED)
+ endif()
+endmacro()
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/OtherTests.cmake b/iotdb-client/odbc/deps/curl-src/CMake/OtherTests.cmake
new file mode 100644
index 0000000000000..d67a9059bcdea
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/OtherTests.cmake
@@ -0,0 +1,221 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+include(CheckCSourceCompiles)
+include(CheckCSourceRuns)
+
+# The begin of the sources (macros and includes)
+set(_source_epilogue "#undef inline")
+
+macro(add_header_include check header)
+ if(${check})
+ set(_source_epilogue "${_source_epilogue}\n#include <${header}>")
+ endif()
+endmacro()
+
+set(signature_call_conv)
+if(HAVE_WINDOWS_H)
+ add_header_include(HAVE_WINSOCK2_H "winsock2.h")
+ add_header_include(HAVE_WINDOWS_H "windows.h")
+ set(_source_epilogue
+ "${_source_epilogue}\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif")
+ set(signature_call_conv "PASCAL")
+ if(WIN32)
+ set(CMAKE_REQUIRED_LIBRARIES ws2_32)
+ endif()
+else()
+ add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
+ add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h")
+endif()
+
+set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+
+check_c_source_compiles("${_source_epilogue}
+ int main(void) {
+ int flag = MSG_NOSIGNAL;
+ (void)flag;
+ return 0;
+ }" HAVE_MSG_NOSIGNAL)
+
+if(NOT HAVE_WINDOWS_H)
+ add_header_include(HAVE_SYS_TIME_H "sys/time.h")
+endif()
+check_c_source_compiles("${_source_epilogue}
+#include
+int main(void) {
+ struct timeval ts;
+ ts.tv_sec = 0;
+ ts.tv_usec = 0;
+ (void)ts;
+ return 0;
+}" HAVE_STRUCT_TIMEVAL)
+
+if(HAVE_WINDOWS_H)
+ set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h)
+else()
+ set(CMAKE_EXTRA_INCLUDE_FILES)
+ if(HAVE_SYS_SOCKET_H)
+ set(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h)
+ endif()
+endif()
+
+check_type_size("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE)
+if(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
+ set(HAVE_STRUCT_SOCKADDR_STORAGE 1)
+endif()
+
+unset(CMAKE_TRY_COMPILE_TARGET_TYPE)
+
+if(NOT CMAKE_CROSSCOMPILING)
+ if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "iOS")
+ # only try this on non-apple platforms
+
+ # if not cross-compilation...
+ set(CMAKE_REQUIRED_FLAGS "")
+ if(HAVE_SYS_POLL_H)
+ set(CMAKE_REQUIRED_FLAGS "-DHAVE_SYS_POLL_H")
+ elseif(HAVE_POLL_H)
+ set(CMAKE_REQUIRED_FLAGS "-DHAVE_POLL_H")
+ endif()
+ check_c_source_runs("
+ #include
+ #include
+
+ #ifdef HAVE_SYS_POLL_H
+ # include
+ #elif HAVE_POLL_H
+ # include
+ #endif
+
+ int main(void)
+ {
+ if(0 != poll(0, 0, 10)) {
+ return 1; /* fail */
+ }
+ else {
+ /* detect the 10.12 poll() breakage */
+ struct timeval before, after;
+ int rc;
+ size_t us;
+
+ gettimeofday(&before, NULL);
+ rc = poll(NULL, 0, 500);
+ gettimeofday(&after, NULL);
+
+ us = (after.tv_sec - before.tv_sec) * 1000000 +
+ (after.tv_usec - before.tv_usec);
+
+ if(us < 400000) {
+ return 1;
+ }
+ }
+ return 0;
+ }" HAVE_POLL_FINE)
+ endif()
+endif()
+
+# Detect HAVE_GETADDRINFO_THREADSAFE
+
+if(WIN32)
+ set(HAVE_GETADDRINFO_THREADSAFE ${HAVE_GETADDRINFO})
+elseif(NOT HAVE_GETADDRINFO)
+ set(HAVE_GETADDRINFO_THREADSAFE FALSE)
+elseif(CMAKE_SYSTEM_NAME STREQUAL "AIX" OR
+ CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
+ CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
+ CMAKE_SYSTEM_NAME STREQUAL "HP-UX" OR
+ CMAKE_SYSTEM_NAME STREQUAL "MidnightBSD" OR
+ CMAKE_SYSTEM_NAME STREQUAL "NetBSD" OR
+ CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+ set(HAVE_GETADDRINFO_THREADSAFE TRUE)
+elseif(CMAKE_SYSTEM_NAME MATCHES "BSD")
+ set(HAVE_GETADDRINFO_THREADSAFE FALSE)
+endif()
+
+if(NOT DEFINED HAVE_GETADDRINFO_THREADSAFE)
+
+ set(_save_epilogue "${_source_epilogue}")
+ set(_source_epilogue "#undef inline")
+
+ add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h")
+ add_header_include(HAVE_SYS_TIME_H "sys/time.h")
+ add_header_include(HAVE_NETDB_H "netdb.h")
+
+ check_c_source_compiles("${_source_epilogue}
+ int main(void)
+ {
+ #ifdef h_errno
+ return 0;
+ #else
+ force compilation error
+ #endif
+ }" HAVE_H_ERRNO)
+
+ if(NOT HAVE_H_ERRNO)
+ check_c_source_runs("${_source_epilogue}
+ int main(void)
+ {
+ h_errno = 2;
+ return h_errno != 0 ? 1 : 0;
+ }" HAVE_H_ERRNO_ASSIGNABLE)
+
+ if(NOT HAVE_H_ERRNO_ASSIGNABLE)
+ check_c_source_compiles("${_source_epilogue}
+ int main(void)
+ {
+ #if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200809L)
+ return 0;
+ #elif defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 700)
+ return 0;
+ #else
+ force compilation error
+ #endif
+ }" HAVE_H_ERRNO_SBS_ISSUE_7)
+ endif()
+ endif()
+
+ if(HAVE_H_ERRNO OR HAVE_H_ERRNO_ASSIGNABLE OR HAVE_H_ERRNO_SBS_ISSUE_7)
+ set(HAVE_GETADDRINFO_THREADSAFE TRUE)
+ endif()
+
+ set(_source_epilogue "${_save_epilogue}")
+endif()
+
+if(NOT DEFINED HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
+ set(_save_epilogue "${_source_epilogue}")
+ set(_source_epilogue "#undef inline")
+
+ add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
+ add_header_include(HAVE_SYS_TIME_H "sys/time.h")
+
+ check_c_source_compiles("${_source_epilogue}
+ #include
+ int main(void)
+ {
+ struct timespec ts;
+ (void)clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
+ return 0;
+ }" HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
+
+ set(_source_epilogue "${_save_epilogue}")
+endif()
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/PickyWarnings.cmake b/iotdb-client/odbc/deps/curl-src/CMake/PickyWarnings.cmake
new file mode 100644
index 0000000000000..1310cb4fbe2bc
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/PickyWarnings.cmake
@@ -0,0 +1,197 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+include(CheckCCompilerFlag)
+
+if(PICKY_COMPILER)
+ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+
+ # https://clang.llvm.org/docs/DiagnosticsReference.html
+ # https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
+
+ # WPICKY_ENABLE = Options we want to enable as-is.
+ # WPICKY_DETECT = Options we want to test first and enable if available.
+
+ # Prefer the -Wextra alias with clang.
+ if(CMAKE_C_COMPILER_ID MATCHES "Clang")
+ set(WPICKY_ENABLE "-Wextra")
+ else()
+ set(WPICKY_ENABLE "-W")
+ endif()
+
+ list(APPEND WPICKY_ENABLE
+ -Wall -pedantic
+ )
+
+ # ----------------------------------
+ # Add new options here, if in doubt:
+ # ----------------------------------
+ set(WPICKY_DETECT
+ )
+
+ # Assume these options always exist with both clang and gcc.
+ # Require clang 3.0 / gcc 2.95 or later.
+ list(APPEND WPICKY_ENABLE
+ -Wbad-function-cast # clang 3.0 gcc 2.95
+ -Wconversion # clang 3.0 gcc 2.95
+ -Winline # clang 1.0 gcc 1.0
+ -Wmissing-declarations # clang 1.0 gcc 2.7
+ -Wmissing-prototypes # clang 1.0 gcc 1.0
+ -Wnested-externs # clang 1.0 gcc 2.7
+ -Wno-long-long # clang 1.0 gcc 2.95
+ -Wno-multichar # clang 1.0 gcc 2.95
+ -Wpointer-arith # clang 1.0 gcc 1.4
+ -Wshadow # clang 1.0 gcc 2.95
+ -Wsign-compare # clang 1.0 gcc 2.95
+ -Wundef # clang 1.0 gcc 2.95
+ -Wunused # clang 1.1 gcc 2.95
+ -Wwrite-strings # clang 1.0 gcc 1.4
+ )
+
+ # Always enable with clang, version dependent with gcc
+ set(WPICKY_COMMON_OLD
+ -Wcast-align # clang 1.0 gcc 4.2
+ -Wdeclaration-after-statement # clang 1.0 gcc 3.4
+ -Wempty-body # clang 3.0 gcc 4.3
+ -Wendif-labels # clang 1.0 gcc 3.3
+ -Wfloat-equal # clang 1.0 gcc 2.96 (3.0)
+ -Wignored-qualifiers # clang 3.0 gcc 4.3
+ -Wno-format-nonliteral # clang 1.0 gcc 2.96 (3.0)
+ -Wno-sign-conversion # clang 3.0 gcc 4.3
+ -Wno-system-headers # clang 1.0 gcc 3.0
+ -Wstrict-prototypes # clang 1.0 gcc 3.3
+ -Wtype-limits # clang 3.0 gcc 4.3
+ -Wvla # clang 2.8 gcc 4.3
+ )
+
+ set(WPICKY_COMMON
+ -Wdouble-promotion # clang 3.6 gcc 4.6 appleclang 6.3
+ -Wenum-conversion # clang 3.2 gcc 10.0 appleclang 4.6 g++ 11.0
+ -Wunused-const-variable # clang 3.4 gcc 6.0 appleclang 5.1
+ )
+
+ if(CMAKE_C_COMPILER_ID MATCHES "Clang")
+ list(APPEND WPICKY_ENABLE
+ ${WPICKY_COMMON_OLD}
+ -Wshift-sign-overflow # clang 2.9
+ -Wshorten-64-to-32 # clang 1.0
+ )
+ # Enable based on compiler version
+ if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.6) OR
+ (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.3))
+ list(APPEND WPICKY_ENABLE
+ ${WPICKY_COMMON}
+ )
+ endif()
+ if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.9) OR
+ (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.3))
+ list(APPEND WPICKY_ENABLE
+ -Wcomma # clang 3.9 appleclang 8.3
+ -Wmissing-variable-declarations # clang 3.2 appleclang 4.6
+ )
+ endif()
+ if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0) OR
+ (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.3))
+ list(APPEND WPICKY_ENABLE
+ -Wassign-enum # clang 7.0 appleclang 10.3
+ -Wextra-semi-stmt # clang 7.0 appleclang 10.3
+ )
+ endif()
+ else() # gcc
+ list(APPEND WPICKY_DETECT
+ ${WPICKY_COMMON}
+ )
+ # Enable based on compiler version
+ if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.3)
+ list(APPEND WPICKY_ENABLE
+ ${WPICKY_COMMON_OLD}
+ -Wmissing-parameter-type # gcc 4.3
+ -Wold-style-declaration # gcc 4.3
+ -Wstrict-aliasing=3 # gcc 4.0
+ )
+ endif()
+ if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5 AND MINGW)
+ list(APPEND WPICKY_ENABLE
+ -Wno-pedantic-ms-format # gcc 4.5 (mingw-only)
+ )
+ endif()
+ if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8)
+ list(APPEND WPICKY_ENABLE
+ -Wformat=2 # clang 3.0 gcc 4.8 (clang part-default, enabling it fully causes -Wformat-nonliteral warnings)
+ )
+ endif()
+ if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0)
+ list(APPEND WPICKY_ENABLE
+ -Warray-bounds=2 -ftree-vrp # clang 3.0 gcc 5.0 (clang default: -Warray-bounds)
+ )
+ endif()
+ if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0)
+ list(APPEND WPICKY_ENABLE
+ -Wduplicated-cond # gcc 6.0
+ -Wnull-dereference # clang 3.0 gcc 6.0 (clang default)
+ -fdelete-null-pointer-checks
+ -Wshift-negative-value # clang 3.7 gcc 6.0 (clang default)
+ -Wshift-overflow=2 # clang 3.0 gcc 6.0 (clang default: -Wshift-overflow)
+ )
+ endif()
+ if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0)
+ list(APPEND WPICKY_ENABLE
+ -Walloc-zero # gcc 7.0
+ -Wduplicated-branches # gcc 7.0
+ -Wformat-overflow=2 # gcc 7.0
+ -Wformat-truncation=1 # gcc 7.0
+ -Wrestrict # gcc 7.0
+ )
+ endif()
+ if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0)
+ list(APPEND WPICKY_ENABLE
+ -Warith-conversion # gcc 10.0
+ )
+ endif()
+ endif()
+
+ #
+
+ unset(WPICKY)
+
+ foreach(_CCOPT ${WPICKY_ENABLE})
+ set(WPICKY "${WPICKY} ${_CCOPT}")
+ endforeach()
+
+ foreach(_CCOPT ${WPICKY_DETECT})
+ # surprisingly, CHECK_C_COMPILER_FLAG needs a new variable to store each new
+ # test result in.
+ string(MAKE_C_IDENTIFIER "OPT${_CCOPT}" _optvarname)
+ # GCC only warns about unknown -Wno- options if there are also other diagnostic messages,
+ # so test for the positive form instead
+ string(REPLACE "-Wno-" "-W" _CCOPT_ON "${_CCOPT}")
+ check_c_compiler_flag(${_CCOPT_ON} ${_optvarname})
+ if(${_optvarname})
+ set(WPICKY "${WPICKY} ${_CCOPT}")
+ endif()
+ endforeach()
+
+ message(STATUS "Picky compiler options:${WPICKY}")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WPICKY}")
+ endif()
+endif()
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/Platforms/WindowsCache.cmake b/iotdb-client/odbc/deps/curl-src/CMake/Platforms/WindowsCache.cmake
new file mode 100644
index 0000000000000..5daec0e1e077d
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/Platforms/WindowsCache.cmake
@@ -0,0 +1,133 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+if(NOT UNIX)
+ if(WIN32)
+
+ set(HAVE_WINDOWS_H 1)
+ set(HAVE_WS2TCPIP_H 1)
+ set(HAVE_WINSOCK2_H 1)
+
+ if(MINGW)
+ set(HAVE_SNPRINTF 1)
+ set(HAVE_UNISTD_H 1)
+ set(HAVE_INTTYPES_H 1)
+ set(HAVE_STRTOLL 1)
+ set(HAVE_BASENAME 1)
+ elseif(MSVC)
+ if(NOT MSVC_VERSION LESS 1800)
+ set(HAVE_INTTYPES_H 1)
+ set(HAVE_STRTOLL 1)
+ else()
+ set(HAVE_INTTYPES_H 0)
+ set(HAVE_STRTOLL 0)
+ endif()
+ if(NOT MSVC_VERSION LESS 1900)
+ set(HAVE_SNPRINTF 1)
+ else()
+ set(HAVE_SNPRINTF 0)
+ endif()
+ set(HAVE_BASENAME 0)
+ endif()
+
+ set(HAVE_LIBSOCKET 0)
+ set(HAVE_GETHOSTNAME 1)
+ set(HAVE_LIBZ 0)
+
+ set(HAVE_ARC4RANDOM 0)
+ set(HAVE_FNMATCH 0)
+ set(HAVE_SCHED_YIELD 0)
+ set(HAVE_ARPA_INET_H 0)
+ set(HAVE_FCNTL_H 1)
+ set(HAVE_IFADDRS_H 0)
+ set(HAVE_IO_H 1)
+ set(HAVE_NETDB_H 0)
+ set(HAVE_NETINET_IN_H 0)
+ set(HAVE_NETINET_TCP_H 0)
+ set(HAVE_NETINET_UDP_H 0)
+ set(HAVE_NET_IF_H 0)
+ set(HAVE_IOCTL_SIOCGIFADDR 0)
+ set(HAVE_POLL_H 0)
+ set(HAVE_POLL_FINE 0)
+ set(HAVE_PWD_H 0)
+ set(HAVE_STRINGS_H 0)
+ set(HAVE_SYS_FILIO_H 0)
+ set(HAVE_SYS_WAIT_H 0)
+ set(HAVE_SYS_IOCTL_H 0)
+ set(HAVE_SYS_PARAM_H 0)
+ set(HAVE_SYS_POLL_H 0)
+ set(HAVE_SYS_RESOURCE_H 0)
+ set(HAVE_SYS_SELECT_H 0)
+ set(HAVE_SYS_SOCKET_H 0)
+ set(HAVE_SYS_SOCKIO_H 0)
+ set(HAVE_SYS_STAT_H 1)
+ set(HAVE_SYS_TIME_H 0)
+ set(HAVE_SYS_TYPES_H 1)
+ set(HAVE_SYS_UN_H 0)
+ set(HAVE_SYS_UTIME_H 1)
+ set(HAVE_TERMIOS_H 0)
+ set(HAVE_TERMIO_H 0)
+ set(HAVE_UTIME_H 0)
+
+ set(HAVE_FSEEKO 0)
+ set(HAVE__FSEEKI64 1)
+ set(HAVE_SOCKET 1)
+ set(HAVE_SELECT 1)
+ set(HAVE_STRDUP 1)
+ set(HAVE_STRICMP 1)
+ set(HAVE_STRCMPI 1)
+ set(HAVE_MEMRCHR 0)
+ set(HAVE_GETTIMEOFDAY 0)
+ set(HAVE_CLOSESOCKET 1)
+ set(HAVE_SIGSETJMP 0)
+ set(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1)
+ set(HAVE_GETPASS_R 0)
+ set(HAVE_GETPWUID 0)
+ set(HAVE_GETEUID 0)
+ set(HAVE_UTIME 1)
+ set(HAVE_GMTIME_R 0)
+ set(HAVE_CLOCK_GETTIME_MONOTONIC_RAW 0)
+ set(HAVE_GETHOSTBYNAME_R 0)
+ set(HAVE_SIGNAL 1)
+ set(HAVE_LINUX_TCP_H 0)
+ set(HAVE_GLIBC_STRERROR_R 0)
+ set(HAVE_MACH_ABSOLUTE_TIME 0)
+ set(HAVE_GETIFADDRS 0)
+
+ set(HAVE_GETHOSTBYNAME_R_3 0)
+ set(HAVE_GETHOSTBYNAME_R_3_REENTRANT 0)
+ set(HAVE_GETHOSTBYNAME_R_5 0)
+ set(HAVE_GETHOSTBYNAME_R_5_REENTRANT 0)
+ set(HAVE_GETHOSTBYNAME_R_6 0)
+ set(HAVE_GETHOSTBYNAME_R_6_REENTRANT 0)
+
+ set(HAVE_O_NONBLOCK 0)
+ set(HAVE_IN_ADDR_T 0)
+ set(STDC_HEADERS 1)
+
+ set(HAVE_SIGACTION 0)
+ set(HAVE_MACRO_SIGSETJMP 0)
+ else()
+ message("This file should be included on Windows platform only")
+ endif()
+endif()
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/Utilities.cmake b/iotdb-client/odbc/deps/curl-src/CMake/Utilities.cmake
new file mode 100644
index 0000000000000..9ff38e3a0f143
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/Utilities.cmake
@@ -0,0 +1,35 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+# File containing various utilities
+
+# Returns a list of arguments that evaluate to true
+function(count_true output_count_var)
+ set(lst_len 0)
+ foreach(option_var IN LISTS ARGN)
+ if(${option_var})
+ math(EXPR lst_len "${lst_len} + 1")
+ endif()
+ endforeach()
+ set(${output_count_var} ${lst_len} PARENT_SCOPE)
+endfunction()
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/cmake_uninstall.cmake.in b/iotdb-client/odbc/deps/curl-src/CMake/cmake_uninstall.cmake.in
new file mode 100644
index 0000000000000..47aec8d42c2c9
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/cmake_uninstall.cmake.in
@@ -0,0 +1,49 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+ message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_PREFIX)
+ set(CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@")
+endif()
+message(${CMAKE_INSTALL_PREFIX})
+
+file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
+string(REGEX REPLACE "\n" ";" files "${files}")
+foreach(file ${files})
+ message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
+ if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
+ exec_program(
+ "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
+ OUTPUT_VARIABLE rm_out
+ RETURN_VALUE rm_retval
+ )
+ if(NOT "${rm_retval}" STREQUAL 0)
+ message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
+ endif()
+ else()
+ message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
+ endif()
+endforeach()
diff --git a/iotdb-client/odbc/deps/curl-src/CMake/curl-config.cmake.in b/iotdb-client/odbc/deps/curl-src/CMake/curl-config.cmake.in
new file mode 100644
index 0000000000000..056907c4f91d0
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMake/curl-config.cmake.in
@@ -0,0 +1,38 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+@PACKAGE_INIT@
+
+include(CMakeFindDependencyMacro)
+if(@USE_OPENSSL@)
+ find_dependency(OpenSSL @OPENSSL_VERSION_MAJOR@)
+endif()
+if(@USE_ZLIB@)
+ find_dependency(ZLIB @ZLIB_VERSION_MAJOR@)
+endif()
+
+include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
+check_required_components("@PROJECT_NAME@")
+
+# Alias for either shared or static library
+add_library(@PROJECT_NAME@::libcurl ALIAS @PROJECT_NAME@::@LIB_SELECTED@)
diff --git a/iotdb-client/odbc/deps/curl-src/CMakeLists.txt b/iotdb-client/odbc/deps/curl-src/CMakeLists.txt
new file mode 100644
index 0000000000000..1b19c681d22fc
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/CMakeLists.txt
@@ -0,0 +1,1749 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+# curl/libcurl CMake script
+# by Tetetest and Sukender (Benoit Neil)
+
+# TODO:
+# The output .so file lacks the soname number which we currently have within the lib/Makefile.am file
+# Add full (4 or 5 libs) SSL support
+# Add INSTALL target (EXTRA_DIST variables in Makefile.am may be moved to Makefile.inc so that CMake/CPack is aware of what's to include).
+# Check on all possible platforms
+# Test with as many configurations possible (With or without any option)
+# Create scripts that help keeping the CMake build system up to date (to reduce maintenance). According to Tetetest:
+# - lists of headers that 'configure' checks for;
+# - curl-specific tests (the ones that are in m4/curl-*.m4 files);
+# - (most obvious thing:) curl version numbers.
+# Add documentation subproject
+#
+# To check:
+# (From Daniel Stenberg) The cmake build selected to run gcc with -fPIC on my box while the plain configure script did not.
+# (From Daniel Stenberg) The gcc command line use neither -g nor any -O options. As a developer, I also treasure our configure scripts's --enable-debug option that sets a long range of "picky" compiler options.
+
+# Note: By default this CMake build script detects the version of some
+# dependencies using `check_symbol_exists`. Those checks do not work
+# in the case that both CURL and its dependency are included as
+# sub-projects in a larger build using `FetchContent`. To support
+# that case, additional variables may be defined by the parent
+# project, ideally in the "extra" find package redirect file:
+# https://cmake.org/cmake/help/latest/module/FetchContent.html#integrating-with-find-package
+#
+# The following variables are available:
+# HAVE_SSL_SET0_WBIO: `SSL_set0_wbio` present in OpenSSL/wolfSSL
+# HAVE_OPENSSL_SRP: `SSL_CTX_set_srp_username` present in OpenSSL/wolfSSL
+# HAVE_GNUTLS_SRP: `gnutls_srp_verifier` present in GnuTLS
+# HAVE_SSL_CTX_SET_QUIC_METHOD: `SSL_CTX_set_quic_method` present in OpenSSL/wolfSSL
+# HAVE_QUICHE_CONN_SET_QLOG_FD: `quiche_conn_set_qlog_fd` present in QUICHE
+# HAVE_ZSTD_CREATEDSTREAM: `ZSTD_createDStream` present in Zstd
+#
+# For each of the above variables, if the variable is DEFINED (either
+# to ON or OFF), the symbol detection will be skipped. If the
+# variable is NOT DEFINED, the symbol detection will be performed.
+
+cmake_minimum_required(VERSION 3.7...3.16 FATAL_ERROR)
+
+set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
+include(Utilities)
+include(Macros)
+include(CMakeDependentOption)
+include(CheckCCompilerFlag)
+
+project(CURL C)
+
+file(STRINGS ${CURL_SOURCE_DIR}/include/curl/curlver.h CURL_VERSION_H_CONTENTS REGEX "#define LIBCURL_VERSION( |_NUM )")
+string(REGEX MATCH "#define LIBCURL_VERSION \"[^\"]*"
+ CURL_VERSION ${CURL_VERSION_H_CONTENTS})
+string(REGEX REPLACE "[^\"]+\"" "" CURL_VERSION ${CURL_VERSION})
+string(REGEX MATCH "#define LIBCURL_VERSION_NUM 0x[0-9a-fA-F]+"
+ CURL_VERSION_NUM ${CURL_VERSION_H_CONTENTS})
+string(REGEX REPLACE "[^0]+0x" "" CURL_VERSION_NUM ${CURL_VERSION_NUM})
+
+
+# Setup package meta-data
+# SET(PACKAGE "curl")
+message(STATUS "curl version=[${CURL_VERSION}]")
+# SET(PACKAGE_TARNAME "curl")
+# SET(PACKAGE_NAME "curl")
+# SET(PACKAGE_VERSION "-")
+# SET(PACKAGE_STRING "curl-")
+# SET(PACKAGE_BUGREPORT "a suitable curl mailing list => https://curl.se/mail/")
+set(OPERATING_SYSTEM "${CMAKE_SYSTEM_NAME}")
+if(CMAKE_C_COMPILER_TARGET)
+ set(OS "\"${CMAKE_C_COMPILER_TARGET}\"")
+else()
+ set(OS "\"${CMAKE_SYSTEM_NAME}\"")
+endif()
+
+include_directories(${CURL_SOURCE_DIR}/include)
+
+set(CMAKE_UNITY_BUILD_BATCH_SIZE 0)
+
+option(CURL_WERROR "Turn compiler warnings into errors" OFF)
+option(PICKY_COMPILER "Enable picky compiler options" ON)
+option(BUILD_CURL_EXE "Set to ON to build curl executable." ON)
+option(BUILD_SHARED_LIBS "Build shared libraries" ON)
+option(BUILD_STATIC_LIBS "Build static libraries" OFF)
+option(BUILD_STATIC_CURL "Build curl executable with static libcurl" OFF)
+option(ENABLE_ARES "Set to ON to enable c-ares support" OFF)
+if(WIN32)
+ option(CURL_STATIC_CRT "Set to ON to build libcurl with static CRT on Windows (/MT)." OFF)
+ option(ENABLE_UNICODE "Set to ON to use the Unicode version of the Windows API functions" OFF)
+ set(CURL_TARGET_WINDOWS_VERSION "" CACHE STRING "Minimum target Windows version as hex string")
+ if(CURL_TARGET_WINDOWS_VERSION)
+ add_definitions(-D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION})
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION})
+ set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION}")
+ endif()
+ if(ENABLE_UNICODE)
+ add_definitions(-DUNICODE -D_UNICODE)
+ if(MINGW)
+ add_compile_options(-municode)
+ endif()
+ endif()
+endif()
+option(CURL_LTO "Turn on compiler Link Time Optimizations" OFF)
+
+cmake_dependent_option(ENABLE_THREADED_RESOLVER "Set to ON to enable threaded DNS lookup"
+ ON "NOT ENABLE_ARES"
+ OFF)
+
+option(ENABLE_DEBUG "Set to ON to enable curl debug features" OFF)
+option(ENABLE_CURLDEBUG "Set to ON to build with TrackMemory feature enabled" OFF)
+
+include(PickyWarnings)
+
+if(ENABLE_DEBUG)
+ # DEBUGBUILD will be defined only for Debug builds
+ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$:DEBUGBUILD>)
+ set(ENABLE_CURLDEBUG ON)
+endif()
+
+if(ENABLE_CURLDEBUG)
+ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS CURLDEBUG)
+endif()
+
+# For debug libs and exes, add "-d" postfix
+if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
+ set(CMAKE_DEBUG_POSTFIX "-d")
+endif()
+
+set(LIB_STATIC "libcurl_static")
+set(LIB_SHARED "libcurl_shared")
+
+if(NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS)
+ set(BUILD_STATIC_LIBS ON)
+endif()
+if(NOT BUILD_STATIC_CURL AND NOT BUILD_SHARED_LIBS)
+ set(BUILD_STATIC_CURL ON)
+elseif(BUILD_STATIC_CURL AND NOT BUILD_STATIC_LIBS)
+ set(BUILD_STATIC_CURL OFF)
+endif()
+
+# lib flavour selected for curl tool
+if(BUILD_STATIC_CURL)
+ set(LIB_SELECTED_FOR_EXE ${LIB_STATIC})
+else()
+ set(LIB_SELECTED_FOR_EXE ${LIB_SHARED})
+endif()
+
+# lib flavour selected for example and test programs.
+if(BUILD_SHARED_LIBS)
+ set(LIB_SELECTED ${LIB_SHARED})
+else()
+ set(LIB_SELECTED ${LIB_STATIC})
+endif()
+
+# initialize CURL_LIBS
+set(CURL_LIBS "")
+
+if(ENABLE_ARES)
+ set(USE_ARES 1)
+ find_package(CARES REQUIRED)
+ list(APPEND CURL_LIBS ${CARES_LIBRARY})
+endif()
+
+include(CurlSymbolHiding)
+
+option(CURL_ENABLE_EXPORT_TARGET "to enable cmake export target" ON)
+mark_as_advanced(CURL_ENABLE_EXPORT_TARGET)
+
+option(CURL_DISABLE_ALTSVC "disables alt-svc support" OFF)
+mark_as_advanced(CURL_DISABLE_ALTSVC)
+option(CURL_DISABLE_SRP "disables TLS-SRP support" OFF)
+mark_as_advanced(CURL_DISABLE_SRP)
+option(CURL_DISABLE_COOKIES "disables cookies support" OFF)
+mark_as_advanced(CURL_DISABLE_COOKIES)
+option(CURL_DISABLE_BASIC_AUTH "disables Basic authentication" OFF)
+mark_as_advanced(CURL_DISABLE_BASIC_AUTH)
+option(CURL_DISABLE_BEARER_AUTH "disables Bearer authentication" OFF)
+mark_as_advanced(CURL_DISABLE_BEARER_AUTH)
+option(CURL_DISABLE_DIGEST_AUTH "disables Digest authentication" OFF)
+mark_as_advanced(CURL_DISABLE_DIGEST_AUTH)
+option(CURL_DISABLE_KERBEROS_AUTH "disables Kerberos authentication" OFF)
+mark_as_advanced(CURL_DISABLE_KERBEROS_AUTH)
+option(CURL_DISABLE_NEGOTIATE_AUTH "disables negotiate authentication" OFF)
+mark_as_advanced(CURL_DISABLE_NEGOTIATE_AUTH)
+option(CURL_DISABLE_AWS "disables AWS-SIG4" OFF)
+mark_as_advanced(CURL_DISABLE_AWS)
+option(CURL_DISABLE_DICT "disables DICT" OFF)
+mark_as_advanced(CURL_DISABLE_DICT)
+option(CURL_DISABLE_DOH "disables DNS-over-HTTPS" OFF)
+mark_as_advanced(CURL_DISABLE_DOH)
+option(CURL_DISABLE_FILE "disables FILE" OFF)
+mark_as_advanced(CURL_DISABLE_FILE)
+cmake_dependent_option(CURL_DISABLE_FORM_API "disables form api" OFF
+ "NOT CURL_DISABLE_MIME" ON)
+mark_as_advanced(CURL_DISABLE_FORM_API)
+option(CURL_DISABLE_FTP "disables FTP" OFF)
+mark_as_advanced(CURL_DISABLE_FTP)
+option(CURL_DISABLE_GETOPTIONS "disables curl_easy_options API for existing options to curl_easy_setopt" OFF)
+mark_as_advanced(CURL_DISABLE_GETOPTIONS)
+option(CURL_DISABLE_GOPHER "disables Gopher" OFF)
+mark_as_advanced(CURL_DISABLE_GOPHER)
+option(CURL_DISABLE_HSTS "disables HSTS support" OFF)
+mark_as_advanced(CURL_DISABLE_HSTS)
+option(CURL_DISABLE_HTTP "disables HTTP" OFF)
+mark_as_advanced(CURL_DISABLE_HTTP)
+option(CURL_DISABLE_HTTP_AUTH "disables all HTTP authentication methods" OFF)
+mark_as_advanced(CURL_DISABLE_HTTP_AUTH)
+option(CURL_DISABLE_IMAP "disables IMAP" OFF)
+mark_as_advanced(CURL_DISABLE_IMAP)
+option(CURL_DISABLE_LDAP "disables LDAP" OFF)
+mark_as_advanced(CURL_DISABLE_LDAP)
+option(CURL_DISABLE_LDAPS "disables LDAPS" OFF)
+mark_as_advanced(CURL_DISABLE_LDAPS)
+option(CURL_DISABLE_LIBCURL_OPTION "disables --libcurl option from the curl tool" OFF)
+mark_as_advanced(CURL_DISABLE_LIBCURL_OPTION)
+option(CURL_DISABLE_MIME "disables MIME support" OFF)
+mark_as_advanced(CURL_DISABLE_MIME)
+option(CURL_DISABLE_MQTT "disables MQTT" OFF)
+mark_as_advanced(CURL_DISABLE_MQTT)
+option(CURL_DISABLE_NETRC "disables netrc parser" OFF)
+mark_as_advanced(CURL_DISABLE_NETRC)
+option(CURL_DISABLE_NTLM "disables NTLM support" OFF)
+mark_as_advanced(CURL_DISABLE_NTLM)
+option(CURL_DISABLE_PARSEDATE "disables date parsing" OFF)
+mark_as_advanced(CURL_DISABLE_PARSEDATE)
+option(CURL_DISABLE_POP3 "disables POP3" OFF)
+mark_as_advanced(CURL_DISABLE_POP3)
+option(CURL_DISABLE_PROGRESS_METER "disables built-in progress meter" OFF)
+mark_as_advanced(CURL_DISABLE_PROGRESS_METER)
+option(CURL_DISABLE_PROXY "disables proxy support" OFF)
+mark_as_advanced(CURL_DISABLE_PROXY)
+option(CURL_DISABLE_RTSP "disables RTSP" OFF)
+mark_as_advanced(CURL_DISABLE_RTSP)
+option(CURL_DISABLE_SHUFFLE_DNS "disables shuffle DNS feature" OFF)
+mark_as_advanced(CURL_DISABLE_SHUFFLE_DNS)
+option(CURL_DISABLE_SMB "disables SMB" OFF)
+mark_as_advanced(CURL_DISABLE_SMB)
+option(CURL_DISABLE_SMTP "disables SMTP" OFF)
+mark_as_advanced(CURL_DISABLE_SMTP)
+option(CURL_DISABLE_SOCKETPAIR "disables use of socketpair for curl_multi_poll" OFF)
+mark_as_advanced(CURL_DISABLE_SOCKETPAIR)
+option(CURL_DISABLE_TELNET "disables Telnet" OFF)
+mark_as_advanced(CURL_DISABLE_TELNET)
+option(CURL_DISABLE_TFTP "disables TFTP" OFF)
+mark_as_advanced(CURL_DISABLE_TFTP)
+option(CURL_DISABLE_VERBOSE_STRINGS "disables verbose strings" OFF)
+mark_as_advanced(CURL_DISABLE_VERBOSE_STRINGS)
+
+# Corresponds to HTTP_ONLY in lib/curl_setup.h
+option(HTTP_ONLY "disables all protocols except HTTP (This overrides all CURL_DISABLE_* options)" OFF)
+mark_as_advanced(HTTP_ONLY)
+
+if(HTTP_ONLY)
+ set(CURL_DISABLE_DICT ON)
+ set(CURL_DISABLE_FILE ON)
+ set(CURL_DISABLE_FTP ON)
+ set(CURL_DISABLE_GOPHER ON)
+ set(CURL_DISABLE_IMAP ON)
+ set(CURL_DISABLE_LDAP ON)
+ set(CURL_DISABLE_LDAPS ON)
+ set(CURL_DISABLE_MQTT ON)
+ set(CURL_DISABLE_POP3 ON)
+ set(CURL_DISABLE_RTSP ON)
+ set(CURL_DISABLE_SMB ON)
+ set(CURL_DISABLE_SMTP ON)
+ set(CURL_DISABLE_TELNET ON)
+ set(CURL_DISABLE_TFTP ON)
+endif()
+
+option(ENABLE_IPV6 "Define if you want to enable IPv6 support" ON)
+mark_as_advanced(ENABLE_IPV6)
+if(ENABLE_IPV6 AND NOT WIN32)
+ include(CheckStructHasMember)
+ check_struct_has_member("struct sockaddr_in6" sin6_addr "netinet/in.h"
+ HAVE_SOCKADDR_IN6_SIN6_ADDR)
+ check_struct_has_member("struct sockaddr_in6" sin6_scope_id "netinet/in.h"
+ HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
+ if(NOT HAVE_SOCKADDR_IN6_SIN6_ADDR)
+ message(WARNING "struct sockaddr_in6 not available, disabling IPv6 support")
+ # Force the feature off as this name is used as guard macro...
+ set(ENABLE_IPV6 OFF
+ CACHE BOOL "Define if you want to enable IPv6 support" FORCE)
+ endif()
+
+ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT ENABLE_ARES)
+ set(use_core_foundation_and_core_services ON)
+
+ find_library(SYSTEMCONFIGURATION_FRAMEWORK "SystemConfiguration")
+ if(NOT SYSTEMCONFIGURATION_FRAMEWORK)
+ message(FATAL_ERROR "SystemConfiguration framework not found")
+ endif()
+
+ list(APPEND CURL_LIBS "-framework SystemConfiguration")
+ endif()
+endif()
+
+if(USE_MANUAL)
+ #nroff is currently only used when USE_MANUAL is set, so we can prevent the warning of no *NROFF if USE_MANUAL is OFF (or not defined), by not even looking for NROFF..
+ curl_nroff_check()
+endif()
+find_package(Perl)
+
+cmake_dependent_option(ENABLE_MANUAL "to provide the built-in manual"
+ ON "NROFF_USEFUL;PERL_FOUND"
+ OFF)
+
+if(ENABLE_MANUAL)
+ set(USE_MANUAL ON)
+endif()
+
+if(CURL_STATIC_CRT)
+ set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>")
+ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
+ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd")
+endif()
+
+# Disable warnings on Borland to avoid changing 3rd party code.
+if(BORLAND)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w-")
+endif()
+
+# If we are on AIX, do the _ALL_SOURCE magic
+if(${CMAKE_SYSTEM_NAME} MATCHES AIX)
+ set(_ALL_SOURCE 1)
+endif()
+
+# If we are on Haiku, make sure that the network library is brought in.
+if(${CMAKE_SYSTEM_NAME} MATCHES Haiku)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lnetwork")
+endif()
+
+# Include all the necessary files for macros
+include(CMakePushCheckState)
+include(CheckFunctionExists)
+include(CheckIncludeFile)
+include(CheckIncludeFiles)
+include(CheckLibraryExists)
+include(CheckSymbolExists)
+include(CheckTypeSize)
+include(CheckCSourceCompiles)
+
+# On windows preload settings
+if(WIN32)
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_WINSOCKAPI_=)
+ include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake)
+endif()
+
+if(ENABLE_THREADED_RESOLVER)
+ find_package(Threads REQUIRED)
+ if(WIN32)
+ set(USE_THREADS_WIN32 ON)
+ else()
+ set(USE_THREADS_POSIX ${CMAKE_USE_PTHREADS_INIT})
+ set(HAVE_PTHREAD_H ${CMAKE_USE_PTHREADS_INIT})
+ endif()
+ set(CURL_LIBS ${CURL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
+endif()
+
+# Check for all needed libraries
+check_library_exists_concat("socket" connect HAVE_LIBSOCKET)
+
+check_function_exists(gethostname HAVE_GETHOSTNAME)
+
+if(WIN32)
+ list(APPEND CURL_LIBS "ws2_32")
+ if(USE_LIBRTMP)
+ list(APPEND CURL_LIBS "winmm")
+ endif()
+endif()
+
+# check SSL libraries
+option(CURL_ENABLE_SSL "Enable SSL support" ON)
+
+if(CURL_DEFAULT_SSL_BACKEND)
+ set(valid_default_ssl_backend FALSE)
+endif()
+
+if(APPLE)
+ cmake_dependent_option(CURL_USE_SECTRANSP "Enable Apple OS native SSL/TLS" OFF CURL_ENABLE_SSL OFF)
+endif()
+if(WIN32)
+ cmake_dependent_option(CURL_USE_SCHANNEL "Enable Windows native SSL/TLS" OFF CURL_ENABLE_SSL OFF)
+ cmake_dependent_option(CURL_WINDOWS_SSPI "Use windows libraries to allow NTLM authentication without OpenSSL" ON
+ CURL_USE_SCHANNEL OFF)
+endif()
+cmake_dependent_option(CURL_USE_MBEDTLS "Enable mbedTLS for SSL/TLS" OFF CURL_ENABLE_SSL OFF)
+cmake_dependent_option(CURL_USE_BEARSSL "Enable BearSSL for SSL/TLS" OFF CURL_ENABLE_SSL OFF)
+cmake_dependent_option(CURL_USE_WOLFSSL "Enable wolfSSL for SSL/TLS" OFF CURL_ENABLE_SSL OFF)
+cmake_dependent_option(CURL_USE_GNUTLS "Enable GnuTLS for SSL/TLS" OFF CURL_ENABLE_SSL OFF)
+
+set(openssl_default ON)
+if(WIN32 OR CURL_USE_SECTRANSP OR CURL_USE_SCHANNEL OR CURL_USE_MBEDTLS OR CURL_USE_WOLFSSL)
+ set(openssl_default OFF)
+endif()
+cmake_dependent_option(CURL_USE_OPENSSL "Use OpenSSL code. Experimental" ${openssl_default} CURL_ENABLE_SSL OFF)
+option(CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG "Disable automatic loading of OpenSSL configuration" OFF)
+
+count_true(enabled_ssl_options_count
+ CURL_USE_SCHANNEL
+ CURL_USE_SECTRANSP
+ CURL_USE_OPENSSL
+ CURL_USE_MBEDTLS
+ CURL_USE_BEARSSL
+ CURL_USE_WOLFSSL
+)
+if(enabled_ssl_options_count GREATER "1")
+ set(CURL_WITH_MULTI_SSL ON)
+endif()
+
+if(CURL_USE_SCHANNEL)
+ set(SSL_ENABLED ON)
+ set(USE_SCHANNEL ON) # Windows native SSL/TLS support
+ set(USE_WINDOWS_SSPI ON) # CURL_USE_SCHANNEL implies CURL_WINDOWS_SSPI
+
+ if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "schannel")
+ set(valid_default_ssl_backend TRUE)
+ endif()
+endif()
+if(CURL_WINDOWS_SSPI)
+ set(USE_WINDOWS_SSPI ON)
+endif()
+
+if(CURL_USE_SECTRANSP)
+ set(use_core_foundation_and_core_services ON)
+
+ find_library(SECURITY_FRAMEWORK "Security")
+ if(NOT SECURITY_FRAMEWORK)
+ message(FATAL_ERROR "Security framework not found")
+ endif()
+
+ set(SSL_ENABLED ON)
+ set(USE_SECTRANSP ON)
+ list(APPEND CURL_LIBS "-framework Security")
+
+ if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "secure-transport")
+ set(valid_default_ssl_backend TRUE)
+ endif()
+endif()
+
+if(use_core_foundation_and_core_services)
+ find_library(COREFOUNDATION_FRAMEWORK "CoreFoundation")
+ find_library(CORESERVICES_FRAMEWORK "CoreServices")
+
+ if(NOT COREFOUNDATION_FRAMEWORK)
+ message(FATAL_ERROR "CoreFoundation framework not found")
+ endif()
+ if(NOT CORESERVICES_FRAMEWORK)
+ message(FATAL_ERROR "CoreServices framework not found")
+ endif()
+
+ list(APPEND CURL_LIBS "-framework CoreFoundation -framework CoreServices")
+endif()
+
+if(CURL_USE_OPENSSL)
+ find_package(OpenSSL REQUIRED)
+ set(SSL_ENABLED ON)
+ set(USE_OPENSSL ON)
+
+ # Depend on OpenSSL via imported targets if supported by the running
+ # version of CMake. This allows our dependents to get our dependencies
+ # transitively.
+ if(NOT CMAKE_VERSION VERSION_LESS 3.4)
+ list(APPEND CURL_LIBS OpenSSL::SSL OpenSSL::Crypto)
+ else()
+ list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
+ include_directories(${OPENSSL_INCLUDE_DIR})
+ endif()
+
+ if(WIN32)
+ list(APPEND CURL_LIBS "ws2_32")
+ list(APPEND CURL_LIBS "bcrypt") # for OpenSSL/LibreSSL
+ endif()
+
+ if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "openssl")
+ set(valid_default_ssl_backend TRUE)
+ endif()
+
+ set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
+ if(NOT DEFINED HAVE_BORINGSSL)
+ check_symbol_exists(OPENSSL_IS_BORINGSSL "openssl/base.h" HAVE_BORINGSSL)
+ endif()
+ if(NOT DEFINED HAVE_AWSLC)
+ check_symbol_exists(OPENSSL_IS_AWSLC "openssl/base.h" HAVE_AWSLC)
+ endif()
+endif()
+
+if(CURL_USE_MBEDTLS)
+ find_package(MbedTLS REQUIRED)
+ set(SSL_ENABLED ON)
+ set(USE_MBEDTLS ON)
+ list(APPEND CURL_LIBS ${MBEDTLS_LIBRARIES})
+ include_directories(${MBEDTLS_INCLUDE_DIRS})
+
+ if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "mbedtls")
+ set(valid_default_ssl_backend TRUE)
+ endif()
+endif()
+
+if(CURL_USE_BEARSSL)
+ find_package(BearSSL REQUIRED)
+ set(SSL_ENABLED ON)
+ set(USE_BEARSSL ON)
+ list(APPEND CURL_LIBS ${BEARSSL_LIBRARY})
+ include_directories(${BEARSSL_INCLUDE_DIRS})
+
+ if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "bearssl")
+ set(valid_default_ssl_backend TRUE)
+ endif()
+endif()
+
+if(CURL_USE_WOLFSSL)
+ find_package(WolfSSL REQUIRED)
+ set(SSL_ENABLED ON)
+ set(USE_WOLFSSL ON)
+ list(APPEND CURL_LIBS ${WolfSSL_LIBRARIES})
+ include_directories(${WolfSSL_INCLUDE_DIRS})
+
+ if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "wolfssl")
+ set(valid_default_ssl_backend TRUE)
+ endif()
+endif()
+
+if(CURL_USE_GNUTLS)
+ find_package(GnuTLS REQUIRED)
+ set(SSL_ENABLED ON)
+ set(USE_GNUTLS ON)
+ list(APPEND CURL_LIBS ${GNUTLS_LIBRARIES} "nettle")
+ include_directories(${GNUTLS_INCLUDE_DIRS})
+
+ if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "gnutls")
+ set(valid_default_ssl_backend TRUE)
+ endif()
+
+ if(NOT DEFINED HAVE_GNUTLS_SRP AND NOT CURL_DISABLE_SRP)
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_INCLUDES ${GNUTLS_INCLUDE_DIRS})
+ set(CMAKE_REQUIRED_LIBRARIES ${GNUTLS_LIBRARIES})
+ check_symbol_exists(gnutls_srp_verifier "gnutls/gnutls.h" HAVE_GNUTLS_SRP)
+ cmake_pop_check_state()
+ endif()
+endif()
+
+if(CURL_DEFAULT_SSL_BACKEND AND NOT valid_default_ssl_backend)
+ message(FATAL_ERROR "CURL_DEFAULT_SSL_BACKEND '${CURL_DEFAULT_SSL_BACKEND}' not enabled.")
+endif()
+
+# Keep ZLIB detection after TLS detection,
+# and before calling openssl_check_symbol_exists().
+
+set(HAVE_LIBZ OFF)
+set(USE_ZLIB OFF)
+optional_dependency(ZLIB)
+if(ZLIB_FOUND)
+ set(HAVE_LIBZ ON)
+ set(USE_ZLIB ON)
+
+ # Depend on ZLIB via imported targets if supported by the running
+ # version of CMake. This allows our dependents to get our dependencies
+ # transitively.
+ if(NOT CMAKE_VERSION VERSION_LESS 3.4)
+ list(APPEND CURL_LIBS ZLIB::ZLIB)
+ else()
+ list(APPEND CURL_LIBS ${ZLIB_LIBRARIES})
+ include_directories(${ZLIB_INCLUDE_DIRS})
+ endif()
+ list(APPEND CMAKE_REQUIRED_INCLUDES ${ZLIB_INCLUDE_DIRS})
+endif()
+
+option(CURL_BROTLI "Set to ON to enable building curl with brotli support." OFF)
+set(HAVE_BROTLI OFF)
+if(CURL_BROTLI)
+ find_package(Brotli REQUIRED)
+ if(BROTLI_FOUND)
+ set(HAVE_BROTLI ON)
+ set(CURL_LIBS "${BROTLI_LIBRARIES};${CURL_LIBS}") # For 'ld' linker. Emulate `list(PREPEND ...)` to stay compatible with \n")
+ endforeach()
+
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS -DLDAP_DEPRECATED=1)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LDAP_LIB})
+ if(HAVE_LIBLBER)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LBER_LIB})
+ endif()
+
+ check_c_source_compiles("
+ ${_INCLUDE_STRING}
+ int main(int argc, char ** argv)
+ {
+ BerValue *bvp = NULL;
+ BerElement *bep = ber_init(bvp);
+ ber_free(bep, 1);
+ return 0;
+ }" NOT_NEED_LBER_H)
+ if(NOT_NEED_LBER_H)
+ set(NEED_LBER_H OFF)
+ else()
+ set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -DNEED_LBER_H")
+ endif()
+
+ check_function_exists(ldap_url_parse HAVE_LDAP_URL_PARSE)
+ check_function_exists(ldap_init_fd HAVE_LDAP_INIT_FD)
+
+ unset(CMAKE_REQUIRED_LIBRARIES)
+
+ check_include_file("ldap_ssl.h" HAVE_LDAP_SSL_H)
+
+ if(HAVE_LDAP_INIT_FD)
+ set(USE_OPENLDAP ON)
+ add_definitions("-DLDAP_DEPRECATED=1")
+ endif()
+ if(NOT CURL_DISABLE_LDAPS)
+ set(HAVE_LDAP_SSL ON)
+ endif()
+ endif()
+ endif()
+endif()
+
+# No ldap, no ldaps.
+if(CURL_DISABLE_LDAP)
+ if(NOT CURL_DISABLE_LDAPS)
+ message(STATUS "LDAP needs to be enabled to support LDAPS")
+ set(CURL_DISABLE_LDAPS ON CACHE BOOL "" FORCE)
+ endif()
+endif()
+
+# Check for idn2
+option(USE_LIBIDN2 "Use libidn2 for IDN support" ON)
+if(USE_LIBIDN2)
+ check_library_exists_concat("idn2" idn2_lookup_ul HAVE_LIBIDN2)
+else()
+ set(HAVE_LIBIDN2 OFF)
+endif()
+
+if(WIN32)
+ option(USE_WIN32_IDN "Use WinIDN for IDN support" OFF)
+ if(USE_WIN32_IDN)
+ list(APPEND CURL_LIBS "normaliz")
+ endif()
+endif()
+
+#libpsl
+option(CURL_USE_LIBPSL "Use libPSL" ON)
+mark_as_advanced(CURL_USE_LIBPSL)
+set(USE_LIBPSL OFF)
+
+if(CURL_USE_LIBPSL)
+ find_package(LibPSL)
+ if(LIBPSL_FOUND)
+ list(APPEND CURL_LIBS ${LIBPSL_LIBRARY})
+ list(APPEND CMAKE_REQUIRED_INCLUDES "${LIBPSL_INCLUDE_DIR}")
+ include_directories("${LIBPSL_INCLUDE_DIR}")
+ set(USE_LIBPSL ON)
+ endif()
+endif()
+
+#libSSH2
+option(CURL_USE_LIBSSH2 "Use libSSH2" ON)
+mark_as_advanced(CURL_USE_LIBSSH2)
+set(USE_LIBSSH2 OFF)
+
+if(CURL_USE_LIBSSH2)
+ find_package(LibSSH2)
+ if(LIBSSH2_FOUND)
+ list(APPEND CURL_LIBS ${LIBSSH2_LIBRARY})
+ list(APPEND CMAKE_REQUIRED_INCLUDES "${LIBSSH2_INCLUDE_DIR}")
+ include_directories("${LIBSSH2_INCLUDE_DIR}")
+ set(USE_LIBSSH2 ON)
+ endif()
+endif()
+
+# libssh
+option(CURL_USE_LIBSSH "Use libSSH" OFF)
+mark_as_advanced(CURL_USE_LIBSSH)
+if(NOT USE_LIBSSH2 AND CURL_USE_LIBSSH)
+ find_package(libssh CONFIG)
+ if(libssh_FOUND)
+ message(STATUS "Found libssh ${libssh_VERSION}")
+ # Use imported target for include and library paths.
+ list(APPEND CURL_LIBS ssh)
+ set(USE_LIBSSH ON)
+ endif()
+endif()
+
+option(CURL_USE_GSSAPI "Use GSSAPI implementation (right now only Heimdal is supported with CMake build)" OFF)
+mark_as_advanced(CURL_USE_GSSAPI)
+
+if(CURL_USE_GSSAPI)
+ find_package(GSS)
+
+ set(HAVE_GSSAPI ${GSS_FOUND})
+ if(GSS_FOUND)
+
+ message(STATUS "Found ${GSS_FLAVOUR} GSSAPI version: \"${GSS_VERSION}\"")
+
+ list(APPEND CMAKE_REQUIRED_INCLUDES ${GSS_INCLUDE_DIR})
+ check_include_file_concat("gssapi/gssapi.h" HAVE_GSSAPI_GSSAPI_H)
+ check_include_file_concat("gssapi/gssapi_generic.h" HAVE_GSSAPI_GSSAPI_GENERIC_H)
+ check_include_file_concat("gssapi/gssapi_krb5.h" HAVE_GSSAPI_GSSAPI_KRB5_H)
+
+ if(GSS_FLAVOUR STREQUAL "Heimdal")
+ set(HAVE_GSSHEIMDAL ON)
+ else() # MIT
+ set(HAVE_GSSMIT ON)
+ set(_INCLUDE_LIST "")
+ if(HAVE_GSSAPI_GSSAPI_H)
+ list(APPEND _INCLUDE_LIST "gssapi/gssapi.h")
+ endif()
+ if(HAVE_GSSAPI_GSSAPI_GENERIC_H)
+ list(APPEND _INCLUDE_LIST "gssapi/gssapi_generic.h")
+ endif()
+ if(HAVE_GSSAPI_GSSAPI_KRB5_H)
+ list(APPEND _INCLUDE_LIST "gssapi/gssapi_krb5.h")
+ endif()
+
+ string(REPLACE ";" " " _COMPILER_FLAGS_STR "${GSS_COMPILER_FLAGS}")
+ string(REPLACE ";" " " _LINKER_FLAGS_STR "${GSS_LINKER_FLAGS}")
+
+ foreach(_dir ${GSS_LINK_DIRECTORIES})
+ set(_LINKER_FLAGS_STR "${_LINKER_FLAGS_STR} -L\"${_dir}\"")
+ endforeach()
+
+ if(NOT DEFINED HAVE_GSS_C_NT_HOSTBASED_SERVICE)
+ set(CMAKE_REQUIRED_FLAGS "${_COMPILER_FLAGS_STR} ${_LINKER_FLAGS_STR}")
+ set(CMAKE_REQUIRED_LIBRARIES ${GSS_LIBRARIES})
+ check_symbol_exists("GSS_C_NT_HOSTBASED_SERVICE" ${_INCLUDE_LIST} HAVE_GSS_C_NT_HOSTBASED_SERVICE)
+ unset(CMAKE_REQUIRED_LIBRARIES)
+ endif()
+ if(NOT HAVE_GSS_C_NT_HOSTBASED_SERVICE)
+ set(HAVE_OLD_GSSMIT ON)
+ endif()
+ endif()
+
+ include_directories(${GSS_INCLUDE_DIR})
+ link_directories(${GSS_LINK_DIRECTORIES})
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GSS_COMPILER_FLAGS}")
+ string(REPLACE ";" " " GSS_LINKER_FLAGS "${GSS_LINKER_FLAGS}")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GSS_LINKER_FLAGS}")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GSS_LINKER_FLAGS}")
+ set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} ${GSS_LINKER_FLAGS}")
+ list(APPEND CURL_LIBS ${GSS_LIBRARIES})
+
+ else()
+ message(WARNING "GSSAPI support has been requested but no supporting libraries found. Skipping.")
+ endif()
+endif()
+
+option(ENABLE_UNIX_SOCKETS "Define if you want Unix domain sockets support" ON)
+if(ENABLE_UNIX_SOCKETS)
+ include(CheckStructHasMember)
+ if(WIN32)
+ set(USE_UNIX_SOCKETS ON)
+ else()
+ check_struct_has_member("struct sockaddr_un" sun_path "sys/un.h" USE_UNIX_SOCKETS)
+ endif()
+else()
+ unset(USE_UNIX_SOCKETS CACHE)
+endif()
+
+
+#
+# CA handling
+#
+set(CURL_CA_BUNDLE "auto" CACHE STRING
+ "Path to the CA bundle. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.")
+set(CURL_CA_FALLBACK OFF CACHE BOOL
+ "Set ON to use built-in CA store of TLS backend. Defaults to OFF")
+set(CURL_CA_PATH "auto" CACHE STRING
+ "Location of default CA path. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.")
+
+if("${CURL_CA_BUNDLE}" STREQUAL "")
+ message(FATAL_ERROR "Invalid value of CURL_CA_BUNDLE. Use 'none', 'auto' or file path.")
+elseif("${CURL_CA_BUNDLE}" STREQUAL "none")
+ unset(CURL_CA_BUNDLE CACHE)
+elseif("${CURL_CA_BUNDLE}" STREQUAL "auto")
+ unset(CURL_CA_BUNDLE CACHE)
+ if(NOT CMAKE_CROSSCOMPILING)
+ set(CURL_CA_BUNDLE_AUTODETECT TRUE)
+ endif()
+else()
+ set(CURL_CA_BUNDLE_SET TRUE)
+endif()
+
+if("${CURL_CA_PATH}" STREQUAL "")
+ message(FATAL_ERROR "Invalid value of CURL_CA_PATH. Use 'none', 'auto' or directory path.")
+elseif("${CURL_CA_PATH}" STREQUAL "none")
+ unset(CURL_CA_PATH CACHE)
+elseif("${CURL_CA_PATH}" STREQUAL "auto")
+ unset(CURL_CA_PATH CACHE)
+ if(NOT CMAKE_CROSSCOMPILING)
+ set(CURL_CA_PATH_AUTODETECT TRUE)
+ endif()
+else()
+ set(CURL_CA_PATH_SET TRUE)
+endif()
+
+if(CURL_CA_BUNDLE_SET AND CURL_CA_PATH_AUTODETECT)
+ # Skip autodetection of unset CA path because CA bundle is set explicitly
+elseif(CURL_CA_PATH_SET AND CURL_CA_BUNDLE_AUTODETECT)
+ # Skip autodetection of unset CA bundle because CA path is set explicitly
+elseif(CURL_CA_PATH_AUTODETECT OR CURL_CA_BUNDLE_AUTODETECT)
+ # first try autodetecting a CA bundle, then a CA path
+
+ if(CURL_CA_BUNDLE_AUTODETECT)
+ set(SEARCH_CA_BUNDLE_PATHS
+ /etc/ssl/certs/ca-certificates.crt
+ /etc/pki/tls/certs/ca-bundle.crt
+ /usr/share/ssl/certs/ca-bundle.crt
+ /usr/local/share/certs/ca-root-nss.crt
+ /etc/ssl/cert.pem)
+
+ foreach(SEARCH_CA_BUNDLE_PATH ${SEARCH_CA_BUNDLE_PATHS})
+ if(EXISTS "${SEARCH_CA_BUNDLE_PATH}")
+ message(STATUS "Found CA bundle: ${SEARCH_CA_BUNDLE_PATH}")
+ set(CURL_CA_BUNDLE "${SEARCH_CA_BUNDLE_PATH}" CACHE STRING
+ "Path to the CA bundle. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.")
+ set(CURL_CA_BUNDLE_SET TRUE CACHE BOOL "Path to the CA bundle has been set")
+ break()
+ endif()
+ endforeach()
+ endif()
+
+ if(CURL_CA_PATH_AUTODETECT AND (NOT CURL_CA_PATH_SET))
+ if(EXISTS "/etc/ssl/certs")
+ set(CURL_CA_PATH "/etc/ssl/certs" CACHE STRING
+ "Location of default CA path. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.")
+ set(CURL_CA_PATH_SET TRUE CACHE BOOL "Path to the CA bundle has been set")
+ endif()
+ endif()
+endif()
+
+if(CURL_CA_PATH_SET AND
+ NOT USE_OPENSSL AND
+ NOT USE_WOLFSSL AND
+ NOT USE_GNUTLS AND
+ NOT USE_MBEDTLS)
+ message(STATUS
+ "CA path only supported by OpenSSL, wolfSSL, GnuTLS or mbedTLS. "
+ "Set CURL_CA_PATH=none or enable one of those TLS backends.")
+endif()
+
+# Check for header files
+if(NOT UNIX)
+ check_include_file_concat("windows.h" HAVE_WINDOWS_H)
+ check_include_file_concat("ws2tcpip.h" HAVE_WS2TCPIP_H)
+ check_include_file_concat("winsock2.h" HAVE_WINSOCK2_H)
+endif()
+
+check_include_file_concat("inttypes.h" HAVE_INTTYPES_H)
+check_include_file_concat("sys/filio.h" HAVE_SYS_FILIO_H)
+check_include_file_concat("sys/wait.h" HAVE_SYS_WAIT_H)
+check_include_file_concat("sys/ioctl.h" HAVE_SYS_IOCTL_H)
+check_include_file_concat("sys/param.h" HAVE_SYS_PARAM_H)
+check_include_file_concat("sys/poll.h" HAVE_SYS_POLL_H)
+check_include_file_concat("sys/resource.h" HAVE_SYS_RESOURCE_H)
+check_include_file_concat("sys/select.h" HAVE_SYS_SELECT_H)
+check_include_file_concat("sys/socket.h" HAVE_SYS_SOCKET_H)
+check_include_file_concat("sys/sockio.h" HAVE_SYS_SOCKIO_H)
+check_include_file_concat("sys/stat.h" HAVE_SYS_STAT_H)
+check_include_file_concat("sys/time.h" HAVE_SYS_TIME_H)
+check_include_file_concat("sys/types.h" HAVE_SYS_TYPES_H)
+check_include_file_concat("sys/un.h" HAVE_SYS_UN_H)
+check_include_file_concat("sys/utime.h" HAVE_SYS_UTIME_H)
+check_include_file_concat("sys/xattr.h" HAVE_SYS_XATTR_H)
+check_include_file_concat("arpa/inet.h" HAVE_ARPA_INET_H)
+check_include_file_concat("fcntl.h" HAVE_FCNTL_H)
+check_include_file_concat("idn2.h" HAVE_IDN2_H)
+check_include_file_concat("ifaddrs.h" HAVE_IFADDRS_H)
+check_include_file_concat("io.h" HAVE_IO_H)
+check_include_file_concat("libgen.h" HAVE_LIBGEN_H)
+check_include_file_concat("locale.h" HAVE_LOCALE_H)
+check_include_file_concat("net/if.h" HAVE_NET_IF_H)
+check_include_file_concat("netdb.h" HAVE_NETDB_H)
+check_include_file_concat("netinet/in.h" HAVE_NETINET_IN_H)
+check_include_file_concat("netinet/tcp.h" HAVE_NETINET_TCP_H)
+check_include_file_concat("netinet/udp.h" HAVE_NETINET_UDP_H)
+check_include_file("linux/tcp.h" HAVE_LINUX_TCP_H)
+
+check_include_file_concat("poll.h" HAVE_POLL_H)
+check_include_file_concat("pwd.h" HAVE_PWD_H)
+check_include_file_concat("stdatomic.h" HAVE_STDATOMIC_H)
+check_include_file_concat("stdbool.h" HAVE_STDBOOL_H)
+check_include_file_concat("stdint.h" HAVE_STDINT_H)
+check_include_file_concat("strings.h" HAVE_STRINGS_H)
+check_include_file_concat("stropts.h" HAVE_STROPTS_H)
+check_include_file_concat("termio.h" HAVE_TERMIO_H)
+check_include_file_concat("termios.h" HAVE_TERMIOS_H)
+check_include_file_concat("unistd.h" HAVE_UNISTD_H)
+check_include_file_concat("utime.h" HAVE_UTIME_H)
+
+check_type_size(size_t SIZEOF_SIZE_T)
+check_type_size(ssize_t SIZEOF_SSIZE_T)
+check_type_size("long long" SIZEOF_LONG_LONG)
+check_type_size("long" SIZEOF_LONG)
+check_type_size("int" SIZEOF_INT)
+check_type_size("__int64" SIZEOF___INT64)
+check_type_size("time_t" SIZEOF_TIME_T)
+check_type_size("suseconds_t" SIZEOF_SUSECONDS_T)
+if(NOT HAVE_SIZEOF_SSIZE_T)
+ if(SIZEOF_LONG EQUAL SIZEOF_SIZE_T)
+ set(ssize_t long)
+ endif()
+ if(NOT ssize_t AND SIZEOF___INT64 EQUAL SIZEOF_SIZE_T)
+ set(ssize_t __int64)
+ endif()
+endif()
+# off_t is sized later, after the HAVE_FILE_OFFSET_BITS test
+
+if(SIZEOF_LONG_LONG)
+ set(HAVE_LONGLONG 1)
+endif()
+if(SIZEOF_SUSECONDS_T)
+ set(HAVE_SUSECONDS_T 1)
+endif()
+
+if(NOT CMAKE_CROSSCOMPILING)
+ find_file(RANDOM_FILE urandom /dev)
+ mark_as_advanced(RANDOM_FILE)
+endif()
+
+# Check for some functions that are used
+if(WIN32)
+ set(CMAKE_REQUIRED_LIBRARIES ws2_32)
+elseif(HAVE_LIBSOCKET)
+ set(CMAKE_REQUIRED_LIBRARIES socket)
+endif()
+
+check_symbol_exists(fchmod "${CURL_INCLUDES}" HAVE_FCHMOD)
+check_symbol_exists(fnmatch "${CURL_INCLUDES};fnmatch.h" HAVE_FNMATCH)
+check_symbol_exists(basename "${CURL_INCLUDES};string.h" HAVE_BASENAME)
+check_symbol_exists(socket "${CURL_INCLUDES}" HAVE_SOCKET)
+check_symbol_exists(sched_yield "${CURL_INCLUDES};sched.h" HAVE_SCHED_YIELD)
+check_symbol_exists(socketpair "${CURL_INCLUDES}" HAVE_SOCKETPAIR)
+check_symbol_exists(recv "${CURL_INCLUDES}" HAVE_RECV)
+check_symbol_exists(send "${CURL_INCLUDES}" HAVE_SEND)
+check_symbol_exists(sendmsg "${CURL_INCLUDES}" HAVE_SENDMSG)
+check_symbol_exists(select "${CURL_INCLUDES}" HAVE_SELECT)
+check_symbol_exists(strdup "${CURL_INCLUDES};string.h" HAVE_STRDUP)
+check_symbol_exists(strtok_r "${CURL_INCLUDES};string.h" HAVE_STRTOK_R)
+check_symbol_exists(strcasecmp "${CURL_INCLUDES};string.h" HAVE_STRCASECMP)
+check_symbol_exists(stricmp "${CURL_INCLUDES};string.h" HAVE_STRICMP)
+check_symbol_exists(strcmpi "${CURL_INCLUDES};string.h" HAVE_STRCMPI)
+check_symbol_exists(memrchr "${CURL_INCLUDES};string.h" HAVE_MEMRCHR)
+check_symbol_exists(alarm "${CURL_INCLUDES}" HAVE_ALARM)
+check_symbol_exists(arc4random "${CURL_INCLUDES};stdlib.h" HAVE_ARC4RANDOM)
+check_symbol_exists(fcntl "${CURL_INCLUDES}" HAVE_FCNTL)
+check_symbol_exists(getppid "${CURL_INCLUDES}" HAVE_GETPPID)
+check_symbol_exists(utimes "${CURL_INCLUDES}" HAVE_UTIMES)
+
+check_symbol_exists(gettimeofday "${CURL_INCLUDES}" HAVE_GETTIMEOFDAY)
+check_symbol_exists(closesocket "${CURL_INCLUDES}" HAVE_CLOSESOCKET)
+check_symbol_exists(sigsetjmp "${CURL_INCLUDES};setjmp.h" HAVE_SIGSETJMP)
+check_symbol_exists(getpass_r "${CURL_INCLUDES}" HAVE_GETPASS_R)
+check_symbol_exists(getpwuid "${CURL_INCLUDES}" HAVE_GETPWUID)
+check_symbol_exists(getpwuid_r "${CURL_INCLUDES}" HAVE_GETPWUID_R)
+check_symbol_exists(geteuid "${CURL_INCLUDES}" HAVE_GETEUID)
+check_symbol_exists(utime "${CURL_INCLUDES}" HAVE_UTIME)
+check_symbol_exists(gmtime_r "${CURL_INCLUDES};stdlib.h;time.h" HAVE_GMTIME_R)
+
+check_symbol_exists(gethostbyname_r "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME_R)
+
+check_symbol_exists(signal "${CURL_INCLUDES};signal.h" HAVE_SIGNAL)
+check_symbol_exists(strtoll "${CURL_INCLUDES};stdlib.h" HAVE_STRTOLL)
+check_symbol_exists(strerror_r "${CURL_INCLUDES};stdlib.h;string.h" HAVE_STRERROR_R)
+check_symbol_exists(siginterrupt "${CURL_INCLUDES};signal.h" HAVE_SIGINTERRUPT)
+check_symbol_exists(getaddrinfo "${CURL_INCLUDES};stdlib.h;string.h" HAVE_GETADDRINFO)
+check_symbol_exists(getifaddrs "${CURL_INCLUDES};stdlib.h" HAVE_GETIFADDRS)
+check_symbol_exists(freeaddrinfo "${CURL_INCLUDES}" HAVE_FREEADDRINFO)
+check_symbol_exists(pipe "${CURL_INCLUDES}" HAVE_PIPE)
+check_symbol_exists(ftruncate "${CURL_INCLUDES}" HAVE_FTRUNCATE)
+check_symbol_exists(fseeko "${CURL_INCLUDES};stdio.h" HAVE_FSEEKO)
+check_symbol_exists(_fseeki64 "${CURL_INCLUDES};stdio.h" HAVE__FSEEKI64)
+check_symbol_exists(getpeername "${CURL_INCLUDES}" HAVE_GETPEERNAME)
+check_symbol_exists(getsockname "${CURL_INCLUDES}" HAVE_GETSOCKNAME)
+check_symbol_exists(if_nametoindex "${CURL_INCLUDES}" HAVE_IF_NAMETOINDEX)
+check_symbol_exists(getrlimit "${CURL_INCLUDES}" HAVE_GETRLIMIT)
+check_symbol_exists(setlocale "${CURL_INCLUDES}" HAVE_SETLOCALE)
+check_symbol_exists(setmode "${CURL_INCLUDES}" HAVE_SETMODE)
+check_symbol_exists(setrlimit "${CURL_INCLUDES}" HAVE_SETRLIMIT)
+
+if(NOT MSVC OR (MSVC_VERSION GREATER_EQUAL 1900))
+ # earlier MSVC compilers had faulty snprintf implementations
+ check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF)
+endif()
+check_function_exists(mach_absolute_time HAVE_MACH_ABSOLUTE_TIME)
+check_symbol_exists(inet_ntop "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_NTOP)
+if(MSVC AND (MSVC_VERSION LESS_EQUAL 1600))
+ set(HAVE_INET_NTOP OFF)
+endif()
+check_symbol_exists(inet_pton "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_PTON)
+
+check_symbol_exists(fsetxattr "${CURL_INCLUDES}" HAVE_FSETXATTR)
+if(HAVE_FSETXATTR)
+ foreach(CURL_TEST HAVE_FSETXATTR_5 HAVE_FSETXATTR_6)
+ curl_internal_test(${CURL_TEST})
+ endforeach()
+endif()
+
+set(CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h")
+check_type_size("sa_family_t" SIZEOF_SA_FAMILY_T)
+set(HAVE_SA_FAMILY_T ${HAVE_SIZEOF_SA_FAMILY_T})
+set(CMAKE_EXTRA_INCLUDE_FILES "")
+
+set(CMAKE_EXTRA_INCLUDE_FILES "ws2def.h")
+check_type_size("ADDRESS_FAMILY" SIZEOF_ADDRESS_FAMILY)
+set(HAVE_ADDRESS_FAMILY ${HAVE_SIZEOF_ADDRESS_FAMILY})
+set(CMAKE_EXTRA_INCLUDE_FILES "")
+
+# sigaction and sigsetjmp are special. Use special mechanism for
+# detecting those, but only if previous attempt failed.
+check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION)
+
+if(NOT HAVE_SIGSETJMP)
+ check_symbol_exists(sigsetjmp "setjmp.h" HAVE_MACRO_SIGSETJMP)
+ if(HAVE_MACRO_SIGSETJMP)
+ set(HAVE_SIGSETJMP 1)
+ endif()
+endif()
+
+# Do curl specific tests
+foreach(CURL_TEST
+ HAVE_FCNTL_O_NONBLOCK
+ HAVE_IOCTLSOCKET
+ HAVE_IOCTLSOCKET_CAMEL
+ HAVE_IOCTLSOCKET_CAMEL_FIONBIO
+ HAVE_IOCTLSOCKET_FIONBIO
+ HAVE_IOCTL_FIONBIO
+ HAVE_IOCTL_SIOCGIFADDR
+ HAVE_SETSOCKOPT_SO_NONBLOCK
+ HAVE_O_NONBLOCK
+ HAVE_GETHOSTBYNAME_R_3
+ HAVE_GETHOSTBYNAME_R_5
+ HAVE_GETHOSTBYNAME_R_6
+ HAVE_GETHOSTBYNAME_R_3_REENTRANT
+ HAVE_GETHOSTBYNAME_R_5_REENTRANT
+ HAVE_GETHOSTBYNAME_R_6_REENTRANT
+ HAVE_IN_ADDR_T
+ HAVE_BOOL_T
+ STDC_HEADERS
+ HAVE_FILE_OFFSET_BITS
+ HAVE_VARIADIC_MACROS_C99
+ HAVE_VARIADIC_MACROS_GCC
+ HAVE_ATOMIC
+ )
+ curl_internal_test(${CURL_TEST})
+endforeach()
+
+if(HAVE_FILE_OFFSET_BITS)
+ set(_FILE_OFFSET_BITS 64)
+ set(CMAKE_REQUIRED_FLAGS "-D_FILE_OFFSET_BITS=64")
+endif()
+check_type_size("off_t" SIZEOF_OFF_T)
+
+# include this header to get the type
+set(CMAKE_REQUIRED_INCLUDES "${CURL_SOURCE_DIR}/include")
+set(CMAKE_EXTRA_INCLUDE_FILES "curl/system.h")
+check_type_size("curl_off_t" SIZEOF_CURL_OFF_T)
+set(CMAKE_EXTRA_INCLUDE_FILES "curl/curl.h")
+check_type_size("curl_socket_t" SIZEOF_CURL_SOCKET_T)
+set(CMAKE_EXTRA_INCLUDE_FILES "")
+
+if(WIN32)
+ # detect actual value of _WIN32_WINNT and store as HAVE_WIN32_WINNT
+ curl_internal_test(HAVE_WIN32_WINNT)
+ if(HAVE_WIN32_WINNT)
+ string(REGEX MATCH ".*_WIN32_WINNT=0x[0-9a-fA-F]+" OUTPUT "${OUTPUT}")
+ string(REGEX REPLACE ".*_WIN32_WINNT=" "" HAVE_WIN32_WINNT "${OUTPUT}")
+ message(STATUS "Found _WIN32_WINNT=${HAVE_WIN32_WINNT}")
+ endif()
+ # avoid storing HAVE_WIN32_WINNT in CMake cache
+ unset(HAVE_WIN32_WINNT CACHE)
+endif()
+
+if(NOT WIN32 AND NOT CMAKE_CROSSCOMPILING)
+ # on not-Windows and not-crosscompiling, check for writable argv[]
+ include(CheckCSourceRuns)
+ check_c_source_runs("
+ int main(int argc, char **argv)
+ {
+ (void)argc;
+ argv[0][0] = ' ';
+ return (argv[0][0] == ' ')?0:1;
+ }" HAVE_WRITABLE_ARGV)
+endif()
+
+set(CMAKE_REQUIRED_FLAGS)
+
+option(ENABLE_WEBSOCKETS "Set to ON to enable EXPERIMENTAL websockets" OFF)
+
+if(ENABLE_WEBSOCKETS)
+ if(${SIZEOF_CURL_OFF_T} GREATER "4")
+ set(USE_WEBSOCKETS ON)
+ else()
+ message(WARNING "curl_off_t is too small to enable WebSockets")
+ endif()
+endif()
+
+foreach(CURL_TEST
+ HAVE_GLIBC_STRERROR_R
+ HAVE_POSIX_STRERROR_R
+ )
+ curl_internal_test(${CURL_TEST})
+endforeach()
+
+# Check for reentrant
+foreach(CURL_TEST
+ HAVE_GETHOSTBYNAME_R_3
+ HAVE_GETHOSTBYNAME_R_5
+ HAVE_GETHOSTBYNAME_R_6)
+ if(NOT ${CURL_TEST})
+ if(${CURL_TEST}_REENTRANT)
+ set(NEED_REENTRANT 1)
+ endif()
+ endif()
+endforeach()
+
+if(NEED_REENTRANT)
+ foreach(CURL_TEST
+ HAVE_GETHOSTBYNAME_R_3
+ HAVE_GETHOSTBYNAME_R_5
+ HAVE_GETHOSTBYNAME_R_6)
+ set(${CURL_TEST} 0)
+ if(${CURL_TEST}_REENTRANT)
+ set(${CURL_TEST} 1)
+ endif()
+ endforeach()
+endif()
+
+# Check clock_gettime(CLOCK_MONOTONIC, x) support
+curl_internal_test(HAVE_CLOCK_GETTIME_MONOTONIC)
+
+# Check compiler support of __builtin_available()
+curl_internal_test(HAVE_BUILTIN_AVAILABLE)
+
+# Some other minor tests
+
+if(NOT HAVE_IN_ADDR_T)
+ set(in_addr_t "unsigned long")
+endif()
+
+# Check for nonblocking
+set(HAVE_DISABLED_NONBLOCKING 1)
+if(HAVE_FIONBIO OR
+ HAVE_IOCTLSOCKET OR
+ HAVE_IOCTLSOCKET_CASE OR
+ HAVE_O_NONBLOCK)
+ set(HAVE_DISABLED_NONBLOCKING)
+endif()
+
+if(CMAKE_COMPILER_IS_GNUCC AND APPLE)
+ include(CheckCCompilerFlag)
+ check_c_compiler_flag(-Wno-long-double HAVE_C_FLAG_Wno_long_double)
+ if(HAVE_C_FLAG_Wno_long_double)
+ # The Mac version of GCC warns about use of long double. Disable it.
+ get_source_file_property(MPRINTF_COMPILE_FLAGS mprintf.c COMPILE_FLAGS)
+ if(MPRINTF_COMPILE_FLAGS)
+ set(MPRINTF_COMPILE_FLAGS "${MPRINTF_COMPILE_FLAGS} -Wno-long-double")
+ else()
+ set(MPRINTF_COMPILE_FLAGS "-Wno-long-double")
+ endif()
+ set_source_files_properties(mprintf.c PROPERTIES
+ COMPILE_FLAGS ${MPRINTF_COMPILE_FLAGS})
+ endif()
+endif()
+
+# TODO test which of these headers are required
+if(WIN32)
+ set(CURL_PULL_WS2TCPIP_H ${HAVE_WS2TCPIP_H})
+else()
+ set(CURL_PULL_SYS_TYPES_H ${HAVE_SYS_TYPES_H})
+ set(CURL_PULL_SYS_SOCKET_H ${HAVE_SYS_SOCKET_H})
+ set(CURL_PULL_SYS_POLL_H ${HAVE_SYS_POLL_H})
+endif()
+
+include(CMake/OtherTests.cmake)
+
+add_definitions(-DHAVE_CONFIG_H)
+
+# For Windows, all compilers used by CMake should support large files
+if(WIN32)
+ set(USE_WIN32_LARGE_FILES ON)
+
+ # Use the manifest embedded in the Windows Resource
+ set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} -DCURL_EMBED_MANIFEST")
+
+ # We use crypto functions that are not available for UWP apps
+ if(NOT WINDOWS_STORE)
+ set(USE_WIN32_CRYPTO ON)
+ endif()
+
+ # Link required libraries for USE_WIN32_CRYPTO or USE_SCHANNEL
+ if(USE_WIN32_CRYPTO OR USE_SCHANNEL)
+ list(APPEND CURL_LIBS "advapi32" "crypt32")
+ endif()
+
+ list(APPEND CURL_LIBS "bcrypt")
+endif()
+
+if(MSVC)
+ # Disable default manifest added by CMake
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO")
+
+ add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
+ if(CMAKE_C_FLAGS MATCHES "/W[0-4]")
+ string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
+ else()
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4")
+ endif()
+
+ # Use multithreaded compilation on VS 2008+
+ if(MSVC_VERSION GREATER_EQUAL 1500)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP")
+ endif()
+endif()
+
+if(CURL_WERROR)
+ if(MSVC_VERSION)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
+ else()
+ # this assumes clang or gcc style options
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
+ endif()
+endif()
+
+if(CURL_LTO)
+ if(CMAKE_VERSION VERSION_LESS 3.9)
+ message(FATAL_ERROR "Requested LTO but your cmake version ${CMAKE_VERSION} is to old. You need at least 3.9")
+ endif()
+
+ cmake_policy(SET CMP0069 NEW)
+
+ include(CheckIPOSupported)
+ check_ipo_supported(RESULT CURL_HAS_LTO OUTPUT CURL_LTO_ERROR LANGUAGES C)
+ if(CURL_HAS_LTO)
+ message(STATUS "LTO supported and enabled")
+ else()
+ message(FATAL_ERROR "LTO was requested - but compiler doesn't support it\n${CURL_LTO_ERROR}")
+ endif()
+endif()
+
+
+# Ugly (but functional) way to include "Makefile.inc" by transforming it (= regenerate it).
+function(transform_makefile_inc INPUT_FILE OUTPUT_FILE)
+ file(READ ${INPUT_FILE} MAKEFILE_INC_TEXT)
+ string(REPLACE "$(top_srcdir)" "\${CURL_SOURCE_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
+ string(REPLACE "$(top_builddir)" "\${CURL_BINARY_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
+
+ string(REGEX REPLACE "\\\\\n" "!π!α!" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
+ string(REGEX REPLACE "([a-zA-Z_][a-zA-Z0-9_]*)[\t ]*=[\t ]*([^\n]*)" "SET(\\1 \\2)" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
+ string(REPLACE "!π!α!" "\n" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
+
+ string(REGEX REPLACE "\\$\\(([a-zA-Z_][a-zA-Z0-9_]*)\\)" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) # Replace $() with ${}
+ string(REGEX REPLACE "@([a-zA-Z_][a-zA-Z0-9_]*)@" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) # Replace @@ with ${}, even if that may not be read by CMake scripts.
+ file(WRITE ${OUTPUT_FILE} ${MAKEFILE_INC_TEXT})
+ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${INPUT_FILE}")
+endfunction()
+
+include(GNUInstallDirs)
+
+set(CURL_INSTALL_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
+set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
+set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated")
+set(project_config "${generated_dir}/${PROJECT_NAME}Config.cmake")
+set(version_config "${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake")
+
+if(USE_MANUAL)
+ add_subdirectory(docs)
+endif()
+
+add_subdirectory(lib)
+
+if(BUILD_CURL_EXE)
+ add_subdirectory(src)
+endif()
+
+cmake_dependent_option(BUILD_TESTING "Build tests"
+ ON "PERL_FOUND;NOT CURL_DISABLE_TESTS"
+ OFF)
+if(BUILD_TESTING)
+ add_subdirectory(tests)
+endif()
+
+# Helper to populate a list (_items) with a label when conditions (the remaining
+# args) are satisfied
+macro(_add_if label)
+ # needs to be a macro to allow this indirection
+ if(${ARGN})
+ set(_items ${_items} "${label}")
+ endif()
+endmacro()
+
+# NTLM support requires crypto function adaptions from various SSL libs
+# TODO alternative SSL libs tests for SSP1, GnuTLS, NSS
+if(NOT (CURL_DISABLE_NTLM) AND
+ (USE_OPENSSL OR USE_MBEDTLS OR USE_DARWINSSL OR USE_WIN32_CRYPTO OR USE_GNUTLS))
+ set(use_curl_ntlm_core ON)
+endif()
+
+# Clear list and try to detect available features
+set(_items)
+_add_if("SSL" SSL_ENABLED)
+_add_if("IPv6" ENABLE_IPV6)
+_add_if("unixsockets" USE_UNIX_SOCKETS)
+_add_if("libz" HAVE_LIBZ)
+_add_if("brotli" HAVE_BROTLI)
+_add_if("zstd" HAVE_ZSTD)
+_add_if("AsynchDNS" USE_ARES OR USE_THREADS_POSIX OR USE_THREADS_WIN32)
+_add_if("IDN" HAVE_LIBIDN2 OR USE_WIN32_IDN)
+_add_if("Largefile" (SIZEOF_CURL_OFF_T GREATER 4) AND
+ ((SIZEOF_OFF_T GREATER 4) OR USE_WIN32_LARGE_FILES))
+# TODO SSP1 (Schannel) check is missing
+_add_if("SSPI" USE_WINDOWS_SSPI)
+_add_if("GSS-API" HAVE_GSSAPI)
+_add_if("alt-svc" NOT CURL_DISABLE_ALTSVC)
+_add_if("HSTS" NOT CURL_DISABLE_HSTS)
+# TODO SSP1 missing for SPNEGO
+_add_if("SPNEGO" NOT CURL_DISABLE_NEGOTIATE_AUTH AND
+ (HAVE_GSSAPI OR USE_WINDOWS_SSPI))
+_add_if("Kerberos" NOT CURL_DISABLE_KERBEROS_AUTH AND
+ (HAVE_GSSAPI OR USE_WINDOWS_SSPI))
+# NTLM support requires crypto function adaptions from various SSL libs
+# TODO alternative SSL libs tests for SSP1, GnuTLS, NSS
+_add_if("NTLM" NOT (CURL_DISABLE_NTLM) AND
+ (use_curl_ntlm_core OR USE_WINDOWS_SSPI))
+# TODO missing option (autoconf: --enable-ntlm-wb)
+_add_if("NTLM_WB" NOT (CURL_DISABLE_NTLM) AND
+ (use_curl_ntlm_core OR USE_WINDOWS_SSPI) AND
+ NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED)
+_add_if("TLS-SRP" USE_TLS_SRP)
+# TODO option --with-nghttp2 tests for nghttp2 lib and nghttp2/nghttp2.h header
+_add_if("HTTP2" USE_NGHTTP2)
+_add_if("HTTP3" USE_NGTCP2 OR USE_QUICHE)
+_add_if("MultiSSL" CURL_WITH_MULTI_SSL)
+# TODO wolfSSL only support this from v5.0.0 onwards
+_add_if("HTTPS-proxy" SSL_ENABLED AND (USE_OPENSSL OR USE_GNUTLS
+ OR USE_SCHANNEL OR USE_RUSTLS OR USE_BEARSSL OR
+ USE_MBEDTLS OR USE_SECTRANSP))
+_add_if("unicode" ENABLE_UNICODE)
+_add_if("threadsafe" HAVE_ATOMIC OR (WIN32 AND
+ HAVE_WIN32_WINNT GREATER_EQUAL 0x600))
+_add_if("PSL" USE_LIBPSL)
+string(REPLACE ";" " " SUPPORT_FEATURES "${_items}")
+message(STATUS "Enabled features: ${SUPPORT_FEATURES}")
+
+# Clear list and try to detect available protocols
+set(_items)
+_add_if("HTTP" NOT CURL_DISABLE_HTTP)
+_add_if("HTTPS" NOT CURL_DISABLE_HTTP AND SSL_ENABLED)
+_add_if("FTP" NOT CURL_DISABLE_FTP)
+_add_if("FTPS" NOT CURL_DISABLE_FTP AND SSL_ENABLED)
+_add_if("FILE" NOT CURL_DISABLE_FILE)
+_add_if("TELNET" NOT CURL_DISABLE_TELNET)
+_add_if("LDAP" NOT CURL_DISABLE_LDAP)
+# CURL_DISABLE_LDAP implies CURL_DISABLE_LDAPS
+_add_if("LDAPS" NOT CURL_DISABLE_LDAPS AND
+ ((USE_OPENLDAP AND SSL_ENABLED) OR
+ (NOT USE_OPENLDAP AND HAVE_LDAP_SSL)))
+_add_if("DICT" NOT CURL_DISABLE_DICT)
+_add_if("TFTP" NOT CURL_DISABLE_TFTP)
+_add_if("GOPHER" NOT CURL_DISABLE_GOPHER)
+_add_if("GOPHERS" NOT CURL_DISABLE_GOPHER AND SSL_ENABLED)
+_add_if("POP3" NOT CURL_DISABLE_POP3)
+_add_if("POP3S" NOT CURL_DISABLE_POP3 AND SSL_ENABLED)
+_add_if("IMAP" NOT CURL_DISABLE_IMAP)
+_add_if("IMAPS" NOT CURL_DISABLE_IMAP AND SSL_ENABLED)
+_add_if("SMB" NOT CURL_DISABLE_SMB AND
+ use_curl_ntlm_core AND (SIZEOF_CURL_OFF_T GREATER 4))
+_add_if("SMBS" NOT CURL_DISABLE_SMB AND SSL_ENABLED AND
+ use_curl_ntlm_core AND (SIZEOF_CURL_OFF_T GREATER 4))
+_add_if("SMTP" NOT CURL_DISABLE_SMTP)
+_add_if("SMTPS" NOT CURL_DISABLE_SMTP AND SSL_ENABLED)
+_add_if("SCP" USE_LIBSSH2 OR USE_LIBSSH)
+_add_if("SFTP" USE_LIBSSH2 OR USE_LIBSSH)
+_add_if("RTSP" NOT CURL_DISABLE_RTSP)
+_add_if("RTMP" USE_LIBRTMP)
+_add_if("MQTT" NOT CURL_DISABLE_MQTT)
+_add_if("WS" USE_WEBSOCKETS)
+_add_if("WSS" USE_WEBSOCKETS)
+if(_items)
+ list(SORT _items)
+endif()
+string(REPLACE ";" " " SUPPORT_PROTOCOLS "${_items}")
+message(STATUS "Enabled protocols: ${SUPPORT_PROTOCOLS}")
+
+# Clear list and collect SSL backends
+set(_items)
+_add_if("Schannel" SSL_ENABLED AND USE_SCHANNEL)
+_add_if("OpenSSL" SSL_ENABLED AND USE_OPENSSL)
+_add_if("Secure Transport" SSL_ENABLED AND USE_SECTRANSP)
+_add_if("mbedTLS" SSL_ENABLED AND USE_MBEDTLS)
+_add_if("BearSSL" SSL_ENABLED AND USE_BEARSSL)
+_add_if("wolfSSL" SSL_ENABLED AND USE_WOLFSSL)
+_add_if("GnuTLS" SSL_ENABLED AND USE_GNUTLS)
+
+if(_items)
+ list(SORT _items)
+endif()
+string(REPLACE ";" " " SSL_BACKENDS "${_items}")
+message(STATUS "Enabled SSL backends: ${SSL_BACKENDS}")
+if(CURL_DEFAULT_SSL_BACKEND)
+ message(STATUS "Default SSL backend: ${CURL_DEFAULT_SSL_BACKEND}")
+endif()
+
+# curl-config needs the following options to be set.
+set(CC "${CMAKE_C_COMPILER}")
+# TODO probably put a -D... options here?
+set(CONFIGURE_OPTIONS "")
+set(CURLVERSION "${CURL_VERSION}")
+set(exec_prefix "\${prefix}")
+set(includedir "\${prefix}/include")
+set(LDFLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
+set(LIBCURL_LIBS "")
+set(libdir "${CMAKE_INSTALL_PREFIX}/lib")
+foreach(_lib ${CMAKE_C_IMPLICIT_LINK_LIBRARIES} ${CURL_LIBS})
+ if(TARGET "${_lib}")
+ set(_libname "${_lib}")
+ get_target_property(_imported "${_libname}" IMPORTED)
+ if(NOT _imported)
+ # Reading the LOCATION property on non-imported target will error out.
+ # Assume the user won't need this information in the .pc file.
+ continue()
+ endif()
+ get_target_property(_lib "${_libname}" LOCATION)
+ if(NOT _lib)
+ message(WARNING "Bad lib in library list: ${_libname}")
+ continue()
+ endif()
+ endif()
+ if(_lib MATCHES ".*/.*" OR _lib MATCHES "^-")
+ set(LIBCURL_LIBS "${LIBCURL_LIBS} ${_lib}")
+ else()
+ set(LIBCURL_LIBS "${LIBCURL_LIBS} -l${_lib}")
+ endif()
+endforeach()
+if(BUILD_SHARED_LIBS)
+ set(ENABLE_SHARED "yes")
+ set(LIBCURL_NO_SHARED "")
+ set(CPPFLAG_CURL_STATICLIB "")
+else()
+ set(ENABLE_SHARED "no")
+ set(LIBCURL_NO_SHARED "${LIBCURL_LIBS}")
+ set(CPPFLAG_CURL_STATICLIB "-DCURL_STATICLIB")
+endif()
+if(BUILD_STATIC_LIBS)
+ set(ENABLE_STATIC "yes")
+else()
+ set(ENABLE_STATIC "no")
+endif()
+# "a" (Linux) or "lib" (Windows)
+string(REPLACE "." "" libext "${CMAKE_STATIC_LIBRARY_SUFFIX}")
+set(prefix "${CMAKE_INSTALL_PREFIX}")
+# Set this to "yes" to append all libraries on which -lcurl is dependent
+set(REQUIRE_LIB_DEPS "no")
+# SUPPORT_FEATURES
+# SUPPORT_PROTOCOLS
+set(VERSIONNUM "${CURL_VERSION_NUM}")
+
+# Finally generate a "curl-config" matching this config
+# Use:
+# * ENABLE_SHARED
+# * ENABLE_STATIC
+configure_file("${CURL_SOURCE_DIR}/curl-config.in"
+ "${CURL_BINARY_DIR}/curl-config" @ONLY)
+install(FILES "${CURL_BINARY_DIR}/curl-config"
+ DESTINATION ${CMAKE_INSTALL_BINDIR}
+ PERMISSIONS
+ OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE
+ WORLD_READ WORLD_EXECUTE)
+
+# Finally generate a pkg-config file matching this config
+configure_file("${CURL_SOURCE_DIR}/libcurl.pc.in"
+ "${CURL_BINARY_DIR}/libcurl.pc" @ONLY)
+install(FILES "${CURL_BINARY_DIR}/libcurl.pc"
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
+
+# install headers
+install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/curl"
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+ FILES_MATCHING PATTERN "*.h")
+
+include(CMakePackageConfigHelpers)
+write_basic_package_version_file(
+ "${version_config}"
+ VERSION ${CURL_VERSION}
+ COMPATIBILITY SameMajorVersion
+)
+file(READ "${version_config}" generated_version_config)
+file(WRITE "${version_config}"
+"if(NOT PACKAGE_FIND_VERSION_RANGE AND PACKAGE_FIND_VERSION_MAJOR STREQUAL \"7\")
+ # Version 8 satisfies version 7... requirements
+ set(PACKAGE_FIND_VERSION_MAJOR 8)
+ set(PACKAGE_FIND_VERSION_COUNT 1)
+endif()
+${generated_version_config}"
+)
+
+# Use:
+# * TARGETS_EXPORT_NAME
+# * PROJECT_NAME
+configure_package_config_file(CMake/curl-config.cmake.in
+ "${project_config}"
+ INSTALL_DESTINATION ${CURL_INSTALL_CMAKE_DIR}
+)
+
+if(CURL_ENABLE_EXPORT_TARGET)
+ install(
+ EXPORT "${TARGETS_EXPORT_NAME}"
+ NAMESPACE "${PROJECT_NAME}::"
+ DESTINATION ${CURL_INSTALL_CMAKE_DIR}
+ )
+endif()
+
+install(
+ FILES ${version_config} ${project_config}
+ DESTINATION ${CURL_INSTALL_CMAKE_DIR}
+)
+
+# Workaround for MSVS10 to avoid the Dialog Hell
+# FIXME: This could be removed with future version of CMake.
+if(MSVC_VERSION EQUAL 1600)
+ set(CURL_SLN_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/CURL.sln")
+ if(EXISTS "${CURL_SLN_FILENAME}")
+ file(APPEND "${CURL_SLN_FILENAME}" "\n# This should be regenerated!\n")
+ endif()
+endif()
+
+if(NOT TARGET curl_uninstall)
+ configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/CMake/cmake_uninstall.cmake.in
+ ${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake
+ IMMEDIATE @ONLY)
+
+ add_custom_target(curl_uninstall
+ COMMAND ${CMAKE_COMMAND} -P
+ ${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake)
+endif()
diff --git a/iotdb-client/odbc/deps/curl-src/COPYING b/iotdb-client/odbc/deps/curl-src/COPYING
new file mode 100644
index 0000000000000..d1eab3eb93284
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/COPYING
@@ -0,0 +1,22 @@
+COPYRIGHT AND PERMISSION NOTICE
+
+Copyright (c) 1996 - 2023, Daniel Stenberg, , and many
+contributors, see the THANKS file.
+
+All rights reserved.
+
+Permission to use, copy, modify, and distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright
+notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
+NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder shall not
+be used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization of the copyright holder.
diff --git a/iotdb-client/odbc/deps/curl-src/curl-config.in b/iotdb-client/odbc/deps/curl-src/curl-config.in
new file mode 100644
index 0000000000000..54f92d9313632
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/curl-config.in
@@ -0,0 +1,196 @@
+#! /bin/sh
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+
+prefix="@prefix@"
+exec_prefix=@exec_prefix@
+includedir=@includedir@
+cppflag_curl_staticlib=@CPPFLAG_CURL_STATICLIB@
+
+usage()
+{
+ cat <&2
+ exit 1
+ fi
+ ;;
+
+ --configure)
+ echo @CONFIGURE_OPTIONS@
+ ;;
+
+ *)
+ echo "unknown option: $1"
+ usage 1
+ ;;
+ esac
+ shift
+done
+
+exit 0
diff --git a/iotdb-client/odbc/deps/curl-src/include/Makefile.am b/iotdb-client/odbc/deps/curl-src/include/Makefile.am
new file mode 100644
index 0000000000000..d65bfeaa0fbd6
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/include/Makefile.am
@@ -0,0 +1,28 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+SUBDIRS = curl
+
+EXTRA_DIST = README.md
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
diff --git a/iotdb-client/odbc/deps/curl-src/include/README.md b/iotdb-client/odbc/deps/curl-src/include/README.md
new file mode 100644
index 0000000000000..c96593263f745
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/include/README.md
@@ -0,0 +1,20 @@
+
+
+# include
+
+Public include files for libcurl, external users.
+
+They're all placed in the curl subdirectory here for better fit in any kind of
+environment. You must include files from here using...
+
+ #include
+
+... style and point the compiler's include path to the directory holding the
+curl subdirectory. It makes it more likely to survive future modifications.
+
+The public curl include files can be shared freely between different platforms
+and different architectures.
diff --git a/iotdb-client/odbc/deps/curl-src/include/curl/.gitignore b/iotdb-client/odbc/deps/curl-src/include/curl/.gitignore
new file mode 100644
index 0000000000000..246793882554b
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/include/curl/.gitignore
@@ -0,0 +1,7 @@
+# Copyright (C) Daniel Stenberg, , et al.
+#
+# SPDX-License-Identifier: curl
+
+curlver.h.dist
+stamp-h2
+stamp-h3
diff --git a/iotdb-client/odbc/deps/curl-src/include/curl/Makefile.am b/iotdb-client/odbc/deps/curl-src/include/curl/Makefile.am
new file mode 100644
index 0000000000000..a655aff1c8a2a
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/include/curl/Makefile.am
@@ -0,0 +1,41 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+pkginclude_HEADERS = \
+ curl.h curlver.h easy.h mprintf.h stdcheaders.h multi.h \
+ typecheck-gcc.h system.h urlapi.h options.h header.h websockets.h
+
+pkgincludedir= $(includedir)/curl
+
+CHECKSRC = $(CS_$(V))
+CS_0 = @echo " RUN " $@;
+CS_1 =
+CS_ = $(CS_0)
+
+checksrc:
+ $(CHECKSRC)@PERL@ $(top_srcdir)/scripts/checksrc.pl -D$(top_srcdir)/include/curl $(pkginclude_HEADERS)
+
+if CURLDEBUG
+# for debug builds, we scan the sources on all regular make invokes
+all-local: checksrc
+endif
diff --git a/iotdb-client/odbc/deps/curl-src/include/curl/curl.h b/iotdb-client/odbc/deps/curl-src/include/curl/curl.h
new file mode 100644
index 0000000000000..bf71d82fb4b79
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/include/curl/curl.h
@@ -0,0 +1,3241 @@
+#ifndef CURLINC_CURL_H
+#define CURLINC_CURL_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+/*
+ * If you have libcurl problems, all docs and details are found here:
+ * https://curl.se/libcurl/
+ */
+
+#ifdef CURL_NO_OLDIES
+#define CURL_STRICTER
+#endif
+
+/* Compile-time deprecation macros. */
+#if defined(__GNUC__) && \
+ ((__GNUC__ > 12) || ((__GNUC__ == 12) && (__GNUC_MINOR__ >= 1 ))) && \
+ !defined(__INTEL_COMPILER) && \
+ !defined(CURL_DISABLE_DEPRECATION) && !defined(BUILDING_LIBCURL)
+#define CURL_DEPRECATED(version, message) \
+ __attribute__((deprecated("since " # version ". " message)))
+#define CURL_IGNORE_DEPRECATION(statements) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") \
+ statements \
+ _Pragma("GCC diagnostic pop")
+#else
+#define CURL_DEPRECATED(version, message)
+#define CURL_IGNORE_DEPRECATION(statements) statements
+#endif
+
+#include "curlver.h" /* libcurl version defines */
+#include "system.h" /* determine things run-time */
+
+/*
+ * Define CURL_WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && \
+ !defined(__SYMBIAN32__)
+#define CURL_WIN32
+#endif
+
+#include
+#include
+
+#if (defined(__FreeBSD__) && (__FreeBSD__ >= 2)) || defined(__MidnightBSD__)
+/* Needed for __FreeBSD_version or __MidnightBSD_version symbol definition */
+#include
+#endif
+
+/* The include stuff here below is mainly for time_t! */
+#include
+#include
+
+#if defined(CURL_WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__)
+#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \
+ defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H))
+/* The check above prevents the winsock2 inclusion if winsock.h already was
+ included, since they can't co-exist without problems */
+#include
+#include
+#endif
+#endif
+
+/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
+ libc5-based Linux systems. Only include it on systems that are known to
+ require it! */
+#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
+ defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
+ defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \
+ defined(__CYGWIN__) || defined(AMIGA) || defined(__NuttX__) || \
+ (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) || \
+ (defined(__MidnightBSD_version) && (__MidnightBSD_version < 100000)) || \
+ defined(__sun__) || defined(__serenity__) || defined(__vxworks__)
+#include
+#endif
+
+#if !defined(CURL_WIN32) && !defined(_WIN32_WCE)
+#include
+#endif
+
+#if !defined(CURL_WIN32)
+#include
+#endif
+
+/* Compatibility for non-Clang compilers */
+#ifndef __has_declspec_attribute
+# define __has_declspec_attribute(x) 0
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
+typedef struct Curl_easy CURL;
+typedef struct Curl_share CURLSH;
+#else
+typedef void CURL;
+typedef void CURLSH;
+#endif
+
+/*
+ * libcurl external API function linkage decorations.
+ */
+
+#ifdef CURL_STATICLIB
+# define CURL_EXTERN
+#elif defined(CURL_WIN32) || defined(__SYMBIAN32__) || \
+ (__has_declspec_attribute(dllexport) && \
+ __has_declspec_attribute(dllimport))
+# if defined(BUILDING_LIBCURL)
+# define CURL_EXTERN __declspec(dllexport)
+# else
+# define CURL_EXTERN __declspec(dllimport)
+# endif
+#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS)
+# define CURL_EXTERN CURL_EXTERN_SYMBOL
+#else
+# define CURL_EXTERN
+#endif
+
+#ifndef curl_socket_typedef
+/* socket typedef */
+#if defined(CURL_WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H)
+typedef SOCKET curl_socket_t;
+#define CURL_SOCKET_BAD INVALID_SOCKET
+#else
+typedef int curl_socket_t;
+#define CURL_SOCKET_BAD -1
+#endif
+#define curl_socket_typedef
+#endif /* curl_socket_typedef */
+
+/* enum for the different supported SSL backends */
+typedef enum {
+ CURLSSLBACKEND_NONE = 0,
+ CURLSSLBACKEND_OPENSSL = 1,
+ CURLSSLBACKEND_GNUTLS = 2,
+ CURLSSLBACKEND_NSS CURL_DEPRECATED(8.3.0, "") = 3,
+ CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */
+ CURLSSLBACKEND_GSKIT CURL_DEPRECATED(8.3.0, "") = 5,
+ CURLSSLBACKEND_POLARSSL CURL_DEPRECATED(7.69.0, "") = 6,
+ CURLSSLBACKEND_WOLFSSL = 7,
+ CURLSSLBACKEND_SCHANNEL = 8,
+ CURLSSLBACKEND_SECURETRANSPORT = 9,
+ CURLSSLBACKEND_AXTLS CURL_DEPRECATED(7.61.0, "") = 10,
+ CURLSSLBACKEND_MBEDTLS = 11,
+ CURLSSLBACKEND_MESALINK CURL_DEPRECATED(7.82.0, "") = 12,
+ CURLSSLBACKEND_BEARSSL = 13,
+ CURLSSLBACKEND_RUSTLS = 14
+} curl_sslbackend;
+
+/* aliases for library clones and renames */
+#define CURLSSLBACKEND_AWSLC CURLSSLBACKEND_OPENSSL
+#define CURLSSLBACKEND_BORINGSSL CURLSSLBACKEND_OPENSSL
+#define CURLSSLBACKEND_LIBRESSL CURLSSLBACKEND_OPENSSL
+
+/* deprecated names: */
+#define CURLSSLBACKEND_CYASSL CURLSSLBACKEND_WOLFSSL
+#define CURLSSLBACKEND_DARWINSSL CURLSSLBACKEND_SECURETRANSPORT
+
+struct curl_httppost {
+ struct curl_httppost *next; /* next entry in the list */
+ char *name; /* pointer to allocated name */
+ long namelength; /* length of name length */
+ char *contents; /* pointer to allocated data contents */
+ long contentslength; /* length of contents field, see also
+ CURL_HTTPPOST_LARGE */
+ char *buffer; /* pointer to allocated buffer contents */
+ long bufferlength; /* length of buffer field */
+ char *contenttype; /* Content-Type */
+ struct curl_slist *contentheader; /* list of extra headers for this form */
+ struct curl_httppost *more; /* if one field name has more than one
+ file, this link should link to following
+ files */
+ long flags; /* as defined below */
+
+/* specified content is a file name */
+#define CURL_HTTPPOST_FILENAME (1<<0)
+/* specified content is a file name */
+#define CURL_HTTPPOST_READFILE (1<<1)
+/* name is only stored pointer do not free in formfree */
+#define CURL_HTTPPOST_PTRNAME (1<<2)
+/* contents is only stored pointer do not free in formfree */
+#define CURL_HTTPPOST_PTRCONTENTS (1<<3)
+/* upload file from buffer */
+#define CURL_HTTPPOST_BUFFER (1<<4)
+/* upload file from pointer contents */
+#define CURL_HTTPPOST_PTRBUFFER (1<<5)
+/* upload file contents by using the regular read callback to get the data and
+ pass the given pointer as custom pointer */
+#define CURL_HTTPPOST_CALLBACK (1<<6)
+/* use size in 'contentlen', added in 7.46.0 */
+#define CURL_HTTPPOST_LARGE (1<<7)
+
+ char *showfilename; /* The file name to show. If not set, the
+ actual file name will be used (if this
+ is a file part) */
+ void *userp; /* custom pointer used for
+ HTTPPOST_CALLBACK posts */
+ curl_off_t contentlen; /* alternative length of contents
+ field. Used if CURL_HTTPPOST_LARGE is
+ set. Added in 7.46.0 */
+};
+
+
+/* This is a return code for the progress callback that, when returned, will
+ signal libcurl to continue executing the default progress function */
+#define CURL_PROGRESSFUNC_CONTINUE 0x10000001
+
+/* This is the CURLOPT_PROGRESSFUNCTION callback prototype. It is now
+ considered deprecated but was the only choice up until 7.31.0 */
+typedef int (*curl_progress_callback)(void *clientp,
+ double dltotal,
+ double dlnow,
+ double ultotal,
+ double ulnow);
+
+/* This is the CURLOPT_XFERINFOFUNCTION callback prototype. It was introduced
+ in 7.32.0, avoids the use of floating point numbers and provides more
+ detailed information. */
+typedef int (*curl_xferinfo_callback)(void *clientp,
+ curl_off_t dltotal,
+ curl_off_t dlnow,
+ curl_off_t ultotal,
+ curl_off_t ulnow);
+
+#ifndef CURL_MAX_READ_SIZE
+ /* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */
+#define CURL_MAX_READ_SIZE (10*1024*1024)
+#endif
+
+#ifndef CURL_MAX_WRITE_SIZE
+ /* Tests have proven that 20K is a very bad buffer size for uploads on
+ Windows, while 16K for some odd reason performed a lot better.
+ We do the ifndef check to allow this value to easier be changed at build
+ time for those who feel adventurous. The practical minimum is about
+ 400 bytes since libcurl uses a buffer of this size as a scratch area
+ (unrelated to network send operations). */
+#define CURL_MAX_WRITE_SIZE 16384
+#endif
+
+#ifndef CURL_MAX_HTTP_HEADER
+/* The only reason to have a max limit for this is to avoid the risk of a bad
+ server feeding libcurl with a never-ending header that will cause reallocs
+ infinitely */
+#define CURL_MAX_HTTP_HEADER (100*1024)
+#endif
+
+/* This is a magic return code for the write callback that, when returned,
+ will signal libcurl to pause receiving on the current transfer. */
+#define CURL_WRITEFUNC_PAUSE 0x10000001
+
+/* This is a magic return code for the write callback that, when returned,
+ will signal an error from the callback. */
+#define CURL_WRITEFUNC_ERROR 0xFFFFFFFF
+
+typedef size_t (*curl_write_callback)(char *buffer,
+ size_t size,
+ size_t nitems,
+ void *outstream);
+
+/* This callback will be called when a new resolver request is made */
+typedef int (*curl_resolver_start_callback)(void *resolver_state,
+ void *reserved, void *userdata);
+
+/* enumeration of file types */
+typedef enum {
+ CURLFILETYPE_FILE = 0,
+ CURLFILETYPE_DIRECTORY,
+ CURLFILETYPE_SYMLINK,
+ CURLFILETYPE_DEVICE_BLOCK,
+ CURLFILETYPE_DEVICE_CHAR,
+ CURLFILETYPE_NAMEDPIPE,
+ CURLFILETYPE_SOCKET,
+ CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */
+
+ CURLFILETYPE_UNKNOWN /* should never occur */
+} curlfiletype;
+
+#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0)
+#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1)
+#define CURLFINFOFLAG_KNOWN_TIME (1<<2)
+#define CURLFINFOFLAG_KNOWN_PERM (1<<3)
+#define CURLFINFOFLAG_KNOWN_UID (1<<4)
+#define CURLFINFOFLAG_KNOWN_GID (1<<5)
+#define CURLFINFOFLAG_KNOWN_SIZE (1<<6)
+#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7)
+
+/* Information about a single file, used when doing FTP wildcard matching */
+struct curl_fileinfo {
+ char *filename;
+ curlfiletype filetype;
+ time_t time; /* always zero! */
+ unsigned int perm;
+ int uid;
+ int gid;
+ curl_off_t size;
+ long int hardlinks;
+
+ struct {
+ /* If some of these fields is not NULL, it is a pointer to b_data. */
+ char *time;
+ char *perm;
+ char *user;
+ char *group;
+ char *target; /* pointer to the target filename of a symlink */
+ } strings;
+
+ unsigned int flags;
+
+ /* These are libcurl private struct fields. Previously used by libcurl, so
+ they must never be interfered with. */
+ char *b_data;
+ size_t b_size;
+ size_t b_used;
+};
+
+/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */
+#define CURL_CHUNK_BGN_FUNC_OK 0
+#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */
+#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */
+
+/* if splitting of data transfer is enabled, this callback is called before
+ download of an individual chunk started. Note that parameter "remains" works
+ only for FTP wildcard downloading (for now), otherwise is not used */
+typedef long (*curl_chunk_bgn_callback)(const void *transfer_info,
+ void *ptr,
+ int remains);
+
+/* return codes for CURLOPT_CHUNK_END_FUNCTION */
+#define CURL_CHUNK_END_FUNC_OK 0
+#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */
+
+/* If splitting of data transfer is enabled this callback is called after
+ download of an individual chunk finished.
+ Note! After this callback was set then it have to be called FOR ALL chunks.
+ Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC.
+ This is the reason why we don't need "transfer_info" parameter in this
+ callback and we are not interested in "remains" parameter too. */
+typedef long (*curl_chunk_end_callback)(void *ptr);
+
+/* return codes for FNMATCHFUNCTION */
+#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */
+#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */
+#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */
+
+/* callback type for wildcard downloading pattern matching. If the
+ string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */
+typedef int (*curl_fnmatch_callback)(void *ptr,
+ const char *pattern,
+ const char *string);
+
+/* These are the return codes for the seek callbacks */
+#define CURL_SEEKFUNC_OK 0
+#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */
+#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so
+ libcurl might try other means instead */
+typedef int (*curl_seek_callback)(void *instream,
+ curl_off_t offset,
+ int origin); /* 'whence' */
+
+/* This is a return code for the read callback that, when returned, will
+ signal libcurl to immediately abort the current transfer. */
+#define CURL_READFUNC_ABORT 0x10000000
+/* This is a return code for the read callback that, when returned, will
+ signal libcurl to pause sending data on the current transfer. */
+#define CURL_READFUNC_PAUSE 0x10000001
+
+/* Return code for when the trailing headers' callback has terminated
+ without any errors */
+#define CURL_TRAILERFUNC_OK 0
+/* Return code for when was an error in the trailing header's list and we
+ want to abort the request */
+#define CURL_TRAILERFUNC_ABORT 1
+
+typedef size_t (*curl_read_callback)(char *buffer,
+ size_t size,
+ size_t nitems,
+ void *instream);
+
+typedef int (*curl_trailer_callback)(struct curl_slist **list,
+ void *userdata);
+
+typedef enum {
+ CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */
+ CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */
+ CURLSOCKTYPE_LAST /* never use */
+} curlsocktype;
+
+/* The return code from the sockopt_callback can signal information back
+ to libcurl: */
+#define CURL_SOCKOPT_OK 0
+#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return
+ CURLE_ABORTED_BY_CALLBACK */
+#define CURL_SOCKOPT_ALREADY_CONNECTED 2
+
+typedef int (*curl_sockopt_callback)(void *clientp,
+ curl_socket_t curlfd,
+ curlsocktype purpose);
+
+struct curl_sockaddr {
+ int family;
+ int socktype;
+ int protocol;
+ unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it
+ turned really ugly and painful on the systems that
+ lack this type */
+ struct sockaddr addr;
+};
+
+typedef curl_socket_t
+(*curl_opensocket_callback)(void *clientp,
+ curlsocktype purpose,
+ struct curl_sockaddr *address);
+
+typedef int
+(*curl_closesocket_callback)(void *clientp, curl_socket_t item);
+
+typedef enum {
+ CURLIOE_OK, /* I/O operation successful */
+ CURLIOE_UNKNOWNCMD, /* command was unknown to callback */
+ CURLIOE_FAILRESTART, /* failed to restart the read */
+ CURLIOE_LAST /* never use */
+} curlioerr;
+
+typedef enum {
+ CURLIOCMD_NOP, /* no operation */
+ CURLIOCMD_RESTARTREAD, /* restart the read stream from start */
+ CURLIOCMD_LAST /* never use */
+} curliocmd;
+
+typedef curlioerr (*curl_ioctl_callback)(CURL *handle,
+ int cmd,
+ void *clientp);
+
+#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS
+/*
+ * The following typedef's are signatures of malloc, free, realloc, strdup and
+ * calloc respectively. Function pointers of these types can be passed to the
+ * curl_global_init_mem() function to set user defined memory management
+ * callback routines.
+ */
+typedef void *(*curl_malloc_callback)(size_t size);
+typedef void (*curl_free_callback)(void *ptr);
+typedef void *(*curl_realloc_callback)(void *ptr, size_t size);
+typedef char *(*curl_strdup_callback)(const char *str);
+typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size);
+
+#define CURL_DID_MEMORY_FUNC_TYPEDEFS
+#endif
+
+/* the kind of data that is passed to information_callback */
+typedef enum {
+ CURLINFO_TEXT = 0,
+ CURLINFO_HEADER_IN, /* 1 */
+ CURLINFO_HEADER_OUT, /* 2 */
+ CURLINFO_DATA_IN, /* 3 */
+ CURLINFO_DATA_OUT, /* 4 */
+ CURLINFO_SSL_DATA_IN, /* 5 */
+ CURLINFO_SSL_DATA_OUT, /* 6 */
+ CURLINFO_END
+} curl_infotype;
+
+typedef int (*curl_debug_callback)
+ (CURL *handle, /* the handle/transfer this concerns */
+ curl_infotype type, /* what kind of data */
+ char *data, /* points to the data */
+ size_t size, /* size of the data pointed to */
+ void *userptr); /* whatever the user please */
+
+/* This is the CURLOPT_PREREQFUNCTION callback prototype. */
+typedef int (*curl_prereq_callback)(void *clientp,
+ char *conn_primary_ip,
+ char *conn_local_ip,
+ int conn_primary_port,
+ int conn_local_port);
+
+/* Return code for when the pre-request callback has terminated without
+ any errors */
+#define CURL_PREREQFUNC_OK 0
+/* Return code for when the pre-request callback wants to abort the
+ request */
+#define CURL_PREREQFUNC_ABORT 1
+
+/* All possible error codes from all sorts of curl functions. Future versions
+ may return other values, stay prepared.
+
+ Always add new return codes last. Never *EVER* remove any. The return
+ codes must remain the same!
+ */
+
+typedef enum {
+ CURLE_OK = 0,
+ CURLE_UNSUPPORTED_PROTOCOL, /* 1 */
+ CURLE_FAILED_INIT, /* 2 */
+ CURLE_URL_MALFORMAT, /* 3 */
+ CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for
+ 7.17.0, reused in April 2011 for 7.21.5] */
+ CURLE_COULDNT_RESOLVE_PROXY, /* 5 */
+ CURLE_COULDNT_RESOLVE_HOST, /* 6 */
+ CURLE_COULDNT_CONNECT, /* 7 */
+ CURLE_WEIRD_SERVER_REPLY, /* 8 */
+ CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server
+ due to lack of access - when login fails
+ this is not returned. */
+ CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for
+ 7.15.4, reused in Dec 2011 for 7.24.0]*/
+ CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */
+ CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server
+ [was obsoleted in August 2007 for 7.17.0,
+ reused in Dec 2011 for 7.24.0]*/
+ CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */
+ CURLE_FTP_WEIRD_227_FORMAT, /* 14 */
+ CURLE_FTP_CANT_GET_HOST, /* 15 */
+ CURLE_HTTP2, /* 16 - A problem in the http2 framing layer.
+ [was obsoleted in August 2007 for 7.17.0,
+ reused in July 2014 for 7.38.0] */
+ CURLE_FTP_COULDNT_SET_TYPE, /* 17 */
+ CURLE_PARTIAL_FILE, /* 18 */
+ CURLE_FTP_COULDNT_RETR_FILE, /* 19 */
+ CURLE_OBSOLETE20, /* 20 - NOT USED */
+ CURLE_QUOTE_ERROR, /* 21 - quote command failure */
+ CURLE_HTTP_RETURNED_ERROR, /* 22 */
+ CURLE_WRITE_ERROR, /* 23 */
+ CURLE_OBSOLETE24, /* 24 - NOT USED */
+ CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */
+ CURLE_READ_ERROR, /* 26 - couldn't open/read from file */
+ CURLE_OUT_OF_MEMORY, /* 27 */
+ CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */
+ CURLE_OBSOLETE29, /* 29 - NOT USED */
+ CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */
+ CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */
+ CURLE_OBSOLETE32, /* 32 - NOT USED */
+ CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */
+ CURLE_HTTP_POST_ERROR, /* 34 */
+ CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */
+ CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */
+ CURLE_FILE_COULDNT_READ_FILE, /* 37 */
+ CURLE_LDAP_CANNOT_BIND, /* 38 */
+ CURLE_LDAP_SEARCH_FAILED, /* 39 */
+ CURLE_OBSOLETE40, /* 40 - NOT USED */
+ CURLE_FUNCTION_NOT_FOUND, /* 41 - NOT USED starting with 7.53.0 */
+ CURLE_ABORTED_BY_CALLBACK, /* 42 */
+ CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */
+ CURLE_OBSOLETE44, /* 44 - NOT USED */
+ CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */
+ CURLE_OBSOLETE46, /* 46 - NOT USED */
+ CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */
+ CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */
+ CURLE_SETOPT_OPTION_SYNTAX, /* 49 - Malformed setopt option */
+ CURLE_OBSOLETE50, /* 50 - NOT USED */
+ CURLE_OBSOLETE51, /* 51 - NOT USED */
+ CURLE_GOT_NOTHING, /* 52 - when this is a specific error */
+ CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */
+ CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as
+ default */
+ CURLE_SEND_ERROR, /* 55 - failed sending network data */
+ CURLE_RECV_ERROR, /* 56 - failure in receiving network data */
+ CURLE_OBSOLETE57, /* 57 - NOT IN USE */
+ CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */
+ CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */
+ CURLE_PEER_FAILED_VERIFICATION, /* 60 - peer's certificate or fingerprint
+ wasn't verified fine */
+ CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */
+ CURLE_OBSOLETE62, /* 62 - NOT IN USE since 7.82.0 */
+ CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */
+ CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */
+ CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind
+ that failed */
+ CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */
+ CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not
+ accepted and we failed to login */
+ CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */
+ CURLE_TFTP_PERM, /* 69 - permission problem on server */
+ CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */
+ CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */
+ CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */
+ CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */
+ CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */
+ CURLE_OBSOLETE75, /* 75 - NOT IN USE since 7.82.0 */
+ CURLE_OBSOLETE76, /* 76 - NOT IN USE since 7.82.0 */
+ CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing
+ or wrong format */
+ CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */
+ CURLE_SSH, /* 79 - error from the SSH layer, somewhat
+ generic so the error message will be of
+ interest when this has happened */
+
+ CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL
+ connection */
+ CURLE_AGAIN, /* 81 - socket is not ready for send/recv,
+ wait till it's ready and try again (Added
+ in 7.18.2) */
+ CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or
+ wrong format (Added in 7.19.0) */
+ CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in
+ 7.19.0) */
+ CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */
+ CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */
+ CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */
+ CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */
+ CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */
+ CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the
+ session will be queued */
+ CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not
+ match */
+ CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */
+ CURLE_HTTP2_STREAM, /* 92 - stream error in HTTP/2 framing layer
+ */
+ CURLE_RECURSIVE_API_CALL, /* 93 - an api function was called from
+ inside a callback */
+ CURLE_AUTH_ERROR, /* 94 - an authentication function returned an
+ error */
+ CURLE_HTTP3, /* 95 - An HTTP/3 layer problem */
+ CURLE_QUIC_CONNECT_ERROR, /* 96 - QUIC connection error */
+ CURLE_PROXY, /* 97 - proxy handshake error */
+ CURLE_SSL_CLIENTCERT, /* 98 - client-side certificate required */
+ CURLE_UNRECOVERABLE_POLL, /* 99 - poll/select returned fatal error */
+ CURL_LAST /* never use! */
+} CURLcode;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+ the obsolete stuff removed! */
+
+/* Previously obsolete error code reused in 7.38.0 */
+#define CURLE_OBSOLETE16 CURLE_HTTP2
+
+/* Previously obsolete error codes reused in 7.24.0 */
+#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED
+#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT
+
+/* compatibility with older names */
+#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING
+#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY
+
+/* The following were added in 7.62.0 */
+#define CURLE_SSL_CACERT CURLE_PEER_FAILED_VERIFICATION
+
+/* The following were added in 7.21.5, April 2011 */
+#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION
+
+/* Added for 7.78.0 */
+#define CURLE_TELNET_OPTION_SYNTAX CURLE_SETOPT_OPTION_SYNTAX
+
+/* The following were added in 7.17.1 */
+/* These are scheduled to disappear by 2009 */
+#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION
+
+/* The following were added in 7.17.0 */
+/* These are scheduled to disappear by 2009 */
+#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */
+#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46
+#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44
+#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10
+#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16
+#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32
+#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29
+#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12
+#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20
+#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40
+#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24
+#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57
+#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN
+
+#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED
+#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE
+#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR
+#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL
+#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS
+#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR
+#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED
+
+/* The following were added earlier */
+
+#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT
+#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
+#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED
+#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED
+#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE
+#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME
+#define CURLE_LDAP_INVALID_URL CURLE_OBSOLETE62
+#define CURLE_CONV_REQD CURLE_OBSOLETE76
+#define CURLE_CONV_FAILED CURLE_OBSOLETE75
+
+/* This was the error code 50 in 7.7.3 and a few earlier versions, this
+ is no longer used by libcurl but is instead #defined here only to not
+ make programs break */
+#define CURLE_ALREADY_COMPLETE 99999
+
+/* Provide defines for really old option names */
+#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */
+#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */
+#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA
+
+/* Since long deprecated options with no code in the lib that does anything
+ with them. */
+#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40
+#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72
+
+#endif /* !CURL_NO_OLDIES */
+
+/*
+ * Proxy error codes. Returned in CURLINFO_PROXY_ERROR if CURLE_PROXY was
+ * return for the transfers.
+ */
+typedef enum {
+ CURLPX_OK,
+ CURLPX_BAD_ADDRESS_TYPE,
+ CURLPX_BAD_VERSION,
+ CURLPX_CLOSED,
+ CURLPX_GSSAPI,
+ CURLPX_GSSAPI_PERMSG,
+ CURLPX_GSSAPI_PROTECTION,
+ CURLPX_IDENTD,
+ CURLPX_IDENTD_DIFFER,
+ CURLPX_LONG_HOSTNAME,
+ CURLPX_LONG_PASSWD,
+ CURLPX_LONG_USER,
+ CURLPX_NO_AUTH,
+ CURLPX_RECV_ADDRESS,
+ CURLPX_RECV_AUTH,
+ CURLPX_RECV_CONNECT,
+ CURLPX_RECV_REQACK,
+ CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED,
+ CURLPX_REPLY_COMMAND_NOT_SUPPORTED,
+ CURLPX_REPLY_CONNECTION_REFUSED,
+ CURLPX_REPLY_GENERAL_SERVER_FAILURE,
+ CURLPX_REPLY_HOST_UNREACHABLE,
+ CURLPX_REPLY_NETWORK_UNREACHABLE,
+ CURLPX_REPLY_NOT_ALLOWED,
+ CURLPX_REPLY_TTL_EXPIRED,
+ CURLPX_REPLY_UNASSIGNED,
+ CURLPX_REQUEST_FAILED,
+ CURLPX_RESOLVE_HOST,
+ CURLPX_SEND_AUTH,
+ CURLPX_SEND_CONNECT,
+ CURLPX_SEND_REQUEST,
+ CURLPX_UNKNOWN_FAIL,
+ CURLPX_UNKNOWN_MODE,
+ CURLPX_USER_REJECTED,
+ CURLPX_LAST /* never use */
+} CURLproxycode;
+
+/* This prototype applies to all conversion callbacks */
+typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length);
+
+typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */
+ void *ssl_ctx, /* actually an OpenSSL
+ or WolfSSL SSL_CTX,
+ or an mbedTLS
+ mbedtls_ssl_config */
+ void *userptr);
+
+typedef enum {
+ CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use
+ CONNECT HTTP/1.1 */
+ CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT
+ HTTP/1.0 */
+ CURLPROXY_HTTPS = 2, /* HTTPS but stick to HTTP/1 added in 7.52.0 */
+ CURLPROXY_HTTPS2 = 3, /* HTTPS and attempt HTTP/2 added in 8.2.0 */
+ CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already
+ in 7.10 */
+ CURLPROXY_SOCKS5 = 5, /* added in 7.10 */
+ CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */
+ CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the
+ host name rather than the IP address. added
+ in 7.18.0 */
+} curl_proxytype; /* this enum was added in 7.10 */
+
+/*
+ * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options:
+ *
+ * CURLAUTH_NONE - No HTTP authentication
+ * CURLAUTH_BASIC - HTTP Basic authentication (default)
+ * CURLAUTH_DIGEST - HTTP Digest authentication
+ * CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication
+ * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated)
+ * CURLAUTH_NTLM - HTTP NTLM authentication
+ * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour
+ * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper
+ * CURLAUTH_BEARER - HTTP Bearer token authentication
+ * CURLAUTH_ONLY - Use together with a single other type to force no
+ * authentication or just that single type
+ * CURLAUTH_ANY - All fine types set
+ * CURLAUTH_ANYSAFE - All fine types except Basic
+ */
+
+#define CURLAUTH_NONE ((unsigned long)0)
+#define CURLAUTH_BASIC (((unsigned long)1)<<0)
+#define CURLAUTH_DIGEST (((unsigned long)1)<<1)
+#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2)
+/* Deprecated since the advent of CURLAUTH_NEGOTIATE */
+#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE
+/* Used for CURLOPT_SOCKS5_AUTH to stay terminologically correct */
+#define CURLAUTH_GSSAPI CURLAUTH_NEGOTIATE
+#define CURLAUTH_NTLM (((unsigned long)1)<<3)
+#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4)
+#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5)
+#define CURLAUTH_BEARER (((unsigned long)1)<<6)
+#define CURLAUTH_AWS_SIGV4 (((unsigned long)1)<<7)
+#define CURLAUTH_ONLY (((unsigned long)1)<<31)
+#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE)
+#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
+
+#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */
+#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */
+#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */
+#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */
+#define CURLSSH_AUTH_HOST (1<<2) /* host key files */
+#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */
+#define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */
+#define CURLSSH_AUTH_GSSAPI (1<<5) /* gssapi (kerberos, ...) */
+#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY
+
+#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */
+#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */
+#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */
+
+#define CURL_ERROR_SIZE 256
+
+enum curl_khtype {
+ CURLKHTYPE_UNKNOWN,
+ CURLKHTYPE_RSA1,
+ CURLKHTYPE_RSA,
+ CURLKHTYPE_DSS,
+ CURLKHTYPE_ECDSA,
+ CURLKHTYPE_ED25519
+};
+
+struct curl_khkey {
+ const char *key; /* points to a null-terminated string encoded with base64
+ if len is zero, otherwise to the "raw" data */
+ size_t len;
+ enum curl_khtype keytype;
+};
+
+/* this is the set of return values expected from the curl_sshkeycallback
+ callback */
+enum curl_khstat {
+ CURLKHSTAT_FINE_ADD_TO_FILE,
+ CURLKHSTAT_FINE,
+ CURLKHSTAT_REJECT, /* reject the connection, return an error */
+ CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now.
+ Causes a CURLE_PEER_FAILED_VERIFICATION error but the
+ connection will be left intact etc */
+ CURLKHSTAT_FINE_REPLACE, /* accept and replace the wrong key */
+ CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */
+};
+
+/* this is the set of status codes pass in to the callback */
+enum curl_khmatch {
+ CURLKHMATCH_OK, /* match */
+ CURLKHMATCH_MISMATCH, /* host found, key mismatch! */
+ CURLKHMATCH_MISSING, /* no matching host/key found */
+ CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */
+};
+
+typedef int
+ (*curl_sshkeycallback) (CURL *easy, /* easy handle */
+ const struct curl_khkey *knownkey, /* known */
+ const struct curl_khkey *foundkey, /* found */
+ enum curl_khmatch, /* libcurl's view on the keys */
+ void *clientp); /* custom pointer passed with */
+ /* CURLOPT_SSH_KEYDATA */
+
+typedef int
+ (*curl_sshhostkeycallback) (void *clientp,/* custom pointer passed */
+ /* with CURLOPT_SSH_HOSTKEYDATA */
+ int keytype, /* CURLKHTYPE */
+ const char *key, /* hostkey to check */
+ size_t keylen); /* length of the key */
+ /* return CURLE_OK to accept */
+ /* or something else to refuse */
+
+
+/* parameter for the CURLOPT_USE_SSL option */
+typedef enum {
+ CURLUSESSL_NONE, /* do not attempt to use SSL */
+ CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */
+ CURLUSESSL_CONTROL, /* SSL for the control connection or fail */
+ CURLUSESSL_ALL, /* SSL for all communication or fail */
+ CURLUSESSL_LAST /* not an option, never use */
+} curl_usessl;
+
+/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */
+
+/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the
+ name of improving interoperability with older servers. Some SSL libraries
+ have introduced work-arounds for this flaw but those work-arounds sometimes
+ make the SSL communication fail. To regain functionality with those broken
+ servers, a user can this way allow the vulnerability back. */
+#define CURLSSLOPT_ALLOW_BEAST (1<<0)
+
+/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those
+ SSL backends where such behavior is present. */
+#define CURLSSLOPT_NO_REVOKE (1<<1)
+
+/* - NO_PARTIALCHAIN tells libcurl to *NOT* accept a partial certificate chain
+ if possible. The OpenSSL backend has this ability. */
+#define CURLSSLOPT_NO_PARTIALCHAIN (1<<2)
+
+/* - REVOKE_BEST_EFFORT tells libcurl to ignore certificate revocation offline
+ checks and ignore missing revocation list for those SSL backends where such
+ behavior is present. */
+#define CURLSSLOPT_REVOKE_BEST_EFFORT (1<<3)
+
+/* - CURLSSLOPT_NATIVE_CA tells libcurl to use standard certificate store of
+ operating system. Currently implemented under MS-Windows. */
+#define CURLSSLOPT_NATIVE_CA (1<<4)
+
+/* - CURLSSLOPT_AUTO_CLIENT_CERT tells libcurl to automatically locate and use
+ a client certificate for authentication. (Schannel) */
+#define CURLSSLOPT_AUTO_CLIENT_CERT (1<<5)
+
+/* The default connection attempt delay in milliseconds for happy eyeballs.
+ CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document
+ this value, keep them in sync. */
+#define CURL_HET_DEFAULT 200L
+
+/* The default connection upkeep interval in milliseconds. */
+#define CURL_UPKEEP_INTERVAL_DEFAULT 60000L
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+ the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+/* These are scheduled to disappear by 2009 */
+
+#define CURLFTPSSL_NONE CURLUSESSL_NONE
+#define CURLFTPSSL_TRY CURLUSESSL_TRY
+#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL
+#define CURLFTPSSL_ALL CURLUSESSL_ALL
+#define CURLFTPSSL_LAST CURLUSESSL_LAST
+#define curl_ftpssl curl_usessl
+#endif /* !CURL_NO_OLDIES */
+
+/* parameter for the CURLOPT_FTP_SSL_CCC option */
+typedef enum {
+ CURLFTPSSL_CCC_NONE, /* do not send CCC */
+ CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */
+ CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */
+ CURLFTPSSL_CCC_LAST /* not an option, never use */
+} curl_ftpccc;
+
+/* parameter for the CURLOPT_FTPSSLAUTH option */
+typedef enum {
+ CURLFTPAUTH_DEFAULT, /* let libcurl decide */
+ CURLFTPAUTH_SSL, /* use "AUTH SSL" */
+ CURLFTPAUTH_TLS, /* use "AUTH TLS" */
+ CURLFTPAUTH_LAST /* not an option, never use */
+} curl_ftpauth;
+
+/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */
+typedef enum {
+ CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */
+ CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD
+ again if MKD succeeded, for SFTP this does
+ similar magic */
+ CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD
+ again even if MKD failed! */
+ CURLFTP_CREATE_DIR_LAST /* not an option, never use */
+} curl_ftpcreatedir;
+
+/* parameter for the CURLOPT_FTP_FILEMETHOD option */
+typedef enum {
+ CURLFTPMETHOD_DEFAULT, /* let libcurl pick */
+ CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */
+ CURLFTPMETHOD_NOCWD, /* no CWD at all */
+ CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */
+ CURLFTPMETHOD_LAST /* not an option, never use */
+} curl_ftpmethod;
+
+/* bitmask defines for CURLOPT_HEADEROPT */
+#define CURLHEADER_UNIFIED 0
+#define CURLHEADER_SEPARATE (1<<0)
+
+/* CURLALTSVC_* are bits for the CURLOPT_ALTSVC_CTRL option */
+#define CURLALTSVC_READONLYFILE (1<<2)
+#define CURLALTSVC_H1 (1<<3)
+#define CURLALTSVC_H2 (1<<4)
+#define CURLALTSVC_H3 (1<<5)
+
+
+struct curl_hstsentry {
+ char *name;
+ size_t namelen;
+ unsigned int includeSubDomains:1;
+ char expire[18]; /* YYYYMMDD HH:MM:SS [null-terminated] */
+};
+
+struct curl_index {
+ size_t index; /* the provided entry's "index" or count */
+ size_t total; /* total number of entries to save */
+};
+
+typedef enum {
+ CURLSTS_OK,
+ CURLSTS_DONE,
+ CURLSTS_FAIL
+} CURLSTScode;
+
+typedef CURLSTScode (*curl_hstsread_callback)(CURL *easy,
+ struct curl_hstsentry *e,
+ void *userp);
+typedef CURLSTScode (*curl_hstswrite_callback)(CURL *easy,
+ struct curl_hstsentry *e,
+ struct curl_index *i,
+ void *userp);
+
+/* CURLHSTS_* are bits for the CURLOPT_HSTS option */
+#define CURLHSTS_ENABLE (long)(1<<0)
+#define CURLHSTS_READONLYFILE (long)(1<<1)
+
+/* The CURLPROTO_ defines below are for the **deprecated** CURLOPT_*PROTOCOLS
+ options. Do not use. */
+#define CURLPROTO_HTTP (1<<0)
+#define CURLPROTO_HTTPS (1<<1)
+#define CURLPROTO_FTP (1<<2)
+#define CURLPROTO_FTPS (1<<3)
+#define CURLPROTO_SCP (1<<4)
+#define CURLPROTO_SFTP (1<<5)
+#define CURLPROTO_TELNET (1<<6)
+#define CURLPROTO_LDAP (1<<7)
+#define CURLPROTO_LDAPS (1<<8)
+#define CURLPROTO_DICT (1<<9)
+#define CURLPROTO_FILE (1<<10)
+#define CURLPROTO_TFTP (1<<11)
+#define CURLPROTO_IMAP (1<<12)
+#define CURLPROTO_IMAPS (1<<13)
+#define CURLPROTO_POP3 (1<<14)
+#define CURLPROTO_POP3S (1<<15)
+#define CURLPROTO_SMTP (1<<16)
+#define CURLPROTO_SMTPS (1<<17)
+#define CURLPROTO_RTSP (1<<18)
+#define CURLPROTO_RTMP (1<<19)
+#define CURLPROTO_RTMPT (1<<20)
+#define CURLPROTO_RTMPE (1<<21)
+#define CURLPROTO_RTMPTE (1<<22)
+#define CURLPROTO_RTMPS (1<<23)
+#define CURLPROTO_RTMPTS (1<<24)
+#define CURLPROTO_GOPHER (1<<25)
+#define CURLPROTO_SMB (1<<26)
+#define CURLPROTO_SMBS (1<<27)
+#define CURLPROTO_MQTT (1<<28)
+#define CURLPROTO_GOPHERS (1<<29)
+#define CURLPROTO_ALL (~0) /* enable everything */
+
+/* long may be 32 or 64 bits, but we should never depend on anything else
+ but 32 */
+#define CURLOPTTYPE_LONG 0
+#define CURLOPTTYPE_OBJECTPOINT 10000
+#define CURLOPTTYPE_FUNCTIONPOINT 20000
+#define CURLOPTTYPE_OFF_T 30000
+#define CURLOPTTYPE_BLOB 40000
+
+/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the
+ string options from the header file */
+
+
+#define CURLOPT(na,t,nu) na = t + nu
+#define CURLOPTDEPRECATED(na,t,nu,v,m) na CURL_DEPRECATED(v,m) = t + nu
+
+/* 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_CBPOINT, 1),
+
+ /* The full URL to get/put */
+ CURLOPT(CURLOPT_URL, CURLOPTTYPE_STRINGPOINT, 2),
+
+ /* Port number to connect to, if other than default. */
+ CURLOPT(CURLOPT_PORT, CURLOPTTYPE_LONG, 3),
+
+ /* Name of proxy to use. */
+ CURLOPT(CURLOPT_PROXY, CURLOPTTYPE_STRINGPOINT, 4),
+
+ /* "user:password;options" to use when fetching. */
+ CURLOPT(CURLOPT_USERPWD, CURLOPTTYPE_STRINGPOINT, 5),
+
+ /* "user:password" to use with proxy. */
+ CURLOPT(CURLOPT_PROXYUSERPWD, CURLOPTTYPE_STRINGPOINT, 6),
+
+ /* Range to get, specified as an ASCII string. */
+ CURLOPT(CURLOPT_RANGE, CURLOPTTYPE_STRINGPOINT, 7),
+
+ /* not used */
+
+ /* Specified file stream to upload from (use as input): */
+ CURLOPT(CURLOPT_READDATA, CURLOPTTYPE_CBPOINT, 9),
+
+ /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE
+ * bytes big. */
+ CURLOPT(CURLOPT_ERRORBUFFER, CURLOPTTYPE_OBJECTPOINT, 10),
+
+ /* Function that will be called to store the output (instead of fwrite). The
+ * parameters will use fwrite() syntax, make sure to follow them. */
+ CURLOPT(CURLOPT_WRITEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 11),
+
+ /* Function that will be called to read the input (instead of fread). The
+ * parameters will use fread() syntax, make sure to follow them. */
+ CURLOPT(CURLOPT_READFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 12),
+
+ /* Time-out the read operation after this amount of seconds */
+ CURLOPT(CURLOPT_TIMEOUT, CURLOPTTYPE_LONG, 13),
+
+ /* If CURLOPT_READDATA is used, this can be used to inform libcurl about
+ * how large the file being sent really is. That allows better error
+ * checking and better verifies that the upload was successful. -1 means
+ * unknown size.
+ *
+ * For large file support, there is also a _LARGE version of the key
+ * which takes an off_t type, allowing platforms with larger off_t
+ * sizes to handle larger files. See below for INFILESIZE_LARGE.
+ */
+ CURLOPT(CURLOPT_INFILESIZE, CURLOPTTYPE_LONG, 14),
+
+ /* POST static input fields. */
+ CURLOPT(CURLOPT_POSTFIELDS, CURLOPTTYPE_OBJECTPOINT, 15),
+
+ /* Set the referrer page (needed by some CGIs) */
+ CURLOPT(CURLOPT_REFERER, CURLOPTTYPE_STRINGPOINT, 16),
+
+ /* Set the FTP PORT string (interface name, named or numerical IP address)
+ Use i.e '-' to use default address. */
+ CURLOPT(CURLOPT_FTPPORT, CURLOPTTYPE_STRINGPOINT, 17),
+
+ /* Set the User-Agent string (examined by some CGIs) */
+ CURLOPT(CURLOPT_USERAGENT, CURLOPTTYPE_STRINGPOINT, 18),
+
+ /* If the download receives less than "low speed limit" bytes/second
+ * during "low speed time" seconds, the operations is aborted.
+ * You could i.e if you have a pretty high speed connection, abort if
+ * it is less than 2000 bytes/sec during 20 seconds.
+ */
+
+ /* Set the "low speed limit" */
+ CURLOPT(CURLOPT_LOW_SPEED_LIMIT, CURLOPTTYPE_LONG, 19),
+
+ /* Set the "low speed time" */
+ CURLOPT(CURLOPT_LOW_SPEED_TIME, CURLOPTTYPE_LONG, 20),
+
+ /* Set the continuation offset.
+ *
+ * Note there is also a _LARGE version of this key which uses
+ * off_t types, allowing for large file offsets on platforms which
+ * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE.
+ */
+ CURLOPT(CURLOPT_RESUME_FROM, CURLOPTTYPE_LONG, 21),
+
+ /* Set cookie in request: */
+ CURLOPT(CURLOPT_COOKIE, CURLOPTTYPE_STRINGPOINT, 22),
+
+ /* This points to a linked list of headers, struct curl_slist kind. This
+ list is also used for RTSP (in spite of its name) */
+ CURLOPT(CURLOPT_HTTPHEADER, CURLOPTTYPE_SLISTPOINT, 23),
+
+ /* This points to a linked list of post entries, struct curl_httppost */
+ CURLOPTDEPRECATED(CURLOPT_HTTPPOST, CURLOPTTYPE_OBJECTPOINT, 24,
+ 7.56.0, "Use CURLOPT_MIMEPOST"),
+
+ /* name of the file keeping your private SSL-certificate */
+ CURLOPT(CURLOPT_SSLCERT, CURLOPTTYPE_STRINGPOINT, 25),
+
+ /* password for the SSL or SSH private key */
+ CURLOPT(CURLOPT_KEYPASSWD, CURLOPTTYPE_STRINGPOINT, 26),
+
+ /* send TYPE parameter? */
+ CURLOPT(CURLOPT_CRLF, CURLOPTTYPE_LONG, 27),
+
+ /* send linked-list of QUOTE commands */
+ CURLOPT(CURLOPT_QUOTE, CURLOPTTYPE_SLISTPOINT, 28),
+
+ /* 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_CBPOINT, 29),
+
+ /* point to a file to read the initial cookies from, also enables
+ "cookie awareness" */
+ CURLOPT(CURLOPT_COOKIEFILE, CURLOPTTYPE_STRINGPOINT, 31),
+
+ /* What version to specifically try to use.
+ See CURL_SSLVERSION defines below. */
+ CURLOPT(CURLOPT_SSLVERSION, CURLOPTTYPE_VALUES, 32),
+
+ /* What kind of HTTP time condition to use, see defines */
+ CURLOPT(CURLOPT_TIMECONDITION, CURLOPTTYPE_VALUES, 33),
+
+ /* Time to use with the above condition. Specified in number of seconds
+ since 1 Jan 1970 */
+ CURLOPT(CURLOPT_TIMEVALUE, CURLOPTTYPE_LONG, 34),
+
+ /* 35 = OBSOLETE */
+
+ /* Custom request, for customizing the get command like
+ HTTP: DELETE, TRACE and others
+ FTP: to use a different list command
+ */
+ CURLOPT(CURLOPT_CUSTOMREQUEST, CURLOPTTYPE_STRINGPOINT, 36),
+
+ /* FILE handle to use instead of stderr */
+ CURLOPT(CURLOPT_STDERR, CURLOPTTYPE_OBJECTPOINT, 37),
+
+ /* 38 is not used */
+
+ /* send linked-list of post-transfer QUOTE commands */
+ CURLOPT(CURLOPT_POSTQUOTE, CURLOPTTYPE_SLISTPOINT, 39),
+
+ /* OBSOLETE, do not use! */
+ CURLOPT(CURLOPT_OBSOLETE40, CURLOPTTYPE_OBJECTPOINT, 40),
+
+ /* talk a lot */
+ CURLOPT(CURLOPT_VERBOSE, CURLOPTTYPE_LONG, 41),
+
+ /* throw the header out too */
+ CURLOPT(CURLOPT_HEADER, CURLOPTTYPE_LONG, 42),
+
+ /* shut off the progress meter */
+ CURLOPT(CURLOPT_NOPROGRESS, CURLOPTTYPE_LONG, 43),
+
+ /* use HEAD to get http document */
+ CURLOPT(CURLOPT_NOBODY, CURLOPTTYPE_LONG, 44),
+
+ /* no output on http error codes >= 400 */
+ CURLOPT(CURLOPT_FAILONERROR, CURLOPTTYPE_LONG, 45),
+
+ /* this is an upload */
+ CURLOPT(CURLOPT_UPLOAD, CURLOPTTYPE_LONG, 46),
+
+ /* HTTP POST method */
+ CURLOPT(CURLOPT_POST, CURLOPTTYPE_LONG, 47),
+
+ /* bare names when listing directories */
+ CURLOPT(CURLOPT_DIRLISTONLY, CURLOPTTYPE_LONG, 48),
+
+ /* Append instead of overwrite on upload! */
+ CURLOPT(CURLOPT_APPEND, CURLOPTTYPE_LONG, 50),
+
+ /* 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_VALUES, 51),
+
+ /* use Location: Luke! */
+ CURLOPT(CURLOPT_FOLLOWLOCATION, CURLOPTTYPE_LONG, 52),
+
+ /* transfer data in text/ASCII format */
+ CURLOPT(CURLOPT_TRANSFERTEXT, CURLOPTTYPE_LONG, 53),
+
+ /* HTTP PUT */
+ CURLOPTDEPRECATED(CURLOPT_PUT, CURLOPTTYPE_LONG, 54,
+ 7.12.1, "Use CURLOPT_UPLOAD"),
+
+ /* 55 = OBSOLETE */
+
+ /* DEPRECATED
+ * Function that will be called instead of the internal progress display
+ * function. This function should be defined as the curl_progress_callback
+ * prototype defines. */
+ CURLOPTDEPRECATED(CURLOPT_PROGRESSFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 56,
+ 7.32.0, "Use CURLOPT_XFERINFOFUNCTION"),
+
+ /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION
+ callbacks */
+ 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),
+
+ /* Port of the proxy, can be set in the proxy string as well with:
+ "[host]:[port]" */
+ CURLOPT(CURLOPT_PROXYPORT, CURLOPTTYPE_LONG, 59),
+
+ /* size of the POST input data, if strlen() is not good to use */
+ CURLOPT(CURLOPT_POSTFIELDSIZE, CURLOPTTYPE_LONG, 60),
+
+ /* tunnel non-http operations through an HTTP proxy */
+ CURLOPT(CURLOPT_HTTPPROXYTUNNEL, CURLOPTTYPE_LONG, 61),
+
+ /* Set the interface string to use as outgoing network interface */
+ CURLOPT(CURLOPT_INTERFACE, CURLOPTTYPE_STRINGPOINT, 62),
+
+ /* Set the krb4/5 security level, this also enables krb4/5 awareness. This
+ * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string
+ * is set but doesn't match one of these, 'private' will be used. */
+ CURLOPT(CURLOPT_KRBLEVEL, CURLOPTTYPE_STRINGPOINT, 63),
+
+ /* Set if we should verify the peer in ssl handshake, set 1 to verify. */
+ CURLOPT(CURLOPT_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 64),
+
+ /* The CApath or CAfile used to validate the peer certificate
+ this option is used only if SSL_VERIFYPEER is true */
+ CURLOPT(CURLOPT_CAINFO, CURLOPTTYPE_STRINGPOINT, 65),
+
+ /* 66 = OBSOLETE */
+ /* 67 = OBSOLETE */
+
+ /* Maximum number of http redirects to follow */
+ CURLOPT(CURLOPT_MAXREDIRS, CURLOPTTYPE_LONG, 68),
+
+ /* Pass a long set to 1 to get the date of the requested document (if
+ possible)! Pass a zero to shut it off. */
+ CURLOPT(CURLOPT_FILETIME, CURLOPTTYPE_LONG, 69),
+
+ /* This points to a linked list of telnet options */
+ CURLOPT(CURLOPT_TELNETOPTIONS, CURLOPTTYPE_SLISTPOINT, 70),
+
+ /* Max amount of cached alive connections */
+ CURLOPT(CURLOPT_MAXCONNECTS, CURLOPTTYPE_LONG, 71),
+
+ /* OBSOLETE, do not use! */
+ CURLOPT(CURLOPT_OBSOLETE72, CURLOPTTYPE_LONG, 72),
+
+ /* 73 = OBSOLETE */
+
+ /* Set to explicitly use a new connection for the upcoming transfer.
+ Do not use this unless you're absolutely sure of this, as it makes the
+ operation slower and is less friendly for the network. */
+ CURLOPT(CURLOPT_FRESH_CONNECT, CURLOPTTYPE_LONG, 74),
+
+ /* Set to explicitly forbid the upcoming transfer's connection to be reused
+ when done. Do not use this unless you're absolutely sure of this, as it
+ makes the operation slower and is less friendly for the network. */
+ CURLOPT(CURLOPT_FORBID_REUSE, CURLOPTTYPE_LONG, 75),
+
+ /* Set to a file name that contains random data for libcurl to use to
+ seed the random engine when doing SSL connects. */
+ CURLOPTDEPRECATED(CURLOPT_RANDOM_FILE, CURLOPTTYPE_STRINGPOINT, 76,
+ 7.84.0, "Serves no purpose anymore"),
+
+ /* Set to the Entropy Gathering Daemon socket pathname */
+ CURLOPTDEPRECATED(CURLOPT_EGDSOCKET, CURLOPTTYPE_STRINGPOINT, 77,
+ 7.84.0, "Serves no purpose anymore"),
+
+ /* Time-out connect operations after this amount of seconds, if connects are
+ OK within this time, then fine... This only aborts the connect phase. */
+ CURLOPT(CURLOPT_CONNECTTIMEOUT, CURLOPTTYPE_LONG, 78),
+
+ /* Function that will be called to store headers (instead of fwrite). The
+ * parameters will use fwrite() syntax, make sure to follow them. */
+ CURLOPT(CURLOPT_HEADERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 79),
+
+ /* Set this to force the HTTP request to get back to GET. Only really usable
+ if POST, PUT or a custom request have been used first.
+ */
+ CURLOPT(CURLOPT_HTTPGET, CURLOPTTYPE_LONG, 80),
+
+ /* Set if we should verify the Common name from the peer certificate in ssl
+ * handshake, set 1 to check existence, 2 to ensure that it matches the
+ * provided hostname. */
+ CURLOPT(CURLOPT_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 81),
+
+ /* Specify which file name to write all known cookies in after completed
+ operation. Set file name to "-" (dash) to make it go to stdout. */
+ CURLOPT(CURLOPT_COOKIEJAR, CURLOPTTYPE_STRINGPOINT, 82),
+
+ /* Specify which SSL ciphers to use */
+ CURLOPT(CURLOPT_SSL_CIPHER_LIST, CURLOPTTYPE_STRINGPOINT, 83),
+
+ /* 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_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
+ PASV command. */
+ CURLOPT(CURLOPT_FTP_USE_EPSV, CURLOPTTYPE_LONG, 85),
+
+ /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */
+ CURLOPT(CURLOPT_SSLCERTTYPE, CURLOPTTYPE_STRINGPOINT, 86),
+
+ /* name of the file keeping your private SSL-key */
+ CURLOPT(CURLOPT_SSLKEY, CURLOPTTYPE_STRINGPOINT, 87),
+
+ /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */
+ CURLOPT(CURLOPT_SSLKEYTYPE, CURLOPTTYPE_STRINGPOINT, 88),
+
+ /* crypto engine for the SSL-sub system */
+ CURLOPT(CURLOPT_SSLENGINE, CURLOPTTYPE_STRINGPOINT, 89),
+
+ /* set the crypto engine for the SSL-sub system as default
+ the param has no meaning...
+ */
+ CURLOPT(CURLOPT_SSLENGINE_DEFAULT, CURLOPTTYPE_LONG, 90),
+
+ /* Non-zero value means to use the global dns cache */
+ /* DEPRECATED, do not use! */
+ CURLOPTDEPRECATED(CURLOPT_DNS_USE_GLOBAL_CACHE, CURLOPTTYPE_LONG, 91,
+ 7.11.1, "Use CURLOPT_SHARE"),
+
+ /* DNS cache timeout */
+ CURLOPT(CURLOPT_DNS_CACHE_TIMEOUT, CURLOPTTYPE_LONG, 92),
+
+ /* send linked-list of pre-transfer QUOTE commands */
+ CURLOPT(CURLOPT_PREQUOTE, CURLOPTTYPE_SLISTPOINT, 93),
+
+ /* set the debug function */
+ CURLOPT(CURLOPT_DEBUGFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 94),
+
+ /* set the data for the debug function */
+ CURLOPT(CURLOPT_DEBUGDATA, CURLOPTTYPE_CBPOINT, 95),
+
+ /* mark this as start of a cookie session */
+ CURLOPT(CURLOPT_COOKIESESSION, CURLOPTTYPE_LONG, 96),
+
+ /* The CApath directory used to validate the peer certificate
+ this option is used only if SSL_VERIFYPEER is true */
+ CURLOPT(CURLOPT_CAPATH, CURLOPTTYPE_STRINGPOINT, 97),
+
+ /* Instruct libcurl to use a smaller receive buffer */
+ CURLOPT(CURLOPT_BUFFERSIZE, CURLOPTTYPE_LONG, 98),
+
+ /* Instruct libcurl to not use any signal/alarm handlers, even when using
+ timeouts. This option is useful for multi-threaded applications.
+ See libcurl-the-guide for more background information. */
+ CURLOPT(CURLOPT_NOSIGNAL, CURLOPTTYPE_LONG, 99),
+
+ /* Provide a CURLShare for mutexing non-ts data */
+ CURLOPT(CURLOPT_SHARE, CURLOPTTYPE_OBJECTPOINT, 100),
+
+ /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
+ CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and
+ CURLPROXY_SOCKS5. */
+ 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
+ CURLOPT_ENCODING */
+ CURLOPT(CURLOPT_ACCEPT_ENCODING, CURLOPTTYPE_STRINGPOINT, 102),
+
+ /* Set pointer to private data */
+ CURLOPT(CURLOPT_PRIVATE, CURLOPTTYPE_OBJECTPOINT, 103),
+
+ /* Set aliases for HTTP 200 in the HTTP Response header */
+ CURLOPT(CURLOPT_HTTP200ALIASES, CURLOPTTYPE_SLISTPOINT, 104),
+
+ /* Continue to send authentication (user+password) when following locations,
+ even when hostname changed. This can potentially send off the name
+ and password to whatever host the server decides. */
+ CURLOPT(CURLOPT_UNRESTRICTED_AUTH, CURLOPTTYPE_LONG, 105),
+
+ /* Specifically switch on or off the FTP engine's use of the EPRT command (
+ it also disables the LPRT attempt). By default, those ones will always be
+ attempted before the good old traditional PORT command. */
+ CURLOPT(CURLOPT_FTP_USE_EPRT, CURLOPTTYPE_LONG, 106),
+
+ /* 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_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.
+ The function must match the curl_ssl_ctx_callback prototype. */
+ CURLOPT(CURLOPT_SSL_CTX_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 108),
+
+ /* Set the userdata for the ssl context callback function's third
+ argument */
+ 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
+ CURLFTP_CREATE_DIR prefix.
+ */
+ CURLOPT(CURLOPT_FTP_CREATE_MISSING_DIRS, CURLOPTTYPE_LONG, 110),
+
+ /* 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_VALUES, 111),
+
+ /* Option that changes the timeout, in seconds, associated with getting a
+ response. This is different from transfer timeout time and essentially
+ places a demand on the server to acknowledge commands in a timely
+ manner. For FTP, SMTP, IMAP and POP3. */
+ CURLOPT(CURLOPT_SERVER_RESPONSE_TIMEOUT, CURLOPTTYPE_LONG, 112),
+
+ /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to
+ tell libcurl to use those IP versions only. This only has effect on
+ systems with support for more than one, i.e IPv4 _and_ IPv6. */
+ 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.
+
+ Note there is also _LARGE version which adds large file support for
+ platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */
+ CURLOPT(CURLOPT_MAXFILESIZE, CURLOPTTYPE_LONG, 114),
+
+ /* See the comment for INFILESIZE above, but in short, specifies
+ * the size of the file being uploaded. -1 means unknown.
+ */
+ CURLOPT(CURLOPT_INFILESIZE_LARGE, CURLOPTTYPE_OFF_T, 115),
+
+ /* Sets the continuation offset. There is also a CURLOPTTYPE_LONG version
+ * of this; look above for RESUME_FROM.
+ */
+ CURLOPT(CURLOPT_RESUME_FROM_LARGE, CURLOPTTYPE_OFF_T, 116),
+
+ /* Sets the maximum size of data that will be downloaded from
+ * an HTTP or FTP server. See MAXFILESIZE above for the LONG version.
+ */
+ CURLOPT(CURLOPT_MAXFILESIZE_LARGE, CURLOPTTYPE_OFF_T, 117),
+
+ /* Set this option to the file name of your .netrc file you want libcurl
+ to parse (using the CURLOPT_NETRC option). If not set, libcurl will do
+ a poor attempt to find the user's home directory and check for a .netrc
+ file in there. */
+ CURLOPT(CURLOPT_NETRC_FILE, CURLOPTTYPE_STRINGPOINT, 118),
+
+ /* Enable SSL/TLS for FTP, pick one of:
+ CURLUSESSL_TRY - try using SSL, proceed anyway otherwise
+ CURLUSESSL_CONTROL - SSL for the control connection or fail
+ CURLUSESSL_ALL - SSL for all communication or fail
+ */
+ CURLOPT(CURLOPT_USE_SSL, CURLOPTTYPE_VALUES, 119),
+
+ /* The _LARGE version of the standard POSTFIELDSIZE option */
+ CURLOPT(CURLOPT_POSTFIELDSIZE_LARGE, CURLOPTTYPE_OFF_T, 120),
+
+ /* Enable/disable the TCP Nagle algorithm */
+ CURLOPT(CURLOPT_TCP_NODELAY, CURLOPTTYPE_LONG, 121),
+
+ /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 123 OBSOLETE. Gone in 7.16.0 */
+ /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 127 OBSOLETE. Gone in 7.16.0 */
+ /* 128 OBSOLETE. Gone in 7.16.0 */
+
+ /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option
+ can be used to change libcurl's default action which is to first try
+ "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK
+ response has been received.
+
+ Available parameters are:
+ CURLFTPAUTH_DEFAULT - let libcurl decide
+ CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS
+ CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL
+ */
+ CURLOPT(CURLOPT_FTPSSLAUTH, CURLOPTTYPE_VALUES, 129),
+
+ CURLOPTDEPRECATED(CURLOPT_IOCTLFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 130,
+ 7.18.0, "Use CURLOPT_SEEKFUNCTION"),
+ CURLOPTDEPRECATED(CURLOPT_IOCTLDATA, CURLOPTTYPE_CBPOINT, 131,
+ 7.18.0, "Use CURLOPT_SEEKDATA"),
+
+ /* 132 OBSOLETE. Gone in 7.16.0 */
+ /* 133 OBSOLETE. Gone in 7.16.0 */
+
+ /* null-terminated string for pass on to the FTP server when asked for
+ "account" info */
+ CURLOPT(CURLOPT_FTP_ACCOUNT, CURLOPTTYPE_STRINGPOINT, 134),
+
+ /* feed cookie into cookie engine */
+ CURLOPT(CURLOPT_COOKIELIST, CURLOPTTYPE_STRINGPOINT, 135),
+
+ /* ignore Content-Length */
+ CURLOPT(CURLOPT_IGNORE_CONTENT_LENGTH, CURLOPTTYPE_LONG, 136),
+
+ /* Set to non-zero to skip the IP address received in a 227 PASV FTP server
+ response. Typically used for FTP-SSL purposes but is not restricted to
+ that. libcurl will then instead use the same IP address it used for the
+ control connection. */
+ CURLOPT(CURLOPT_FTP_SKIP_PASV_IP, CURLOPTTYPE_LONG, 137),
+
+ /* Select "file method" to use when doing FTP, see the curl_ftpmethod
+ above. */
+ CURLOPT(CURLOPT_FTP_FILEMETHOD, CURLOPTTYPE_VALUES, 138),
+
+ /* Local port number to bind the socket to */
+ CURLOPT(CURLOPT_LOCALPORT, CURLOPTTYPE_LONG, 139),
+
+ /* Number of ports to try, including the first one set with LOCALPORT.
+ Thus, setting it to 1 will make no additional attempts but the first.
+ */
+ CURLOPT(CURLOPT_LOCALPORTRANGE, CURLOPTTYPE_LONG, 140),
+
+ /* no transfer, set up connection and let application use the socket by
+ extracting it with CURLINFO_LASTSOCKET */
+ CURLOPT(CURLOPT_CONNECT_ONLY, CURLOPTTYPE_LONG, 141),
+
+ /* Function that will be called to convert from the
+ network encoding (instead of using the iconv calls in libcurl) */
+ CURLOPTDEPRECATED(CURLOPT_CONV_FROM_NETWORK_FUNCTION,
+ CURLOPTTYPE_FUNCTIONPOINT, 142,
+ 7.82.0, "Serves no purpose anymore"),
+
+ /* Function that will be called to convert to the
+ network encoding (instead of using the iconv calls in libcurl) */
+ CURLOPTDEPRECATED(CURLOPT_CONV_TO_NETWORK_FUNCTION,
+ CURLOPTTYPE_FUNCTIONPOINT, 143,
+ 7.82.0, "Serves no purpose anymore"),
+
+ /* Function that will be called to convert from UTF8
+ (instead of using the iconv calls in libcurl)
+ Note that this is used only for SSL certificate processing */
+ CURLOPTDEPRECATED(CURLOPT_CONV_FROM_UTF8_FUNCTION,
+ CURLOPTTYPE_FUNCTIONPOINT, 144,
+ 7.82.0, "Serves no purpose anymore"),
+
+ /* if the connection proceeds too quickly then need to slow it down */
+ /* limit-rate: maximum number of bytes per second to send or receive */
+ CURLOPT(CURLOPT_MAX_SEND_SPEED_LARGE, CURLOPTTYPE_OFF_T, 145),
+ CURLOPT(CURLOPT_MAX_RECV_SPEED_LARGE, CURLOPTTYPE_OFF_T, 146),
+
+ /* Pointer to command string to send if USER/PASS fails. */
+ CURLOPT(CURLOPT_FTP_ALTERNATIVE_TO_USER, CURLOPTTYPE_STRINGPOINT, 147),
+
+ /* callback function for setting socket options */
+ CURLOPT(CURLOPT_SOCKOPTFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 148),
+ CURLOPT(CURLOPT_SOCKOPTDATA, CURLOPTTYPE_CBPOINT, 149),
+
+ /* set to 0 to disable session ID reuse 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_VALUES, 151),
+
+ /* Used by scp/sftp to do public/private key authentication */
+ CURLOPT(CURLOPT_SSH_PUBLIC_KEYFILE, CURLOPTTYPE_STRINGPOINT, 152),
+ CURLOPT(CURLOPT_SSH_PRIVATE_KEYFILE, CURLOPTTYPE_STRINGPOINT, 153),
+
+ /* Send CCC (Clear Command Channel) after authentication */
+ CURLOPT(CURLOPT_FTP_SSL_CCC, CURLOPTTYPE_LONG, 154),
+
+ /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */
+ CURLOPT(CURLOPT_TIMEOUT_MS, CURLOPTTYPE_LONG, 155),
+ CURLOPT(CURLOPT_CONNECTTIMEOUT_MS, CURLOPTTYPE_LONG, 156),
+
+ /* set to zero to disable the libcurl's decoding and thus pass the raw body
+ data to the application even when it is encoded/compressed */
+ CURLOPT(CURLOPT_HTTP_TRANSFER_DECODING, CURLOPTTYPE_LONG, 157),
+ CURLOPT(CURLOPT_HTTP_CONTENT_DECODING, CURLOPTTYPE_LONG, 158),
+
+ /* Permission used when creating new files and directories on the remote
+ server for protocols that support it, SFTP/SCP/FILE */
+ CURLOPT(CURLOPT_NEW_FILE_PERMS, CURLOPTTYPE_LONG, 159),
+ CURLOPT(CURLOPT_NEW_DIRECTORY_PERMS, CURLOPTTYPE_LONG, 160),
+
+ /* Set the behavior 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_VALUES, 161),
+
+ /* used by scp/sftp to verify the host's public key */
+ CURLOPT(CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, CURLOPTTYPE_STRINGPOINT, 162),
+
+ /* Callback function for opening socket (instead of socket(2)). Optionally,
+ callback is able change the address or refuse to connect returning
+ CURL_SOCKET_BAD. The callback should have type
+ curl_opensocket_callback */
+ CURLOPT(CURLOPT_OPENSOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 163),
+ CURLOPT(CURLOPT_OPENSOCKETDATA, CURLOPTTYPE_CBPOINT, 164),
+
+ /* POST volatile input fields. */
+ CURLOPT(CURLOPT_COPYPOSTFIELDS, CURLOPTTYPE_OBJECTPOINT, 165),
+
+ /* set transfer mode (;type=) when doing FTP via an HTTP proxy */
+ CURLOPT(CURLOPT_PROXY_TRANSFER_MODE, CURLOPTTYPE_LONG, 166),
+
+ /* Callback function for seeking in the input stream */
+ CURLOPT(CURLOPT_SEEKFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 167),
+ CURLOPT(CURLOPT_SEEKDATA, CURLOPTTYPE_CBPOINT, 168),
+
+ /* CRL file */
+ CURLOPT(CURLOPT_CRLFILE, CURLOPTTYPE_STRINGPOINT, 169),
+
+ /* Issuer certificate */
+ CURLOPT(CURLOPT_ISSUERCERT, CURLOPTTYPE_STRINGPOINT, 170),
+
+ /* (IPv6) Address scope */
+ CURLOPT(CURLOPT_ADDRESS_SCOPE, CURLOPTTYPE_LONG, 171),
+
+ /* Collect certificate chain info and allow it to get retrievable with
+ CURLINFO_CERTINFO after the transfer is complete. */
+ CURLOPT(CURLOPT_CERTINFO, CURLOPTTYPE_LONG, 172),
+
+ /* "name" and "pwd" to use when fetching. */
+ CURLOPT(CURLOPT_USERNAME, CURLOPTTYPE_STRINGPOINT, 173),
+ CURLOPT(CURLOPT_PASSWORD, CURLOPTTYPE_STRINGPOINT, 174),
+
+ /* "name" and "pwd" to use with Proxy when fetching. */
+ CURLOPT(CURLOPT_PROXYUSERNAME, CURLOPTTYPE_STRINGPOINT, 175),
+ CURLOPT(CURLOPT_PROXYPASSWORD, CURLOPTTYPE_STRINGPOINT, 176),
+
+ /* Comma separated list of hostnames defining no-proxy zones. These should
+ match both hostnames directly, and hostnames within a domain. For
+ example, local.com will match local.com and www.local.com, but NOT
+ notlocal.com or www.notlocal.com. For compatibility with other
+ implementations of this, .local.com will be considered to be the same as
+ local.com. A single * is the only valid wildcard, and effectively
+ disables the use of proxy. */
+ CURLOPT(CURLOPT_NOPROXY, CURLOPTTYPE_STRINGPOINT, 177),
+
+ /* block size for TFTP transfers */
+ CURLOPT(CURLOPT_TFTP_BLKSIZE, CURLOPTTYPE_LONG, 178),
+
+ /* Socks Service */
+ /* DEPRECATED, do not use! */
+ CURLOPTDEPRECATED(CURLOPT_SOCKS5_GSSAPI_SERVICE,
+ CURLOPTTYPE_STRINGPOINT, 179,
+ 7.49.0, "Use CURLOPT_PROXY_SERVICE_NAME"),
+
+ /* Socks Service */
+ CURLOPT(CURLOPT_SOCKS5_GSSAPI_NEC, CURLOPTTYPE_LONG, 180),
+
+ /* set the bitmask for the protocols that are allowed to be used for the
+ transfer, which thus helps the app which takes URLs from users or other
+ external inputs and want to restrict what protocol(s) to deal
+ with. Defaults to CURLPROTO_ALL. */
+ CURLOPTDEPRECATED(CURLOPT_PROTOCOLS, CURLOPTTYPE_LONG, 181,
+ 7.85.0, "Use CURLOPT_PROTOCOLS_STR"),
+
+ /* set the bitmask for the protocols that libcurl is allowed to follow to,
+ as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
+ to be set in both bitmasks to be allowed to get redirected to. */
+ CURLOPTDEPRECATED(CURLOPT_REDIR_PROTOCOLS, CURLOPTTYPE_LONG, 182,
+ 7.85.0, "Use CURLOPT_REDIR_PROTOCOLS_STR"),
+
+ /* set the SSH knownhost file name to use */
+ CURLOPT(CURLOPT_SSH_KNOWNHOSTS, CURLOPTTYPE_STRINGPOINT, 183),
+
+ /* set the SSH host key callback, must point to a curl_sshkeycallback
+ function */
+ CURLOPT(CURLOPT_SSH_KEYFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 184),
+
+ /* set the SSH host key callback custom pointer */
+ CURLOPT(CURLOPT_SSH_KEYDATA, CURLOPTTYPE_CBPOINT, 185),
+
+ /* set the SMTP mail originator */
+ CURLOPT(CURLOPT_MAIL_FROM, CURLOPTTYPE_STRINGPOINT, 186),
+
+ /* set the list of SMTP mail receiver(s) */
+ CURLOPT(CURLOPT_MAIL_RCPT, CURLOPTTYPE_SLISTPOINT, 187),
+
+ /* FTP: send PRET before PASV */
+ CURLOPT(CURLOPT_FTP_USE_PRET, CURLOPTTYPE_LONG, 188),
+
+ /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */
+ CURLOPT(CURLOPT_RTSP_REQUEST, CURLOPTTYPE_VALUES, 189),
+
+ /* The RTSP session identifier */
+ CURLOPT(CURLOPT_RTSP_SESSION_ID, CURLOPTTYPE_STRINGPOINT, 190),
+
+ /* The RTSP stream URI */
+ CURLOPT(CURLOPT_RTSP_STREAM_URI, CURLOPTTYPE_STRINGPOINT, 191),
+
+ /* The Transport: header to use in RTSP requests */
+ CURLOPT(CURLOPT_RTSP_TRANSPORT, CURLOPTTYPE_STRINGPOINT, 192),
+
+ /* Manually initialize the client RTSP CSeq for this handle */
+ CURLOPT(CURLOPT_RTSP_CLIENT_CSEQ, CURLOPTTYPE_LONG, 193),
+
+ /* Manually initialize the server RTSP CSeq for this handle */
+ CURLOPT(CURLOPT_RTSP_SERVER_CSEQ, CURLOPTTYPE_LONG, 194),
+
+ /* The stream to pass to INTERLEAVEFUNCTION. */
+ CURLOPT(CURLOPT_INTERLEAVEDATA, CURLOPTTYPE_CBPOINT, 195),
+
+ /* Let the application define a custom write method for RTP data */
+ CURLOPT(CURLOPT_INTERLEAVEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 196),
+
+ /* Turn on wildcard matching */
+ CURLOPT(CURLOPT_WILDCARDMATCH, CURLOPTTYPE_LONG, 197),
+
+ /* Directory matching callback called before downloading of an
+ individual file (chunk) started */
+ CURLOPT(CURLOPT_CHUNK_BGN_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 198),
+
+ /* Directory matching callback called after the file (chunk)
+ was downloaded, or skipped */
+ CURLOPT(CURLOPT_CHUNK_END_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 199),
+
+ /* Change match (fnmatch-like) callback for wildcard matching */
+ CURLOPT(CURLOPT_FNMATCH_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 200),
+
+ /* Let the application define custom chunk data pointer */
+ CURLOPT(CURLOPT_CHUNK_DATA, CURLOPTTYPE_CBPOINT, 201),
+
+ /* FNMATCH_FUNCTION user pointer */
+ CURLOPT(CURLOPT_FNMATCH_DATA, CURLOPTTYPE_CBPOINT, 202),
+
+ /* send linked-list of name:port:address sets */
+ CURLOPT(CURLOPT_RESOLVE, CURLOPTTYPE_SLISTPOINT, 203),
+
+ /* Set a username for authenticated TLS */
+ CURLOPT(CURLOPT_TLSAUTH_USERNAME, CURLOPTTYPE_STRINGPOINT, 204),
+
+ /* Set a password for authenticated TLS */
+ CURLOPT(CURLOPT_TLSAUTH_PASSWORD, CURLOPTTYPE_STRINGPOINT, 205),
+
+ /* Set authentication type for authenticated TLS */
+ CURLOPT(CURLOPT_TLSAUTH_TYPE, CURLOPTTYPE_STRINGPOINT, 206),
+
+ /* Set to 1 to enable the "TE:" header in HTTP requests to ask for
+ compressed transfer-encoded responses. Set to 0 to disable the use of TE:
+ in outgoing requests. The current default is 0, but it might change in a
+ future libcurl release.
+
+ libcurl will ask for the compressed methods it knows of, and if that
+ isn't any, it will not ask for transfer-encoding at all even if this
+ option is set to 1.
+
+ */
+ CURLOPT(CURLOPT_TRANSFER_ENCODING, CURLOPTTYPE_LONG, 207),
+
+ /* 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_CBPOINT, 209),
+
+ /* allow GSSAPI credential delegation */
+ CURLOPT(CURLOPT_GSSAPI_DELEGATION, CURLOPTTYPE_VALUES, 210),
+
+ /* Set the name servers to use for DNS resolution */
+ CURLOPT(CURLOPT_DNS_SERVERS, CURLOPTTYPE_STRINGPOINT, 211),
+
+ /* Time-out accept operations (currently for FTP only) after this amount
+ of milliseconds. */
+ CURLOPT(CURLOPT_ACCEPTTIMEOUT_MS, CURLOPTTYPE_LONG, 212),
+
+ /* Set TCP keepalive */
+ CURLOPT(CURLOPT_TCP_KEEPALIVE, CURLOPTTYPE_LONG, 213),
+
+ /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */
+ CURLOPT(CURLOPT_TCP_KEEPIDLE, CURLOPTTYPE_LONG, 214),
+ CURLOPT(CURLOPT_TCP_KEEPINTVL, CURLOPTTYPE_LONG, 215),
+
+ /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */
+ CURLOPT(CURLOPT_SSL_OPTIONS, CURLOPTTYPE_VALUES, 216),
+
+ /* Set the SMTP auth originator */
+ CURLOPT(CURLOPT_MAIL_AUTH, CURLOPTTYPE_STRINGPOINT, 217),
+
+ /* Enable/disable SASL initial response */
+ CURLOPT(CURLOPT_SASL_IR, CURLOPTTYPE_LONG, 218),
+
+ /* Function that will be called instead of the internal progress display
+ * function. This function should be defined as the curl_xferinfo_callback
+ * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */
+ CURLOPT(CURLOPT_XFERINFOFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 219),
+
+ /* The XOAUTH2 bearer token */
+ CURLOPT(CURLOPT_XOAUTH2_BEARER, CURLOPTTYPE_STRINGPOINT, 220),
+
+ /* Set the interface string to use as outgoing network
+ * interface for DNS requests.
+ * Only supported by the c-ares DNS backend */
+ CURLOPT(CURLOPT_DNS_INTERFACE, CURLOPTTYPE_STRINGPOINT, 221),
+
+ /* Set the local IPv4 address to use for outgoing DNS requests.
+ * Only supported by the c-ares DNS backend */
+ CURLOPT(CURLOPT_DNS_LOCAL_IP4, CURLOPTTYPE_STRINGPOINT, 222),
+
+ /* Set the local IPv6 address to use for outgoing DNS requests.
+ * Only supported by the c-ares DNS backend */
+ CURLOPT(CURLOPT_DNS_LOCAL_IP6, CURLOPTTYPE_STRINGPOINT, 223),
+
+ /* Set authentication options directly */
+ CURLOPT(CURLOPT_LOGIN_OPTIONS, CURLOPTTYPE_STRINGPOINT, 224),
+
+ /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */
+ CURLOPTDEPRECATED(CURLOPT_SSL_ENABLE_NPN, CURLOPTTYPE_LONG, 225,
+ 7.86.0, "Has no function"),
+
+ /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */
+ CURLOPT(CURLOPT_SSL_ENABLE_ALPN, CURLOPTTYPE_LONG, 226),
+
+ /* Time to wait for a response to an HTTP request containing an
+ * Expect: 100-continue header before sending the data anyway. */
+ CURLOPT(CURLOPT_EXPECT_100_TIMEOUT_MS, CURLOPTTYPE_LONG, 227),
+
+ /* This points to a linked list of headers used for proxy requests only,
+ struct curl_slist kind */
+ CURLOPT(CURLOPT_PROXYHEADER, CURLOPTTYPE_SLISTPOINT, 228),
+
+ /* Pass in a bitmask of "header options" */
+ 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 */
+ CURLOPT(CURLOPT_PINNEDPUBLICKEY, CURLOPTTYPE_STRINGPOINT, 230),
+
+ /* Path to Unix domain socket */
+ CURLOPT(CURLOPT_UNIX_SOCKET_PATH, CURLOPTTYPE_STRINGPOINT, 231),
+
+ /* Set if we should verify the certificate status. */
+ CURLOPT(CURLOPT_SSL_VERIFYSTATUS, CURLOPTTYPE_LONG, 232),
+
+ /* Set if we should enable TLS false start. */
+ CURLOPT(CURLOPT_SSL_FALSESTART, CURLOPTTYPE_LONG, 233),
+
+ /* Do not squash dot-dot sequences */
+ CURLOPT(CURLOPT_PATH_AS_IS, CURLOPTTYPE_LONG, 234),
+
+ /* Proxy Service Name */
+ CURLOPT(CURLOPT_PROXY_SERVICE_NAME, CURLOPTTYPE_STRINGPOINT, 235),
+
+ /* Service Name */
+ CURLOPT(CURLOPT_SERVICE_NAME, CURLOPTTYPE_STRINGPOINT, 236),
+
+ /* Wait/don't wait for pipe/mutex to clarify */
+ CURLOPT(CURLOPT_PIPEWAIT, CURLOPTTYPE_LONG, 237),
+
+ /* Set the protocol used when curl is given a URL without a protocol */
+ CURLOPT(CURLOPT_DEFAULT_PROTOCOL, CURLOPTTYPE_STRINGPOINT, 238),
+
+ /* Set stream weight, 1 - 256 (default is 16) */
+ CURLOPT(CURLOPT_STREAM_WEIGHT, CURLOPTTYPE_LONG, 239),
+
+ /* Set stream dependency on another CURL handle */
+ CURLOPT(CURLOPT_STREAM_DEPENDS, CURLOPTTYPE_OBJECTPOINT, 240),
+
+ /* Set E-xclusive stream dependency on another CURL handle */
+ CURLOPT(CURLOPT_STREAM_DEPENDS_E, CURLOPTTYPE_OBJECTPOINT, 241),
+
+ /* Do not send any tftp option requests to the server */
+ CURLOPT(CURLOPT_TFTP_NO_OPTIONS, CURLOPTTYPE_LONG, 242),
+
+ /* Linked-list of host:port:connect-to-host:connect-to-port,
+ overrides the URL's host:port (only for the network layer) */
+ CURLOPT(CURLOPT_CONNECT_TO, CURLOPTTYPE_SLISTPOINT, 243),
+
+ /* Set TCP Fast Open */
+ CURLOPT(CURLOPT_TCP_FASTOPEN, CURLOPTTYPE_LONG, 244),
+
+ /* Continue to send data if the server responds early with an
+ * HTTP status code >= 300 */
+ CURLOPT(CURLOPT_KEEP_SENDING_ON_ERROR, CURLOPTTYPE_LONG, 245),
+
+ /* The CApath or CAfile used to validate the proxy certificate
+ this option is used only if PROXY_SSL_VERIFYPEER is true */
+ CURLOPT(CURLOPT_PROXY_CAINFO, CURLOPTTYPE_STRINGPOINT, 246),
+
+ /* The CApath directory used to validate the proxy certificate
+ this option is used only if PROXY_SSL_VERIFYPEER is true */
+ CURLOPT(CURLOPT_PROXY_CAPATH, CURLOPTTYPE_STRINGPOINT, 247),
+
+ /* Set if we should verify the proxy in ssl handshake,
+ set 1 to verify. */
+ CURLOPT(CURLOPT_PROXY_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 248),
+
+ /* Set if we should verify the Common name from the proxy certificate in ssl
+ * handshake, set 1 to check existence, 2 to ensure that it matches
+ * the provided hostname. */
+ CURLOPT(CURLOPT_PROXY_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 249),
+
+ /* What version to specifically try to use for proxy.
+ See CURL_SSLVERSION defines below. */
+ CURLOPT(CURLOPT_PROXY_SSLVERSION, CURLOPTTYPE_VALUES, 250),
+
+ /* Set a username for authenticated TLS for proxy */
+ CURLOPT(CURLOPT_PROXY_TLSAUTH_USERNAME, CURLOPTTYPE_STRINGPOINT, 251),
+
+ /* Set a password for authenticated TLS for proxy */
+ CURLOPT(CURLOPT_PROXY_TLSAUTH_PASSWORD, CURLOPTTYPE_STRINGPOINT, 252),
+
+ /* Set authentication type for authenticated TLS for proxy */
+ CURLOPT(CURLOPT_PROXY_TLSAUTH_TYPE, CURLOPTTYPE_STRINGPOINT, 253),
+
+ /* name of the file keeping your private SSL-certificate for proxy */
+ CURLOPT(CURLOPT_PROXY_SSLCERT, CURLOPTTYPE_STRINGPOINT, 254),
+
+ /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for
+ proxy */
+ CURLOPT(CURLOPT_PROXY_SSLCERTTYPE, CURLOPTTYPE_STRINGPOINT, 255),
+
+ /* name of the file keeping your private SSL-key for proxy */
+ CURLOPT(CURLOPT_PROXY_SSLKEY, CURLOPTTYPE_STRINGPOINT, 256),
+
+ /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for
+ proxy */
+ CURLOPT(CURLOPT_PROXY_SSLKEYTYPE, CURLOPTTYPE_STRINGPOINT, 257),
+
+ /* password for the SSL private key for proxy */
+ CURLOPT(CURLOPT_PROXY_KEYPASSWD, CURLOPTTYPE_STRINGPOINT, 258),
+
+ /* Specify which SSL ciphers to use for proxy */
+ CURLOPT(CURLOPT_PROXY_SSL_CIPHER_LIST, CURLOPTTYPE_STRINGPOINT, 259),
+
+ /* CRL file for proxy */
+ CURLOPT(CURLOPT_PROXY_CRLFILE, CURLOPTTYPE_STRINGPOINT, 260),
+
+ /* Enable/disable specific SSL features with a bitmask for proxy, see
+ CURLSSLOPT_* */
+ CURLOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLOPTTYPE_LONG, 261),
+
+ /* Name of pre proxy to use. */
+ CURLOPT(CURLOPT_PRE_PROXY, CURLOPTTYPE_STRINGPOINT, 262),
+
+ /* The public key in DER form used to validate the proxy public key
+ this option is used only if PROXY_SSL_VERIFYPEER is true */
+ CURLOPT(CURLOPT_PROXY_PINNEDPUBLICKEY, CURLOPTTYPE_STRINGPOINT, 263),
+
+ /* Path to an abstract Unix domain socket */
+ CURLOPT(CURLOPT_ABSTRACT_UNIX_SOCKET, CURLOPTTYPE_STRINGPOINT, 264),
+
+ /* Suppress proxy CONNECT response headers from user callbacks */
+ CURLOPT(CURLOPT_SUPPRESS_CONNECT_HEADERS, CURLOPTTYPE_LONG, 265),
+
+ /* The request target, instead of extracted from the URL */
+ CURLOPT(CURLOPT_REQUEST_TARGET, CURLOPTTYPE_STRINGPOINT, 266),
+
+ /* bitmask of allowed auth methods for connections to SOCKS5 proxies */
+ CURLOPT(CURLOPT_SOCKS5_AUTH, CURLOPTTYPE_LONG, 267),
+
+ /* Enable/disable SSH compression */
+ CURLOPT(CURLOPT_SSH_COMPRESSION, CURLOPTTYPE_LONG, 268),
+
+ /* Post MIME data. */
+ CURLOPT(CURLOPT_MIMEPOST, CURLOPTTYPE_OBJECTPOINT, 269),
+
+ /* Time to use with the CURLOPT_TIMECONDITION. Specified in number of
+ seconds since 1 Jan 1970. */
+ CURLOPT(CURLOPT_TIMEVALUE_LARGE, CURLOPTTYPE_OFF_T, 270),
+
+ /* Head start in milliseconds to give happy eyeballs. */
+ CURLOPT(CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, CURLOPTTYPE_LONG, 271),
+
+ /* Function that will be called before a resolver request is made */
+ CURLOPT(CURLOPT_RESOLVER_START_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 272),
+
+ /* User data to pass to the resolver start callback. */
+ CURLOPT(CURLOPT_RESOLVER_START_DATA, CURLOPTTYPE_CBPOINT, 273),
+
+ /* send HAProxy PROXY protocol header? */
+ CURLOPT(CURLOPT_HAPROXYPROTOCOL, CURLOPTTYPE_LONG, 274),
+
+ /* shuffle addresses before use when DNS returns multiple */
+ CURLOPT(CURLOPT_DNS_SHUFFLE_ADDRESSES, CURLOPTTYPE_LONG, 275),
+
+ /* Specify which TLS 1.3 ciphers suites to use */
+ CURLOPT(CURLOPT_TLS13_CIPHERS, CURLOPTTYPE_STRINGPOINT, 276),
+ CURLOPT(CURLOPT_PROXY_TLS13_CIPHERS, CURLOPTTYPE_STRINGPOINT, 277),
+
+ /* Disallow specifying username/login in URL. */
+ CURLOPT(CURLOPT_DISALLOW_USERNAME_IN_URL, CURLOPTTYPE_LONG, 278),
+
+ /* DNS-over-HTTPS URL */
+ CURLOPT(CURLOPT_DOH_URL, CURLOPTTYPE_STRINGPOINT, 279),
+
+ /* Preferred buffer size to use for uploads */
+ CURLOPT(CURLOPT_UPLOAD_BUFFERSIZE, CURLOPTTYPE_LONG, 280),
+
+ /* Time in ms between connection upkeep calls for long-lived connections. */
+ CURLOPT(CURLOPT_UPKEEP_INTERVAL_MS, CURLOPTTYPE_LONG, 281),
+
+ /* Specify URL using CURL URL API. */
+ CURLOPT(CURLOPT_CURLU, CURLOPTTYPE_OBJECTPOINT, 282),
+
+ /* add trailing data just after no more data is available */
+ CURLOPT(CURLOPT_TRAILERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 283),
+
+ /* pointer to be passed to HTTP_TRAILER_FUNCTION */
+ 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),
+
+ /* alt-svc control bitmask */
+ CURLOPT(CURLOPT_ALTSVC_CTRL, CURLOPTTYPE_LONG, 286),
+
+ /* alt-svc cache file name to possibly read from/write to */
+ CURLOPT(CURLOPT_ALTSVC, CURLOPTTYPE_STRINGPOINT, 287),
+
+ /* maximum age (idle time) of a connection to consider it for reuse
+ * (in seconds) */
+ CURLOPT(CURLOPT_MAXAGE_CONN, CURLOPTTYPE_LONG, 288),
+
+ /* SASL authorization identity */
+ CURLOPT(CURLOPT_SASL_AUTHZID, CURLOPTTYPE_STRINGPOINT, 289),
+
+ /* allow RCPT TO command to fail for some recipients */
+ CURLOPT(CURLOPT_MAIL_RCPT_ALLOWFAILS, CURLOPTTYPE_LONG, 290),
+
+ /* the private SSL-certificate as a "blob" */
+ CURLOPT(CURLOPT_SSLCERT_BLOB, CURLOPTTYPE_BLOB, 291),
+ CURLOPT(CURLOPT_SSLKEY_BLOB, CURLOPTTYPE_BLOB, 292),
+ CURLOPT(CURLOPT_PROXY_SSLCERT_BLOB, CURLOPTTYPE_BLOB, 293),
+ CURLOPT(CURLOPT_PROXY_SSLKEY_BLOB, CURLOPTTYPE_BLOB, 294),
+ CURLOPT(CURLOPT_ISSUERCERT_BLOB, CURLOPTTYPE_BLOB, 295),
+
+ /* Issuer certificate for proxy */
+ CURLOPT(CURLOPT_PROXY_ISSUERCERT, CURLOPTTYPE_STRINGPOINT, 296),
+ CURLOPT(CURLOPT_PROXY_ISSUERCERT_BLOB, CURLOPTTYPE_BLOB, 297),
+
+ /* the EC curves requested by the TLS client (RFC 8422, 5.1);
+ * OpenSSL support via 'set_groups'/'set_curves':
+ * https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html
+ */
+ CURLOPT(CURLOPT_SSL_EC_CURVES, CURLOPTTYPE_STRINGPOINT, 298),
+
+ /* HSTS bitmask */
+ CURLOPT(CURLOPT_HSTS_CTRL, CURLOPTTYPE_LONG, 299),
+ /* HSTS file name */
+ CURLOPT(CURLOPT_HSTS, CURLOPTTYPE_STRINGPOINT, 300),
+
+ /* HSTS read callback */
+ CURLOPT(CURLOPT_HSTSREADFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 301),
+ CURLOPT(CURLOPT_HSTSREADDATA, CURLOPTTYPE_CBPOINT, 302),
+
+ /* HSTS write callback */
+ CURLOPT(CURLOPT_HSTSWRITEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 303),
+ CURLOPT(CURLOPT_HSTSWRITEDATA, CURLOPTTYPE_CBPOINT, 304),
+
+ /* Parameters for V4 signature */
+ CURLOPT(CURLOPT_AWS_SIGV4, CURLOPTTYPE_STRINGPOINT, 305),
+
+ /* Same as CURLOPT_SSL_VERIFYPEER but for DoH (DNS-over-HTTPS) servers. */
+ CURLOPT(CURLOPT_DOH_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 306),
+
+ /* Same as CURLOPT_SSL_VERIFYHOST but for DoH (DNS-over-HTTPS) servers. */
+ CURLOPT(CURLOPT_DOH_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 307),
+
+ /* Same as CURLOPT_SSL_VERIFYSTATUS but for DoH (DNS-over-HTTPS) servers. */
+ CURLOPT(CURLOPT_DOH_SSL_VERIFYSTATUS, CURLOPTTYPE_LONG, 308),
+
+ /* The CA certificates as "blob" used to validate the peer certificate
+ this option is used only if SSL_VERIFYPEER is true */
+ CURLOPT(CURLOPT_CAINFO_BLOB, CURLOPTTYPE_BLOB, 309),
+
+ /* The CA certificates as "blob" used to validate the proxy certificate
+ this option is used only if PROXY_SSL_VERIFYPEER is true */
+ CURLOPT(CURLOPT_PROXY_CAINFO_BLOB, CURLOPTTYPE_BLOB, 310),
+
+ /* used by scp/sftp to verify the host's public key */
+ CURLOPT(CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256, CURLOPTTYPE_STRINGPOINT, 311),
+
+ /* Function that will be called immediately before the initial request
+ is made on a connection (after any protocol negotiation step). */
+ CURLOPT(CURLOPT_PREREQFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 312),
+
+ /* Data passed to the CURLOPT_PREREQFUNCTION callback */
+ CURLOPT(CURLOPT_PREREQDATA, CURLOPTTYPE_CBPOINT, 313),
+
+ /* maximum age (since creation) of a connection to consider it for reuse
+ * (in seconds) */
+ CURLOPT(CURLOPT_MAXLIFETIME_CONN, CURLOPTTYPE_LONG, 314),
+
+ /* Set MIME option flags. */
+ CURLOPT(CURLOPT_MIME_OPTIONS, CURLOPTTYPE_LONG, 315),
+
+ /* set the SSH host key callback, must point to a curl_sshkeycallback
+ function */
+ CURLOPT(CURLOPT_SSH_HOSTKEYFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 316),
+
+ /* set the SSH host key callback custom pointer */
+ CURLOPT(CURLOPT_SSH_HOSTKEYDATA, CURLOPTTYPE_CBPOINT, 317),
+
+ /* specify which protocols that are allowed to be used for the transfer,
+ which thus helps the app which takes URLs from users or other external
+ inputs and want to restrict what protocol(s) to deal with. Defaults to
+ all built-in protocols. */
+ CURLOPT(CURLOPT_PROTOCOLS_STR, CURLOPTTYPE_STRINGPOINT, 318),
+
+ /* specify which protocols that libcurl is allowed to follow directs to */
+ CURLOPT(CURLOPT_REDIR_PROTOCOLS_STR, CURLOPTTYPE_STRINGPOINT, 319),
+
+ /* websockets options */
+ CURLOPT(CURLOPT_WS_OPTIONS, CURLOPTTYPE_LONG, 320),
+
+ /* CA cache timeout */
+ CURLOPT(CURLOPT_CA_CACHE_TIMEOUT, CURLOPTTYPE_LONG, 321),
+
+ /* Can leak things, gonna exit() soon */
+ CURLOPT(CURLOPT_QUICK_EXIT, CURLOPTTYPE_LONG, 322),
+
+ /* set a specific client IP for HAProxy PROXY protocol header? */
+ CURLOPT(CURLOPT_HAPROXY_CLIENT_IP, CURLOPTTYPE_STRINGPOINT, 323),
+
+ CURLOPT_LASTENTRY /* the last unused */
+} CURLoption;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+ the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+/* These are scheduled to disappear by 2011 */
+
+/* This was added in version 7.19.1 */
+#define CURLOPT_POST301 CURLOPT_POSTREDIR
+
+/* These are scheduled to disappear by 2009 */
+
+/* The following were added in 7.17.0 */
+#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD
+#define CURLOPT_FTPAPPEND CURLOPT_APPEND
+#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY
+#define CURLOPT_FTP_SSL CURLOPT_USE_SSL
+
+/* The following were added earlier */
+
+#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD
+#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL
+
+/* */
+#define CURLOPT_FTP_RESPONSE_TIMEOUT CURLOPT_SERVER_RESPONSE_TIMEOUT
+
+/* Added in 8.2.0 */
+#define CURLOPT_MAIL_RCPT_ALLLOWFAILS CURLOPT_MAIL_RCPT_ALLOWFAILS
+
+#else
+/* This is set if CURL_NO_OLDIES is defined at compile-time */
+#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */
+#endif
+
+
+ /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host
+ name resolves addresses using more than one IP protocol version, this
+ option might be handy to force libcurl to use a specific IP version. */
+#define CURL_IPRESOLVE_WHATEVER 0 /* default, uses addresses to all IP
+ versions that your system allows */
+#define CURL_IPRESOLVE_V4 1 /* uses only IPv4 addresses/connections */
+#define CURL_IPRESOLVE_V6 2 /* uses only IPv6 addresses/connections */
+
+ /* Convenient "aliases" */
+#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER
+
+ /* These enums are for use with the CURLOPT_HTTP_VERSION option. */
+enum {
+ CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd
+ like the library to choose the best possible
+ for us! */
+ CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */
+ CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */
+ CURL_HTTP_VERSION_2_0, /* please use HTTP 2 in the request */
+ CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */
+ CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE, /* please use HTTP 2 without HTTP/1.1
+ Upgrade */
+ CURL_HTTP_VERSION_3 = 30, /* Use HTTP/3, fallback to HTTP/2 or HTTP/1 if
+ needed. For HTTPS only. For HTTP, this option
+ makes libcurl return error. */
+ CURL_HTTP_VERSION_3ONLY = 31, /* Use HTTP/3 without fallback. For HTTPS
+ only. For HTTP, this makes libcurl
+ return error. */
+
+ CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
+};
+
+/* Convenience definition simple because the name of the version is HTTP/2 and
+ not 2.0. The 2_0 version of the enum name was set while the version was
+ still planned to be 2.0 and we stick to it for compatibility. */
+#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0
+
+/*
+ * Public API enums for RTSP requests
+ */
+enum {
+ CURL_RTSPREQ_NONE, /* first in list */
+ CURL_RTSPREQ_OPTIONS,
+ CURL_RTSPREQ_DESCRIBE,
+ CURL_RTSPREQ_ANNOUNCE,
+ CURL_RTSPREQ_SETUP,
+ CURL_RTSPREQ_PLAY,
+ CURL_RTSPREQ_PAUSE,
+ CURL_RTSPREQ_TEARDOWN,
+ CURL_RTSPREQ_GET_PARAMETER,
+ CURL_RTSPREQ_SET_PARAMETER,
+ CURL_RTSPREQ_RECORD,
+ CURL_RTSPREQ_RECEIVE,
+ CURL_RTSPREQ_LAST /* last in list */
+};
+
+ /* These enums are for use with the CURLOPT_NETRC option. */
+enum CURL_NETRC_OPTION {
+ CURL_NETRC_IGNORED, /* The .netrc will never be read.
+ * This is the default. */
+ CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred
+ * to one in the .netrc. */
+ CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored.
+ * Unless one is set programmatically, the .netrc
+ * will be queried. */
+ CURL_NETRC_LAST
+};
+
+enum {
+ CURL_SSLVERSION_DEFAULT,
+ CURL_SSLVERSION_TLSv1, /* TLS 1.x */
+ CURL_SSLVERSION_SSLv2,
+ CURL_SSLVERSION_SSLv3,
+ CURL_SSLVERSION_TLSv1_0,
+ CURL_SSLVERSION_TLSv1_1,
+ CURL_SSLVERSION_TLSv1_2,
+ CURL_SSLVERSION_TLSv1_3,
+
+ CURL_SSLVERSION_LAST /* never use, keep last */
+};
+
+enum {
+ CURL_SSLVERSION_MAX_NONE = 0,
+ CURL_SSLVERSION_MAX_DEFAULT = (CURL_SSLVERSION_TLSv1 << 16),
+ CURL_SSLVERSION_MAX_TLSv1_0 = (CURL_SSLVERSION_TLSv1_0 << 16),
+ CURL_SSLVERSION_MAX_TLSv1_1 = (CURL_SSLVERSION_TLSv1_1 << 16),
+ CURL_SSLVERSION_MAX_TLSv1_2 = (CURL_SSLVERSION_TLSv1_2 << 16),
+ CURL_SSLVERSION_MAX_TLSv1_3 = (CURL_SSLVERSION_TLSv1_3 << 16),
+
+ /* never use, keep last */
+ CURL_SSLVERSION_MAX_LAST = (CURL_SSLVERSION_LAST << 16)
+};
+
+enum CURL_TLSAUTH {
+ CURL_TLSAUTH_NONE,
+ CURL_TLSAUTH_SRP,
+ CURL_TLSAUTH_LAST /* never use, keep last */
+};
+
+/* symbols to use with CURLOPT_POSTREDIR.
+ CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303
+ can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302
+ | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */
+
+#define CURL_REDIR_GET_ALL 0
+#define CURL_REDIR_POST_301 1
+#define CURL_REDIR_POST_302 2
+#define CURL_REDIR_POST_303 4
+#define CURL_REDIR_POST_ALL \
+ (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303)
+
+typedef enum {
+ CURL_TIMECOND_NONE,
+
+ CURL_TIMECOND_IFMODSINCE,
+ CURL_TIMECOND_IFUNMODSINCE,
+ CURL_TIMECOND_LASTMOD,
+
+ CURL_TIMECOND_LAST
+} curl_TimeCond;
+
+/* Special size_t value signaling a null-terminated string. */
+#define CURL_ZERO_TERMINATED ((size_t) -1)
+
+/* curl_strequal() and curl_strnequal() are subject for removal in a future
+ release */
+CURL_EXTERN int curl_strequal(const char *s1, const char *s2);
+CURL_EXTERN int curl_strnequal(const char *s1, const char *s2, size_t n);
+
+/* Mime/form handling support. */
+typedef struct curl_mime curl_mime; /* Mime context. */
+typedef struct curl_mimepart curl_mimepart; /* Mime part context. */
+
+/* CURLMIMEOPT_ defines are for the CURLOPT_MIME_OPTIONS option. */
+#define CURLMIMEOPT_FORMESCAPE (1<<0) /* Use backslash-escaping for forms. */
+
+/*
+ * NAME curl_mime_init()
+ *
+ * DESCRIPTION
+ *
+ * Create a mime context and return its handle. The easy parameter is the
+ * target handle.
+ */
+CURL_EXTERN curl_mime *curl_mime_init(CURL *easy);
+
+/*
+ * NAME curl_mime_free()
+ *
+ * DESCRIPTION
+ *
+ * release a mime handle and its substructures.
+ */
+CURL_EXTERN void curl_mime_free(curl_mime *mime);
+
+/*
+ * NAME curl_mime_addpart()
+ *
+ * DESCRIPTION
+ *
+ * Append a new empty part to the given mime context and return a handle to
+ * the created part.
+ */
+CURL_EXTERN curl_mimepart *curl_mime_addpart(curl_mime *mime);
+
+/*
+ * NAME curl_mime_name()
+ *
+ * DESCRIPTION
+ *
+ * Set mime/form part name.
+ */
+CURL_EXTERN CURLcode curl_mime_name(curl_mimepart *part, const char *name);
+
+/*
+ * NAME curl_mime_filename()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part remote file name.
+ */
+CURL_EXTERN CURLcode curl_mime_filename(curl_mimepart *part,
+ const char *filename);
+
+/*
+ * NAME curl_mime_type()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part type.
+ */
+CURL_EXTERN CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype);
+
+/*
+ * NAME curl_mime_encoder()
+ *
+ * DESCRIPTION
+ *
+ * Set mime data transfer encoder.
+ */
+CURL_EXTERN CURLcode curl_mime_encoder(curl_mimepart *part,
+ const char *encoding);
+
+/*
+ * NAME curl_mime_data()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part data source from memory data,
+ */
+CURL_EXTERN CURLcode curl_mime_data(curl_mimepart *part,
+ const char *data, size_t datasize);
+
+/*
+ * NAME curl_mime_filedata()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part data source from named file.
+ */
+CURL_EXTERN CURLcode curl_mime_filedata(curl_mimepart *part,
+ const char *filename);
+
+/*
+ * NAME curl_mime_data_cb()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part data source from callback function.
+ */
+CURL_EXTERN CURLcode curl_mime_data_cb(curl_mimepart *part,
+ curl_off_t datasize,
+ curl_read_callback readfunc,
+ curl_seek_callback seekfunc,
+ curl_free_callback freefunc,
+ void *arg);
+
+/*
+ * NAME curl_mime_subparts()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part data source from subparts.
+ */
+CURL_EXTERN CURLcode curl_mime_subparts(curl_mimepart *part,
+ curl_mime *subparts);
+/*
+ * NAME curl_mime_headers()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part headers.
+ */
+CURL_EXTERN CURLcode curl_mime_headers(curl_mimepart *part,
+ struct curl_slist *headers,
+ int take_ownership);
+
+typedef enum {
+ /********* the first one is unused ************/
+ CURLFORM_NOTHING CURL_DEPRECATED(7.56.0, ""),
+ CURLFORM_COPYNAME CURL_DEPRECATED(7.56.0, "Use curl_mime_name()"),
+ CURLFORM_PTRNAME CURL_DEPRECATED(7.56.0, "Use curl_mime_name()"),
+ CURLFORM_NAMELENGTH CURL_DEPRECATED(7.56.0, ""),
+ CURLFORM_COPYCONTENTS CURL_DEPRECATED(7.56.0, "Use curl_mime_data()"),
+ CURLFORM_PTRCONTENTS CURL_DEPRECATED(7.56.0, "Use curl_mime_data()"),
+ CURLFORM_CONTENTSLENGTH CURL_DEPRECATED(7.56.0, "Use curl_mime_data()"),
+ CURLFORM_FILECONTENT CURL_DEPRECATED(7.56.0, "Use curl_mime_data_cb()"),
+ CURLFORM_ARRAY CURL_DEPRECATED(7.56.0, ""),
+ CURLFORM_OBSOLETE,
+ CURLFORM_FILE CURL_DEPRECATED(7.56.0, "Use curl_mime_filedata()"),
+
+ CURLFORM_BUFFER CURL_DEPRECATED(7.56.0, "Use curl_mime_filename()"),
+ CURLFORM_BUFFERPTR CURL_DEPRECATED(7.56.0, "Use curl_mime_data()"),
+ CURLFORM_BUFFERLENGTH CURL_DEPRECATED(7.56.0, "Use curl_mime_data()"),
+
+ CURLFORM_CONTENTTYPE CURL_DEPRECATED(7.56.0, "Use curl_mime_type()"),
+ CURLFORM_CONTENTHEADER CURL_DEPRECATED(7.56.0, "Use curl_mime_headers()"),
+ CURLFORM_FILENAME CURL_DEPRECATED(7.56.0, "Use curl_mime_filename()"),
+ CURLFORM_END,
+ CURLFORM_OBSOLETE2,
+
+ CURLFORM_STREAM CURL_DEPRECATED(7.56.0, "Use curl_mime_data_cb()"),
+ CURLFORM_CONTENTLEN /* added in 7.46.0, provide a curl_off_t length */
+ CURL_DEPRECATED(7.56.0, "Use curl_mime_data()"),
+
+ CURLFORM_LASTENTRY /* the last unused */
+} CURLformoption;
+
+/* structure to be used as parameter for CURLFORM_ARRAY */
+struct curl_forms {
+ CURLformoption option;
+ const char *value;
+};
+
+/* use this for multipart formpost building */
+/* Returns code for curl_formadd()
+ *
+ * Returns:
+ * CURL_FORMADD_OK on success
+ * CURL_FORMADD_MEMORY if the FormInfo allocation fails
+ * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form
+ * CURL_FORMADD_NULL if a null pointer was given for a char
+ * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed
+ * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
+ * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error)
+ * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated
+ * CURL_FORMADD_MEMORY if some allocation for string copying failed.
+ * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array
+ *
+ ***************************************************************************/
+typedef enum {
+ CURL_FORMADD_OK CURL_DEPRECATED(7.56.0, ""), /* 1st, no error */
+
+ CURL_FORMADD_MEMORY CURL_DEPRECATED(7.56.0, ""),
+ CURL_FORMADD_OPTION_TWICE CURL_DEPRECATED(7.56.0, ""),
+ CURL_FORMADD_NULL CURL_DEPRECATED(7.56.0, ""),
+ CURL_FORMADD_UNKNOWN_OPTION CURL_DEPRECATED(7.56.0, ""),
+ CURL_FORMADD_INCOMPLETE CURL_DEPRECATED(7.56.0, ""),
+ CURL_FORMADD_ILLEGAL_ARRAY CURL_DEPRECATED(7.56.0, ""),
+ /* libcurl was built with form api disabled */
+ CURL_FORMADD_DISABLED CURL_DEPRECATED(7.56.0, ""),
+
+ CURL_FORMADD_LAST /* last */
+} CURLFORMcode;
+
+/*
+ * NAME curl_formadd()
+ *
+ * DESCRIPTION
+ *
+ * Pretty advanced function for building multi-part formposts. Each invoke
+ * adds one part that together construct a full post. Then use
+ * CURLOPT_HTTPPOST to send it off to libcurl.
+ */
+CURL_EXTERN CURLFORMcode CURL_DEPRECATED(7.56.0, "Use curl_mime_init()")
+curl_formadd(struct curl_httppost **httppost,
+ struct curl_httppost **last_post,
+ ...);
+
+/*
+ * callback function for curl_formget()
+ * The void *arg pointer will be the one passed as second argument to
+ * curl_formget().
+ * The character buffer passed to it must not be freed.
+ * Should return the buffer length passed to it as the argument "len" on
+ * success.
+ */
+typedef size_t (*curl_formget_callback)(void *arg, const char *buf,
+ size_t len);
+
+/*
+ * NAME curl_formget()
+ *
+ * DESCRIPTION
+ *
+ * Serialize a curl_httppost struct built with curl_formadd().
+ * Accepts a void pointer as second argument which will be passed to
+ * the curl_formget_callback function.
+ * Returns 0 on success.
+ */
+CURL_EXTERN int CURL_DEPRECATED(7.56.0, "")
+curl_formget(struct curl_httppost *form, void *arg,
+ curl_formget_callback append);
+/*
+ * NAME curl_formfree()
+ *
+ * DESCRIPTION
+ *
+ * Free a multipart formpost previously built with curl_formadd().
+ */
+CURL_EXTERN void CURL_DEPRECATED(7.56.0, "Use curl_mime_free()")
+curl_formfree(struct curl_httppost *form);
+
+/*
+ * NAME curl_getenv()
+ *
+ * DESCRIPTION
+ *
+ * Returns a malloc()'ed string that MUST be curl_free()ed after usage is
+ * complete. DEPRECATED - see lib/README.curlx
+ */
+CURL_EXTERN char *curl_getenv(const char *variable);
+
+/*
+ * NAME curl_version()
+ *
+ * DESCRIPTION
+ *
+ * Returns a static ascii string of the libcurl version.
+ */
+CURL_EXTERN char *curl_version(void);
+
+/*
+ * NAME curl_easy_escape()
+ *
+ * DESCRIPTION
+ *
+ * Escapes URL strings (converts all letters consider illegal in URLs to their
+ * %XX versions). This function returns a new allocated string or NULL if an
+ * error occurred.
+ */
+CURL_EXTERN char *curl_easy_escape(CURL *handle,
+ const char *string,
+ int length);
+
+/* the previous version: */
+CURL_EXTERN char *curl_escape(const char *string,
+ int length);
+
+
+/*
+ * NAME curl_easy_unescape()
+ *
+ * DESCRIPTION
+ *
+ * Unescapes URL encoding in strings (converts all %XX codes to their 8bit
+ * versions). This function returns a new allocated string or NULL if an error
+ * occurred.
+ * Conversion Note: On non-ASCII platforms the ASCII %XX codes are
+ * converted into the host encoding.
+ */
+CURL_EXTERN char *curl_easy_unescape(CURL *handle,
+ const char *string,
+ int length,
+ int *outlength);
+
+/* the previous version */
+CURL_EXTERN char *curl_unescape(const char *string,
+ int length);
+
+/*
+ * NAME curl_free()
+ *
+ * DESCRIPTION
+ *
+ * Provided for de-allocation in the same translation unit that did the
+ * allocation. Added in libcurl 7.10
+ */
+CURL_EXTERN void curl_free(void *p);
+
+/*
+ * NAME curl_global_init()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_init() should be invoked exactly once for each application that
+ * uses libcurl and before any call of other libcurl functions.
+
+ * This function is thread-safe if CURL_VERSION_THREADSAFE is set in the
+ * curl_version_info_data.features flag (fetch by curl_version_info()).
+
+ */
+CURL_EXTERN CURLcode curl_global_init(long flags);
+
+/*
+ * NAME curl_global_init_mem()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_init() or curl_global_init_mem() should be invoked exactly once
+ * for each application that uses libcurl. This function can be used to
+ * initialize libcurl and set user defined memory management callback
+ * functions. Users can implement memory management routines to check for
+ * memory leaks, check for mis-use of the curl library etc. User registered
+ * callback routines will be invoked by this library instead of the system
+ * memory management routines like malloc, free etc.
+ */
+CURL_EXTERN CURLcode curl_global_init_mem(long flags,
+ curl_malloc_callback m,
+ curl_free_callback f,
+ curl_realloc_callback r,
+ curl_strdup_callback s,
+ curl_calloc_callback c);
+
+/*
+ * NAME curl_global_cleanup()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_cleanup() should be invoked exactly once for each application
+ * that uses libcurl
+ */
+CURL_EXTERN void curl_global_cleanup(void);
+
+/*
+ * NAME curl_global_trace()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_trace() can be invoked at application start to
+ * configure which components in curl should participate in tracing.
+
+ * This function is thread-safe if CURL_VERSION_THREADSAFE is set in the
+ * curl_version_info_data.features flag (fetch by curl_version_info()).
+
+ */
+CURL_EXTERN CURLcode curl_global_trace(const char *config);
+
+/* linked-list structure for the CURLOPT_QUOTE option (and other) */
+struct curl_slist {
+ char *data;
+ struct curl_slist *next;
+};
+
+/*
+ * NAME curl_global_sslset()
+ *
+ * DESCRIPTION
+ *
+ * When built with multiple SSL backends, curl_global_sslset() allows to
+ * choose one. This function can only be called once, and it must be called
+ * *before* curl_global_init().
+ *
+ * The backend can be identified by the id (e.g. CURLSSLBACKEND_OPENSSL). The
+ * backend can also be specified via the name parameter (passing -1 as id).
+ * If both id and name are specified, the name will be ignored. If neither id
+ * nor name are specified, the function will fail with
+ * CURLSSLSET_UNKNOWN_BACKEND and set the "avail" pointer to the
+ * NULL-terminated list of available backends.
+ *
+ * Upon success, the function returns CURLSSLSET_OK.
+ *
+ * If the specified SSL backend is not available, the function returns
+ * CURLSSLSET_UNKNOWN_BACKEND and sets the "avail" pointer to a NULL-terminated
+ * list of available SSL backends.
+ *
+ * The SSL backend can be set only once. If it has already been set, a
+ * subsequent attempt to change it will result in a CURLSSLSET_TOO_LATE.
+ */
+
+struct curl_ssl_backend {
+ curl_sslbackend id;
+ const char *name;
+};
+typedef struct curl_ssl_backend curl_ssl_backend;
+
+typedef enum {
+ CURLSSLSET_OK = 0,
+ CURLSSLSET_UNKNOWN_BACKEND,
+ CURLSSLSET_TOO_LATE,
+ CURLSSLSET_NO_BACKENDS /* libcurl was built without any SSL support */
+} CURLsslset;
+
+CURL_EXTERN CURLsslset curl_global_sslset(curl_sslbackend id, const char *name,
+ const curl_ssl_backend ***avail);
+
+/*
+ * NAME curl_slist_append()
+ *
+ * DESCRIPTION
+ *
+ * Appends a string to a linked list. If no list exists, it will be created
+ * first. Returns the new list, after appending.
+ */
+CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *list,
+ const char *data);
+
+/*
+ * NAME curl_slist_free_all()
+ *
+ * DESCRIPTION
+ *
+ * free a previously built curl_slist.
+ */
+CURL_EXTERN void curl_slist_free_all(struct curl_slist *list);
+
+/*
+ * NAME curl_getdate()
+ *
+ * DESCRIPTION
+ *
+ * Returns the time, in seconds since 1 Jan 1970 of the time string given in
+ * the first argument. The time argument in the second parameter is unused
+ * and should be set to NULL.
+ */
+CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused);
+
+/* info about the certificate chain, for SSL backends that support it. Asked
+ for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */
+struct curl_certinfo {
+ int num_of_certs; /* number of certificates with information */
+ struct curl_slist **certinfo; /* for each index in this array, there's a
+ linked list with textual information for a
+ certificate in the format "name:content".
+ eg "Subject:foo", "Issuer:bar", etc. */
+};
+
+/* Information about the SSL library used and the respective internal SSL
+ handle, which can be used to obtain further information regarding the
+ connection. Asked for with CURLINFO_TLS_SSL_PTR or CURLINFO_TLS_SESSION. */
+struct curl_tlssessioninfo {
+ curl_sslbackend backend;
+ void *internals;
+};
+
+#define CURLINFO_STRING 0x100000
+#define CURLINFO_LONG 0x200000
+#define CURLINFO_DOUBLE 0x300000
+#define CURLINFO_SLIST 0x400000
+#define CURLINFO_PTR 0x400000 /* same as SLIST */
+#define CURLINFO_SOCKET 0x500000
+#define CURLINFO_OFF_T 0x600000
+#define CURLINFO_MASK 0x0fffff
+#define CURLINFO_TYPEMASK 0xf00000
+
+typedef enum {
+ CURLINFO_NONE, /* first, never use this */
+ CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1,
+ CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2,
+ CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3,
+ CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4,
+ CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5,
+ CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6,
+ CURLINFO_SIZE_UPLOAD CURL_DEPRECATED(7.55.0, "Use CURLINFO_SIZE_UPLOAD_T")
+ = CURLINFO_DOUBLE + 7,
+ CURLINFO_SIZE_UPLOAD_T = CURLINFO_OFF_T + 7,
+ CURLINFO_SIZE_DOWNLOAD
+ CURL_DEPRECATED(7.55.0, "Use CURLINFO_SIZE_DOWNLOAD_T")
+ = CURLINFO_DOUBLE + 8,
+ CURLINFO_SIZE_DOWNLOAD_T = CURLINFO_OFF_T + 8,
+ CURLINFO_SPEED_DOWNLOAD
+ CURL_DEPRECATED(7.55.0, "Use CURLINFO_SPEED_DOWNLOAD_T")
+ = CURLINFO_DOUBLE + 9,
+ CURLINFO_SPEED_DOWNLOAD_T = CURLINFO_OFF_T + 9,
+ CURLINFO_SPEED_UPLOAD
+ CURL_DEPRECATED(7.55.0, "Use CURLINFO_SPEED_UPLOAD_T")
+ = CURLINFO_DOUBLE + 10,
+ CURLINFO_SPEED_UPLOAD_T = CURLINFO_OFF_T + 10,
+ CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11,
+ CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12,
+ CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13,
+ CURLINFO_FILETIME = CURLINFO_LONG + 14,
+ CURLINFO_FILETIME_T = CURLINFO_OFF_T + 14,
+ CURLINFO_CONTENT_LENGTH_DOWNLOAD
+ CURL_DEPRECATED(7.55.0,
+ "Use CURLINFO_CONTENT_LENGTH_DOWNLOAD_T")
+ = CURLINFO_DOUBLE + 15,
+ CURLINFO_CONTENT_LENGTH_DOWNLOAD_T = CURLINFO_OFF_T + 15,
+ CURLINFO_CONTENT_LENGTH_UPLOAD
+ CURL_DEPRECATED(7.55.0,
+ "Use CURLINFO_CONTENT_LENGTH_UPLOAD_T")
+ = CURLINFO_DOUBLE + 16,
+ CURLINFO_CONTENT_LENGTH_UPLOAD_T = CURLINFO_OFF_T + 16,
+ CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17,
+ CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18,
+ CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19,
+ CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20,
+ CURLINFO_PRIVATE = CURLINFO_STRING + 21,
+ CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22,
+ CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23,
+ CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24,
+ CURLINFO_OS_ERRNO = CURLINFO_LONG + 25,
+ CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26,
+ CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27,
+ CURLINFO_COOKIELIST = CURLINFO_SLIST + 28,
+ CURLINFO_LASTSOCKET CURL_DEPRECATED(7.45.0, "Use CURLINFO_ACTIVESOCKET")
+ = CURLINFO_LONG + 29,
+ CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30,
+ CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31,
+ CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32,
+ CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33,
+ CURLINFO_CERTINFO = CURLINFO_PTR + 34,
+ CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35,
+ CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36,
+ CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37,
+ CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38,
+ CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39,
+ CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40,
+ CURLINFO_LOCAL_IP = CURLINFO_STRING + 41,
+ CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42,
+ CURLINFO_TLS_SESSION CURL_DEPRECATED(7.48.0, "Use CURLINFO_TLS_SSL_PTR")
+ = CURLINFO_PTR + 43,
+ CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44,
+ CURLINFO_TLS_SSL_PTR = CURLINFO_PTR + 45,
+ CURLINFO_HTTP_VERSION = CURLINFO_LONG + 46,
+ CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47,
+ CURLINFO_PROTOCOL CURL_DEPRECATED(7.85.0, "Use CURLINFO_SCHEME")
+ = CURLINFO_LONG + 48,
+ CURLINFO_SCHEME = CURLINFO_STRING + 49,
+ CURLINFO_TOTAL_TIME_T = CURLINFO_OFF_T + 50,
+ CURLINFO_NAMELOOKUP_TIME_T = CURLINFO_OFF_T + 51,
+ CURLINFO_CONNECT_TIME_T = CURLINFO_OFF_T + 52,
+ CURLINFO_PRETRANSFER_TIME_T = CURLINFO_OFF_T + 53,
+ CURLINFO_STARTTRANSFER_TIME_T = CURLINFO_OFF_T + 54,
+ CURLINFO_REDIRECT_TIME_T = CURLINFO_OFF_T + 55,
+ CURLINFO_APPCONNECT_TIME_T = CURLINFO_OFF_T + 56,
+ CURLINFO_RETRY_AFTER = CURLINFO_OFF_T + 57,
+ CURLINFO_EFFECTIVE_METHOD = CURLINFO_STRING + 58,
+ CURLINFO_PROXY_ERROR = CURLINFO_LONG + 59,
+ CURLINFO_REFERER = CURLINFO_STRING + 60,
+ CURLINFO_CAINFO = CURLINFO_STRING + 61,
+ CURLINFO_CAPATH = CURLINFO_STRING + 62,
+ CURLINFO_XFER_ID = CURLINFO_OFF_T + 63,
+ CURLINFO_CONN_ID = CURLINFO_OFF_T + 64,
+ CURLINFO_LASTONE = 64
+} CURLINFO;
+
+/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
+ CURLINFO_HTTP_CODE */
+#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE
+
+typedef enum {
+ CURLCLOSEPOLICY_NONE, /* first, never use this */
+
+ CURLCLOSEPOLICY_OLDEST,
+ CURLCLOSEPOLICY_LEAST_RECENTLY_USED,
+ CURLCLOSEPOLICY_LEAST_TRAFFIC,
+ CURLCLOSEPOLICY_SLOWEST,
+ CURLCLOSEPOLICY_CALLBACK,
+
+ CURLCLOSEPOLICY_LAST /* last, never use this */
+} curl_closepolicy;
+
+#define CURL_GLOBAL_SSL (1<<0) /* no purpose since 7.57.0 */
+#define CURL_GLOBAL_WIN32 (1<<1)
+#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32)
+#define CURL_GLOBAL_NOTHING 0
+#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL
+#define CURL_GLOBAL_ACK_EINTR (1<<2)
+
+
+/*****************************************************************************
+ * Setup defines, protos etc for the sharing stuff.
+ */
+
+/* Different data locks for a single share */
+typedef enum {
+ CURL_LOCK_DATA_NONE = 0,
+ /* CURL_LOCK_DATA_SHARE is used internally to say that
+ * the locking is just made to change the internal state of the share
+ * itself.
+ */
+ CURL_LOCK_DATA_SHARE,
+ CURL_LOCK_DATA_COOKIE,
+ CURL_LOCK_DATA_DNS,
+ CURL_LOCK_DATA_SSL_SESSION,
+ CURL_LOCK_DATA_CONNECT,
+ CURL_LOCK_DATA_PSL,
+ CURL_LOCK_DATA_HSTS,
+ CURL_LOCK_DATA_LAST
+} curl_lock_data;
+
+/* Different lock access types */
+typedef enum {
+ CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */
+ CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */
+ CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */
+ CURL_LOCK_ACCESS_LAST /* never use */
+} curl_lock_access;
+
+typedef void (*curl_lock_function)(CURL *handle,
+ curl_lock_data data,
+ curl_lock_access locktype,
+ void *userptr);
+typedef void (*curl_unlock_function)(CURL *handle,
+ curl_lock_data data,
+ void *userptr);
+
+
+typedef enum {
+ CURLSHE_OK, /* all is fine */
+ CURLSHE_BAD_OPTION, /* 1 */
+ CURLSHE_IN_USE, /* 2 */
+ CURLSHE_INVALID, /* 3 */
+ CURLSHE_NOMEM, /* 4 out of memory */
+ CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */
+ CURLSHE_LAST /* never use */
+} CURLSHcode;
+
+typedef enum {
+ CURLSHOPT_NONE, /* don't use */
+ CURLSHOPT_SHARE, /* specify a data type to share */
+ CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */
+ CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */
+ CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */
+ CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock
+ callback functions */
+ CURLSHOPT_LAST /* never use */
+} CURLSHoption;
+
+CURL_EXTERN CURLSH *curl_share_init(void);
+CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *share, CURLSHoption option,
+ ...);
+CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *share);
+
+/****************************************************************************
+ * Structures for querying information about the curl library at runtime.
+ */
+
+typedef enum {
+ CURLVERSION_FIRST,
+ CURLVERSION_SECOND,
+ CURLVERSION_THIRD,
+ CURLVERSION_FOURTH,
+ CURLVERSION_FIFTH,
+ CURLVERSION_SIXTH,
+ CURLVERSION_SEVENTH,
+ CURLVERSION_EIGHTH,
+ CURLVERSION_NINTH,
+ CURLVERSION_TENTH,
+ CURLVERSION_ELEVENTH,
+ CURLVERSION_LAST /* never actually use this */
+} CURLversion;
+
+/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by
+ basically all programs ever that want to get version information. It is
+ meant to be a built-in version number for what kind of struct the caller
+ expects. If the struct ever changes, we redefine the NOW to another enum
+ from above. */
+#define CURLVERSION_NOW CURLVERSION_ELEVENTH
+
+struct curl_version_info_data {
+ CURLversion age; /* age of the returned struct */
+ const char *version; /* LIBCURL_VERSION */
+ unsigned int version_num; /* LIBCURL_VERSION_NUM */
+ const char *host; /* OS/host/cpu/machine when configured */
+ int features; /* bitmask, see defines below */
+ const char *ssl_version; /* human readable string */
+ long ssl_version_num; /* not used anymore, always 0 */
+ const char *libz_version; /* human readable string */
+ /* protocols is terminated by an entry with a NULL protoname */
+ const char * const *protocols;
+
+ /* The fields below this were added in CURLVERSION_SECOND */
+ const char *ares;
+ int ares_num;
+
+ /* This field was added in CURLVERSION_THIRD */
+ const char *libidn;
+
+ /* These field were added in CURLVERSION_FOURTH */
+
+ /* Same as '_libiconv_version' if built with HAVE_ICONV */
+ int iconv_ver_num;
+
+ const char *libssh_version; /* human readable string */
+
+ /* These fields were added in CURLVERSION_FIFTH */
+ unsigned int brotli_ver_num; /* Numeric Brotli version
+ (MAJOR << 24) | (MINOR << 12) | PATCH */
+ const char *brotli_version; /* human readable string. */
+
+ /* These fields were added in CURLVERSION_SIXTH */
+ unsigned int nghttp2_ver_num; /* Numeric nghttp2 version
+ (MAJOR << 16) | (MINOR << 8) | PATCH */
+ const char *nghttp2_version; /* human readable string. */
+ const char *quic_version; /* human readable quic (+ HTTP/3) library +
+ version or NULL */
+
+ /* These fields were added in CURLVERSION_SEVENTH */
+ const char *cainfo; /* the built-in default CURLOPT_CAINFO, might
+ be NULL */
+ const char *capath; /* the built-in default CURLOPT_CAPATH, might
+ be NULL */
+
+ /* These fields were added in CURLVERSION_EIGHTH */
+ unsigned int zstd_ver_num; /* Numeric Zstd version
+ (MAJOR << 24) | (MINOR << 12) | PATCH */
+ const char *zstd_version; /* human readable string. */
+
+ /* These fields were added in CURLVERSION_NINTH */
+ const char *hyper_version; /* human readable string. */
+
+ /* These fields were added in CURLVERSION_TENTH */
+ const char *gsasl_version; /* human readable string. */
+
+ /* These fields were added in CURLVERSION_ELEVENTH */
+ /* feature_names is terminated by an entry with a NULL feature name */
+ const char * const *feature_names;
+};
+typedef struct curl_version_info_data curl_version_info_data;
+
+#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */
+#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported
+ (deprecated) */
+#define CURL_VERSION_SSL (1<<2) /* SSL options are present */
+#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */
+#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */
+#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth is supported
+ (deprecated) */
+#define CURL_VERSION_DEBUG (1<<6) /* Built with debug capabilities */
+#define CURL_VERSION_ASYNCHDNS (1<<7) /* Asynchronous DNS resolves */
+#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */
+#define CURL_VERSION_LARGEFILE (1<<9) /* Supports files larger than 2GB */
+#define CURL_VERSION_IDN (1<<10) /* Internationized Domain Names are
+ supported */
+#define CURL_VERSION_SSPI (1<<11) /* Built against Windows SSPI */
+#define CURL_VERSION_CONV (1<<12) /* Character conversions supported */
+#define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported */
+#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */
+#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper
+ is supported */
+#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */
+#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */
+#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */
+#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */
+#define CURL_VERSION_PSL (1<<20) /* Mozilla's Public Suffix List, used
+ for cookie domain verification */
+#define CURL_VERSION_HTTPS_PROXY (1<<21) /* HTTPS-proxy support built-in */
+#define CURL_VERSION_MULTI_SSL (1<<22) /* Multiple SSL backends available */
+#define CURL_VERSION_BROTLI (1<<23) /* Brotli features are present. */
+#define CURL_VERSION_ALTSVC (1<<24) /* Alt-Svc handling built-in */
+#define CURL_VERSION_HTTP3 (1<<25) /* HTTP3 support built-in */
+#define CURL_VERSION_ZSTD (1<<26) /* zstd features are present */
+#define CURL_VERSION_UNICODE (1<<27) /* Unicode support on Windows */
+#define CURL_VERSION_HSTS (1<<28) /* HSTS is supported */
+#define CURL_VERSION_GSASL (1<<29) /* libgsasl is supported */
+#define CURL_VERSION_THREADSAFE (1<<30) /* libcurl API is thread-safe */
+
+ /*
+ * NAME curl_version_info()
+ *
+ * DESCRIPTION
+ *
+ * This function returns a pointer to a static copy of the version info
+ * struct. See above.
+ */
+CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion);
+
+/*
+ * NAME curl_easy_strerror()
+ *
+ * DESCRIPTION
+ *
+ * The curl_easy_strerror function may be used to turn a CURLcode value
+ * into the equivalent human readable error string. This is useful
+ * for printing meaningful error messages.
+ */
+CURL_EXTERN const char *curl_easy_strerror(CURLcode);
+
+/*
+ * NAME curl_share_strerror()
+ *
+ * DESCRIPTION
+ *
+ * The curl_share_strerror function may be used to turn a CURLSHcode value
+ * into the equivalent human readable error string. This is useful
+ * for printing meaningful error messages.
+ */
+CURL_EXTERN const char *curl_share_strerror(CURLSHcode);
+
+/*
+ * NAME curl_easy_pause()
+ *
+ * DESCRIPTION
+ *
+ * The curl_easy_pause function pauses or unpauses transfers. Select the new
+ * state by setting the bitmask, use the convenience defines below.
+ *
+ */
+CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask);
+
+#define CURLPAUSE_RECV (1<<0)
+#define CURLPAUSE_RECV_CONT (0)
+
+#define CURLPAUSE_SEND (1<<2)
+#define CURLPAUSE_SEND_CONT (0)
+
+#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND)
+#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT)
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+/* unfortunately, the easy.h and multi.h include files need options and info
+ stuff before they can be included! */
+#include "easy.h" /* nothing in curl is fun without the easy stuff */
+#include "multi.h"
+#include "urlapi.h"
+#include "options.h"
+#include "header.h"
+#include "websockets.h"
+
+/* the typechecker doesn't work in C++ (yet) */
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
+ ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \
+ !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK)
+#include "typecheck-gcc.h"
+#else
+#if defined(__STDC__) && (__STDC__ >= 1)
+/* This preprocessor magic that replaces a call with the exact same call is
+ only done to make sure application authors pass exactly three arguments
+ to these functions. */
+#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param)
+#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg)
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+#endif /* __STDC__ >= 1 */
+#endif /* gcc >= 4.3 && !__cplusplus && !CURL_DISABLE_TYPECHECK */
+
+#endif /* CURLINC_CURL_H */
diff --git a/iotdb-client/odbc/deps/curl-src/include/curl/curlver.h b/iotdb-client/odbc/deps/curl-src/include/curl/curlver.h
new file mode 100644
index 0000000000000..898816844792d
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/include/curl/curlver.h
@@ -0,0 +1,79 @@
+#ifndef CURLINC_CURLVER_H
+#define CURLINC_CURLVER_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+/* This header file contains nothing but libcurl version info, generated by
+ a script at release-time. This was made its own header file in 7.11.2 */
+
+/* This is the global package copyright */
+#define LIBCURL_COPYRIGHT "Daniel Stenberg, ."
+
+/* This is the version number of the libcurl package from which this header
+ file origins: */
+#define LIBCURL_VERSION "8.4.0-DEV"
+
+/* The numeric version number is also available "in parts" by using these
+ defines: */
+#define LIBCURL_VERSION_MAJOR 8
+#define LIBCURL_VERSION_MINOR 4
+#define LIBCURL_VERSION_PATCH 0
+
+/* This is the numeric version of the libcurl version number, meant for easier
+ parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will
+ always follow this syntax:
+
+ 0xXXYYZZ
+
+ Where XX, YY and ZZ are the main version, release and patch numbers in
+ hexadecimal (using 8 bits each). All three numbers are always represented
+ using two digits. 1.2 would appear as "0x010200" while version 9.11.7
+ appears as "0x090b07".
+
+ This 6-digit (24 bits) hexadecimal number does not show pre-release number,
+ and it is always a greater number in a more recent release. It makes
+ comparisons with greater than and less than work.
+
+ Note: This define is the full hex number and _does not_ use the
+ CURL_VERSION_BITS() macro since curl's own configure script greps for it
+ and needs it to contain the full number.
+*/
+#define LIBCURL_VERSION_NUM 0x080400
+
+/*
+ * This is the date and time when the full source package was created. The
+ * timestamp is not stored in git, as the timestamp is properly set in the
+ * tarballs by the maketgz script.
+ *
+ * The format of the date follows this template:
+ *
+ * "2007-11-23"
+ */
+#define LIBCURL_TIMESTAMP "[unreleased]"
+
+#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z))
+#define CURL_AT_LEAST_VERSION(x,y,z) \
+ (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
+
+#endif /* CURLINC_CURLVER_H */
diff --git a/iotdb-client/odbc/deps/curl-src/include/curl/easy.h b/iotdb-client/odbc/deps/curl-src/include/curl/easy.h
new file mode 100644
index 0000000000000..1285101c587d7
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/include/curl/easy.h
@@ -0,0 +1,125 @@
+#ifndef CURLINC_EASY_H
+#define CURLINC_EASY_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Flag bits in the curl_blob struct: */
+#define CURL_BLOB_COPY 1 /* tell libcurl to copy the data */
+#define CURL_BLOB_NOCOPY 0 /* tell libcurl to NOT copy the data */
+
+struct curl_blob {
+ void *data;
+ size_t len;
+ unsigned int flags; /* bit 0 is defined, the rest are reserved and should be
+ left zeroes */
+};
+
+CURL_EXTERN CURL *curl_easy_init(void);
+CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
+CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
+CURL_EXTERN void curl_easy_cleanup(CURL *curl);
+
+/*
+ * NAME curl_easy_getinfo()
+ *
+ * DESCRIPTION
+ *
+ * Request internal information from the curl session with this function.
+ * The third argument MUST be pointing to the specific type of the used option
+ * which is documented in each man page of the option. The data pointed to
+ * will be filled in accordingly and can be relied upon only if the function
+ * returns CURLE_OK. This function is intended to get used *AFTER* a performed
+ * transfer, all results from this function are undefined until the transfer
+ * is completed.
+ */
+CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
+
+
+/*
+ * NAME curl_easy_duphandle()
+ *
+ * DESCRIPTION
+ *
+ * Creates a new curl session handle with the same options set for the handle
+ * passed in. Duplicating a handle could only be a matter of cloning data and
+ * options, internal state info and things like persistent connections cannot
+ * be transferred. It is useful in multithreaded applications when you can run
+ * curl_easy_duphandle() for each new thread to avoid a series of identical
+ * curl_easy_setopt() invokes in every thread.
+ */
+CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl);
+
+/*
+ * NAME curl_easy_reset()
+ *
+ * DESCRIPTION
+ *
+ * Re-initializes a CURL handle to the default values. This puts back the
+ * handle to the same state as it was in when it was just created.
+ *
+ * It does keep: live connections, the Session ID cache, the DNS cache and the
+ * cookies.
+ */
+CURL_EXTERN void curl_easy_reset(CURL *curl);
+
+/*
+ * NAME curl_easy_recv()
+ *
+ * DESCRIPTION
+ *
+ * Receives data from the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen,
+ size_t *n);
+
+/*
+ * NAME curl_easy_send()
+ *
+ * DESCRIPTION
+ *
+ * Sends data over the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
+ size_t buflen, size_t *n);
+
+
+/*
+ * NAME curl_easy_upkeep()
+ *
+ * DESCRIPTION
+ *
+ * Performs connection upkeep for the given session handle.
+ */
+CURL_EXTERN CURLcode curl_easy_upkeep(CURL *curl);
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif
diff --git a/iotdb-client/odbc/deps/curl-src/include/curl/header.h b/iotdb-client/odbc/deps/curl-src/include/curl/header.h
new file mode 100644
index 0000000000000..8df11e1e4243e
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/include/curl/header.h
@@ -0,0 +1,74 @@
+#ifndef CURLINC_HEADER_H
+#define CURLINC_HEADER_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct curl_header {
+ char *name; /* this might not use the same case */
+ char *value;
+ size_t amount; /* number of headers using this name */
+ size_t index; /* ... of this instance, 0 or higher */
+ unsigned int origin; /* see bits below */
+ void *anchor; /* handle privately used by libcurl */
+};
+
+/* 'origin' bits */
+#define CURLH_HEADER (1<<0) /* plain server header */
+#define CURLH_TRAILER (1<<1) /* trailers */
+#define CURLH_CONNECT (1<<2) /* CONNECT headers */
+#define CURLH_1XX (1<<3) /* 1xx headers */
+#define CURLH_PSEUDO (1<<4) /* pseudo headers */
+
+typedef enum {
+ CURLHE_OK,
+ CURLHE_BADINDEX, /* header exists but not with this index */
+ CURLHE_MISSING, /* no such header exists */
+ CURLHE_NOHEADERS, /* no headers at all exist (yet) */
+ CURLHE_NOREQUEST, /* no request with this number was used */
+ CURLHE_OUT_OF_MEMORY, /* out of memory while processing */
+ CURLHE_BAD_ARGUMENT, /* a function argument was not okay */
+ CURLHE_NOT_BUILT_IN /* if API was disabled in the build */
+} CURLHcode;
+
+CURL_EXTERN CURLHcode curl_easy_header(CURL *easy,
+ const char *name,
+ size_t index,
+ unsigned int origin,
+ int request,
+ struct curl_header **hout);
+
+CURL_EXTERN struct curl_header *curl_easy_nextheader(CURL *easy,
+ unsigned int origin,
+ int request,
+ struct curl_header *prev);
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif /* CURLINC_HEADER_H */
diff --git a/iotdb-client/odbc/deps/curl-src/include/curl/mprintf.h b/iotdb-client/odbc/deps/curl-src/include/curl/mprintf.h
new file mode 100644
index 0000000000000..dc5664bc539ea
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/include/curl/mprintf.h
@@ -0,0 +1,70 @@
+#ifndef CURLINC_MPRINTF_H
+#define CURLINC_MPRINTF_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include
+#include /* needed for FILE */
+#include "curl.h" /* for CURL_EXTERN */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if (defined(__GNUC__) || defined(__clang__)) && \
+ defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
+ !defined(__MINGW32__) && !defined(CURL_NO_FMT_CHECKS)
+#define CURL_TEMP_PRINTF(a,b) __attribute__ ((format(printf, a, b)))
+#else
+#define CURL_TEMP_PRINTF(a,b)
+#endif
+
+CURL_EXTERN int curl_mprintf(const char *format, ...) CURL_TEMP_PRINTF(1, 2);
+CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...)
+ CURL_TEMP_PRINTF(2, 3);
+CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...)
+ CURL_TEMP_PRINTF(2, 3);
+CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength,
+ const char *format, ...) CURL_TEMP_PRINTF(3, 4);
+CURL_EXTERN int curl_mvprintf(const char *format, va_list args)
+ CURL_TEMP_PRINTF(1, 0);
+CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args)
+ CURL_TEMP_PRINTF(2, 0);
+CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args)
+ CURL_TEMP_PRINTF(2, 0);
+CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength,
+ const char *format, va_list args)
+ CURL_TEMP_PRINTF(3, 0);
+CURL_EXTERN char *curl_maprintf(const char *format, ...)
+ CURL_TEMP_PRINTF(1, 2);
+CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args)
+ CURL_TEMP_PRINTF(1, 0);
+
+#undef CURL_TEMP_PRINTF
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif /* CURLINC_MPRINTF_H */
diff --git a/iotdb-client/odbc/deps/curl-src/include/curl/multi.h b/iotdb-client/odbc/deps/curl-src/include/curl/multi.h
new file mode 100644
index 0000000000000..e79b48ff32ac7
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/include/curl/multi.h
@@ -0,0 +1,471 @@
+#ifndef CURLINC_MULTI_H
+#define CURLINC_MULTI_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+/*
+ This is an "external" header file. Don't give away any internals here!
+
+ GOALS
+
+ o Enable a "pull" interface. The application that uses libcurl decides where
+ and when to ask libcurl to get/send data.
+
+ o Enable multiple simultaneous transfers in the same thread without making it
+ complicated for the application.
+
+ o Enable the application to select() on its own file descriptors and curl's
+ file descriptors simultaneous easily.
+
+*/
+
+/*
+ * This header file should not really need to include "curl.h" since curl.h
+ * itself includes this file and we expect user applications to do #include
+ * without the need for especially including multi.h.
+ *
+ * For some reason we added this include here at one point, and rather than to
+ * break existing (wrongly written) libcurl applications, we leave it as-is
+ * but with this warning attached.
+ */
+#include "curl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
+typedef struct Curl_multi CURLM;
+#else
+typedef void CURLM;
+#endif
+
+typedef enum {
+ CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
+ curl_multi_socket*() soon */
+ CURLM_OK,
+ CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */
+ CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
+ CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */
+ CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
+ CURLM_BAD_SOCKET, /* the passed in socket argument did not match */
+ CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */
+ CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was
+ attempted to get added - again */
+ CURLM_RECURSIVE_API_CALL, /* an api function was called from inside a
+ callback */
+ CURLM_WAKEUP_FAILURE, /* wakeup is unavailable or failed */
+ CURLM_BAD_FUNCTION_ARGUMENT, /* function called with a bad parameter */
+ CURLM_ABORTED_BY_CALLBACK,
+ CURLM_UNRECOVERABLE_POLL,
+ CURLM_LAST
+} CURLMcode;
+
+/* just to make code nicer when using curl_multi_socket() you can now check
+ for CURLM_CALL_MULTI_SOCKET too in the same style it works for
+ curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */
+#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM
+
+/* bitmask bits for CURLMOPT_PIPELINING */
+#define CURLPIPE_NOTHING 0L
+#define CURLPIPE_HTTP1 1L
+#define CURLPIPE_MULTIPLEX 2L
+
+typedef enum {
+ CURLMSG_NONE, /* first, not used */
+ CURLMSG_DONE, /* This easy handle has completed. 'result' contains
+ the CURLcode of the transfer */
+ CURLMSG_LAST /* last, not used */
+} CURLMSG;
+
+struct CURLMsg {
+ CURLMSG msg; /* what this message means */
+ CURL *easy_handle; /* the handle it concerns */
+ union {
+ void *whatever; /* message-specific data */
+ CURLcode result; /* return code for transfer */
+ } data;
+};
+typedef struct CURLMsg CURLMsg;
+
+/* Based on poll(2) structure and values.
+ * We don't use pollfd and POLL* constants explicitly
+ * to cover platforms without poll(). */
+#define CURL_WAIT_POLLIN 0x0001
+#define CURL_WAIT_POLLPRI 0x0002
+#define CURL_WAIT_POLLOUT 0x0004
+
+struct curl_waitfd {
+ curl_socket_t fd;
+ short events;
+ short revents;
+};
+
+/*
+ * Name: curl_multi_init()
+ *
+ * Desc: initialize multi-style curl usage
+ *
+ * Returns: a new CURLM handle to use in all 'curl_multi' functions.
+ */
+CURL_EXTERN CURLM *curl_multi_init(void);
+
+/*
+ * Name: curl_multi_add_handle()
+ *
+ * Desc: add a standard curl handle to the multi stack
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
+ CURL *curl_handle);
+
+ /*
+ * Name: curl_multi_remove_handle()
+ *
+ * Desc: removes a curl handle from the multi stack again
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
+ CURL *curl_handle);
+
+ /*
+ * Name: curl_multi_fdset()
+ *
+ * Desc: Ask curl for its fd_set sets. The app can use these to select() or
+ * poll() on. We want curl_multi_perform() called as soon as one of
+ * them are ready.
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
+ fd_set *read_fd_set,
+ fd_set *write_fd_set,
+ fd_set *exc_fd_set,
+ int *max_fd);
+
+/*
+ * Name: curl_multi_wait()
+ *
+ * Desc: Poll on all fds within a CURLM set as well as any
+ * additional fds passed to the function.
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle,
+ struct curl_waitfd extra_fds[],
+ unsigned int extra_nfds,
+ int timeout_ms,
+ int *ret);
+
+/*
+ * Name: curl_multi_poll()
+ *
+ * Desc: Poll on all fds within a CURLM set as well as any
+ * additional fds passed to the function.
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_poll(CURLM *multi_handle,
+ struct curl_waitfd extra_fds[],
+ unsigned int extra_nfds,
+ int timeout_ms,
+ int *ret);
+
+/*
+ * Name: curl_multi_wakeup()
+ *
+ * Desc: wakes up a sleeping curl_multi_poll call.
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_wakeup(CURLM *multi_handle);
+
+ /*
+ * Name: curl_multi_perform()
+ *
+ * Desc: When the app thinks there's data available for curl it calls this
+ * function to read/write whatever there is right now. This returns
+ * as soon as the reads and writes are done. This function does not
+ * require that there actually is data available for reading or that
+ * data can be written, it can be called just in case. It returns
+ * the number of handles that still transfer data in the second
+ * argument's integer-pointer.
+ *
+ * Returns: CURLMcode type, general multi error code. *NOTE* that this only
+ * returns errors etc regarding the whole multi stack. There might
+ * still have occurred problems on individual transfers even when
+ * this returns OK.
+ */
+CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle,
+ int *running_handles);
+
+ /*
+ * Name: curl_multi_cleanup()
+ *
+ * Desc: Cleans up and removes a whole multi stack. It does not free or
+ * touch any individual easy handles in any way. We need to define
+ * in what state those handles will be if this function is called
+ * in the middle of a transfer.
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
+
+/*
+ * Name: curl_multi_info_read()
+ *
+ * Desc: Ask the multi handle if there's any messages/informationals from
+ * the individual transfers. Messages include informationals such as
+ * error code from the transfer or just the fact that a transfer is
+ * completed. More details on these should be written down as well.
+ *
+ * Repeated calls to this function will return a new struct each
+ * time, until a special "end of msgs" struct is returned as a signal
+ * that there is no more to get at this point.
+ *
+ * The data the returned pointer points to will not survive calling
+ * curl_multi_cleanup().
+ *
+ * The 'CURLMsg' struct is meant to be very simple and only contain
+ * very basic information. If more involved information is wanted,
+ * we will provide the particular "transfer handle" in that struct
+ * and that should/could/would be used in subsequent
+ * curl_easy_getinfo() calls (or similar). The point being that we
+ * must never expose complex structs to applications, as then we'll
+ * undoubtably get backwards compatibility problems in the future.
+ *
+ * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out
+ * of structs. It also writes the number of messages left in the
+ * queue (after this read) in the integer the second argument points
+ * to.
+ */
+CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle,
+ int *msgs_in_queue);
+
+/*
+ * Name: curl_multi_strerror()
+ *
+ * Desc: The curl_multi_strerror function may be used to turn a CURLMcode
+ * value into the equivalent human readable error string. This is
+ * useful for printing meaningful error messages.
+ *
+ * Returns: A pointer to a null-terminated error message.
+ */
+CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
+
+/*
+ * Name: curl_multi_socket() and
+ * curl_multi_socket_all()
+ *
+ * Desc: An alternative version of curl_multi_perform() that allows the
+ * application to pass in one of the file descriptors that have been
+ * detected to have "action" on them and let libcurl perform.
+ * See man page for details.
+ */
+#define CURL_POLL_NONE 0
+#define CURL_POLL_IN 1
+#define CURL_POLL_OUT 2
+#define CURL_POLL_INOUT 3
+#define CURL_POLL_REMOVE 4
+
+#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
+
+#define CURL_CSELECT_IN 0x01
+#define CURL_CSELECT_OUT 0x02
+#define CURL_CSELECT_ERR 0x04
+
+typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
+ curl_socket_t s, /* socket */
+ int what, /* see above */
+ void *userp, /* private callback
+ pointer */
+ void *socketp); /* private socket
+ pointer */
+/*
+ * Name: curl_multi_timer_callback
+ *
+ * Desc: Called by libcurl whenever the library detects a change in the
+ * maximum number of milliseconds the app is allowed to wait before
+ * curl_multi_socket() or curl_multi_perform() must be called
+ * (to allow libcurl's timed events to take place).
+ *
+ * Returns: The callback should return zero.
+ */
+typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */
+ long timeout_ms, /* see above */
+ void *userp); /* private callback
+ pointer */
+
+CURL_EXTERN CURLMcode CURL_DEPRECATED(7.19.5, "Use curl_multi_socket_action()")
+curl_multi_socket(CURLM *multi_handle, curl_socket_t s, int *running_handles);
+
+CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle,
+ curl_socket_t s,
+ int ev_bitmask,
+ int *running_handles);
+
+CURL_EXTERN CURLMcode CURL_DEPRECATED(7.19.5, "Use curl_multi_socket_action()")
+curl_multi_socket_all(CURLM *multi_handle, int *running_handles);
+
+#ifndef CURL_ALLOW_OLD_MULTI_SOCKET
+/* This macro below was added in 7.16.3 to push users who recompile to use
+ the new curl_multi_socket_action() instead of the old curl_multi_socket()
+*/
+#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z)
+#endif
+
+/*
+ * Name: curl_multi_timeout()
+ *
+ * Desc: Returns the maximum number of milliseconds the app is allowed to
+ * wait before curl_multi_socket() or curl_multi_perform() must be
+ * called (to allow libcurl's timed events to take place).
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle,
+ long *milliseconds);
+
+typedef enum {
+ /* This is the socket callback function pointer */
+ CURLOPT(CURLMOPT_SOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 1),
+
+ /* This is the argument passed to the socket callback */
+ CURLOPT(CURLMOPT_SOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 2),
+
+ /* set to 1 to enable pipelining for this multi handle */
+ CURLOPT(CURLMOPT_PIPELINING, CURLOPTTYPE_LONG, 3),
+
+ /* This is the timer callback function pointer */
+ CURLOPT(CURLMOPT_TIMERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 4),
+
+ /* This is the argument passed to the timer callback */
+ CURLOPT(CURLMOPT_TIMERDATA, CURLOPTTYPE_OBJECTPOINT, 5),
+
+ /* maximum number of entries in the connection cache */
+ CURLOPT(CURLMOPT_MAXCONNECTS, CURLOPTTYPE_LONG, 6),
+
+ /* maximum number of (pipelining) connections to one host */
+ CURLOPT(CURLMOPT_MAX_HOST_CONNECTIONS, CURLOPTTYPE_LONG, 7),
+
+ /* maximum number of requests in a pipeline */
+ CURLOPT(CURLMOPT_MAX_PIPELINE_LENGTH, CURLOPTTYPE_LONG, 8),
+
+ /* a connection with a content-length longer than this
+ will not be considered for pipelining */
+ CURLOPT(CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 9),
+
+ /* a connection with a chunk length longer than this
+ will not be considered for pipelining */
+ CURLOPT(CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 10),
+
+ /* a list of site names(+port) that are blocked from pipelining */
+ CURLOPT(CURLMOPT_PIPELINING_SITE_BL, CURLOPTTYPE_OBJECTPOINT, 11),
+
+ /* a list of server types that are blocked from pipelining */
+ CURLOPT(CURLMOPT_PIPELINING_SERVER_BL, CURLOPTTYPE_OBJECTPOINT, 12),
+
+ /* maximum number of open connections in total */
+ CURLOPT(CURLMOPT_MAX_TOTAL_CONNECTIONS, CURLOPTTYPE_LONG, 13),
+
+ /* This is the server push callback function pointer */
+ CURLOPT(CURLMOPT_PUSHFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 14),
+
+ /* This is the argument passed to the server push callback */
+ CURLOPT(CURLMOPT_PUSHDATA, CURLOPTTYPE_OBJECTPOINT, 15),
+
+ /* maximum number of concurrent streams to support on a connection */
+ CURLOPT(CURLMOPT_MAX_CONCURRENT_STREAMS, CURLOPTTYPE_LONG, 16),
+
+ CURLMOPT_LASTENTRY /* the last unused */
+} CURLMoption;
+
+
+/*
+ * Name: curl_multi_setopt()
+ *
+ * Desc: Sets options for the multi handle.
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
+ CURLMoption option, ...);
+
+
+/*
+ * Name: curl_multi_assign()
+ *
+ * Desc: This function sets an association in the multi handle between the
+ * given socket and a private pointer of the application. This is
+ * (only) useful for curl_multi_socket uses.
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
+ curl_socket_t sockfd, void *sockp);
+
+/*
+ * Name: curl_multi_get_handles()
+ *
+ * Desc: Returns an allocated array holding all handles currently added to
+ * the multi handle. Marks the final entry with a NULL pointer. If
+ * there is no easy handle added to the multi handle, this function
+ * returns an array with the first entry as a NULL pointer.
+ *
+ * Returns: NULL on failure, otherwise a CURL **array pointer
+ */
+CURL_EXTERN CURL **curl_multi_get_handles(CURLM *multi_handle);
+
+/*
+ * Name: curl_push_callback
+ *
+ * Desc: This callback gets called when a new stream is being pushed by the
+ * server. It approves or denies the new stream. It can also decide
+ * to completely fail the connection.
+ *
+ * Returns: CURL_PUSH_OK, CURL_PUSH_DENY or CURL_PUSH_ERROROUT
+ */
+#define CURL_PUSH_OK 0
+#define CURL_PUSH_DENY 1
+#define CURL_PUSH_ERROROUT 2 /* added in 7.72.0 */
+
+struct curl_pushheaders; /* forward declaration only */
+
+CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h,
+ size_t num);
+CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h,
+ const char *name);
+
+typedef int (*curl_push_callback)(CURL *parent,
+ CURL *easy,
+ size_t num_headers,
+ struct curl_pushheaders *headers,
+ void *userp);
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif
diff --git a/iotdb-client/odbc/deps/curl-src/include/curl/options.h b/iotdb-client/odbc/deps/curl-src/include/curl/options.h
new file mode 100644
index 0000000000000..1ed76a95c68cc
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/include/curl/options.h
@@ -0,0 +1,70 @@
+#ifndef CURLINC_OPTIONS_H
+#define CURLINC_OPTIONS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#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 null-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/iotdb-client/odbc/deps/curl-src/include/curl/stdcheaders.h b/iotdb-client/odbc/deps/curl-src/include/curl/stdcheaders.h
new file mode 100644
index 0000000000000..7451aa30525c1
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/include/curl/stdcheaders.h
@@ -0,0 +1,35 @@
+#ifndef CURLINC_STDCHEADERS_H
+#define CURLINC_STDCHEADERS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include
+
+size_t fread(void *, size_t, size_t, FILE *);
+size_t fwrite(const void *, size_t, size_t, FILE *);
+
+int strcasecmp(const char *, const char *);
+int strncasecmp(const char *, const char *, size_t);
+
+#endif /* CURLINC_STDCHEADERS_H */
diff --git a/iotdb-client/odbc/deps/curl-src/include/curl/system.h b/iotdb-client/odbc/deps/curl-src/include/curl/system.h
new file mode 100644
index 0000000000000..97e0d037a9eff
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/include/curl/system.h
@@ -0,0 +1,521 @@
+#ifndef CURLINC_SYSTEM_H
+#define CURLINC_SYSTEM_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+/*
+ * Try to keep one section per platform, compiler and architecture, otherwise,
+ * if an existing section is reused for a different one and later on the
+ * original is adjusted, probably the piggybacking one can be adversely
+ * changed.
+ *
+ * In order to differentiate between platforms/compilers/architectures use
+ * only compiler built in predefined preprocessor symbols.
+ *
+ * curl_off_t
+ * ----------
+ *
+ * For any given platform/compiler curl_off_t must be typedef'ed to a 64-bit
+ * wide signed integral data type. The width of this data type must remain
+ * constant and independent of any possible large file support settings.
+ *
+ * As an exception to the above, curl_off_t shall be typedef'ed to a 32-bit
+ * wide signed integral data type if there is no 64-bit type.
+ *
+ * As a general rule, curl_off_t shall not be mapped to off_t. This rule shall
+ * only be violated if off_t is the only 64-bit data type available and the
+ * size of off_t is independent of large file support settings. Keep your
+ * build on the safe side avoiding an off_t gating. If you have a 64-bit
+ * off_t then take for sure that another 64-bit data type exists, dig deeper
+ * and you will find it.
+ *
+ */
+
+#if defined(__DJGPP__) || defined(__GO32__)
+# if defined(__DJGPP__) && (__DJGPP__ > 1)
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# else
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__SALFORDC__)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__BORLANDC__)
+# if (__BORLANDC__ < 0x520)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# else
+# define CURL_TYPEOF_CURL_OFF_T __int64
+# define CURL_FORMAT_CURL_OFF_T "I64d"
+# define CURL_FORMAT_CURL_OFF_TU "I64u"
+# define CURL_SUFFIX_CURL_OFF_T i64
+# define CURL_SUFFIX_CURL_OFF_TU ui64
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__TURBOC__)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__POCC__)
+# if (__POCC__ < 280)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# elif defined(_MSC_VER)
+# define CURL_TYPEOF_CURL_OFF_T __int64
+# define CURL_FORMAT_CURL_OFF_T "I64d"
+# define CURL_FORMAT_CURL_OFF_TU "I64u"
+# define CURL_SUFFIX_CURL_OFF_T i64
+# define CURL_SUFFIX_CURL_OFF_TU ui64
+# else
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__LCC__)
+# if defined(__MCST__) /* MCST eLbrus Compiler Collection */
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+# else /* Local (or Little) C Compiler */
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+# endif
+
+#elif defined(__SYMBIAN32__)
+# if defined(__EABI__) /* Treat all ARM compilers equally */
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# elif defined(__CW32__)
+# pragma longlong on
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# elif defined(__VC32__)
+# define CURL_TYPEOF_CURL_OFF_T __int64
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
+
+#elif defined(macintosh)
+# include
+# if TYPE_LONGLONG
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# else
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
+
+#elif defined(__TANDEM)
+# if ! defined(__LP64)
+ /* Required for 32-bit NonStop builds only. */
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+# endif
+
+#elif defined(_WIN32_WCE)
+# define CURL_TYPEOF_CURL_OFF_T __int64
+# define CURL_FORMAT_CURL_OFF_T "I64d"
+# define CURL_FORMAT_CURL_OFF_TU "I64u"
+# define CURL_SUFFIX_CURL_OFF_T i64
+# define CURL_SUFFIX_CURL_OFF_TU ui64
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__MINGW32__)
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "I64d"
+# define CURL_FORMAT_CURL_OFF_TU "I64u"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_WS2TCPIP_H 1
+
+#elif defined(__VMS)
+# if defined(__VAX)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# else
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
+
+#elif defined(__OS400__)
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+
+#elif defined(__MVS__)
+# if defined(_LONG_LONG)
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# elif defined(_LP64)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# else
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+
+#elif defined(__370__)
+# if defined(__IBMC__) || defined(__IBMCPP__)
+# if defined(_ILP32)
+# elif defined(_LP64)
+# endif
+# if defined(_LONG_LONG)
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# elif defined(_LP64)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# else
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+# endif
+
+#elif defined(TPF)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__TINYC__) /* also known as tcc */
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+
+#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* Oracle Solaris Studio */
+# if !defined(__LP64) && (defined(__ILP32) || \
+ defined(__i386) || \
+ defined(__sparcv8) || \
+ defined(__sparcv8plus))
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# elif defined(__LP64) || \
+ defined(__amd64) || defined(__sparcv9)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+
+#elif defined(__xlc__) /* IBM xlc compiler */
+# if !defined(_LP64)
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# else
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+
+#elif defined(__hpux) /* HP aCC compiler */
+# if !defined(_LP64)
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# else
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+
+/* ===================================== */
+/* KEEP MSVC THE PENULTIMATE ENTRY */
+/* ===================================== */
+
+#elif defined(_MSC_VER)
+# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
+# define CURL_TYPEOF_CURL_OFF_T __int64
+# define CURL_FORMAT_CURL_OFF_T "I64d"
+# define CURL_FORMAT_CURL_OFF_TU "I64u"
+# define CURL_SUFFIX_CURL_OFF_T i64
+# define CURL_SUFFIX_CURL_OFF_TU ui64
+# else
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+/* ===================================== */
+/* KEEP GENERIC GCC THE LAST ENTRY */
+/* ===================================== */
+
+#elif defined(__GNUC__) && !defined(_SCO_DS)
+# if !defined(__LP64__) && \
+ (defined(__ILP32__) || defined(__i386__) || defined(__hppa__) || \
+ defined(__ppc__) || defined(__powerpc__) || defined(__arm__) || \
+ defined(__sparc__) || defined(__mips__) || defined(__sh__) || \
+ defined(__XTENSA__) || \
+ (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 4) || \
+ (defined(__LONG_MAX__) && __LONG_MAX__ == 2147483647L))
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# elif defined(__LP64__) || \
+ defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \
+ defined(__e2k__) || \
+ (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8) || \
+ (defined(__LONG_MAX__) && __LONG_MAX__ == 9223372036854775807L)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
+
+#else
+/* generic "safe guess" on old 32 bit style */
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+#endif
+
+#ifdef _AIX
+/* AIX needs */
+#define CURL_PULL_SYS_POLL_H
+#endif
+
+
+/* CURL_PULL_WS2TCPIP_H is defined above when inclusion of header file */
+/* ws2tcpip.h is required here to properly make type definitions below. */
+#ifdef CURL_PULL_WS2TCPIP_H
+# include
+# include
+# include
+#endif
+
+/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */
+/* sys/types.h is required here to properly make type definitions below. */
+#ifdef CURL_PULL_SYS_TYPES_H
+# include
+#endif
+
+/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */
+/* sys/socket.h is required here to properly make type definitions below. */
+#ifdef CURL_PULL_SYS_SOCKET_H
+# include
+#endif
+
+/* CURL_PULL_SYS_POLL_H is defined above when inclusion of header file */
+/* sys/poll.h is required here to properly make type definitions below. */
+#ifdef CURL_PULL_SYS_POLL_H
+# include
+#endif
+
+/* Data type definition of curl_socklen_t. */
+#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
+ typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
+#endif
+
+/* Data type definition of curl_off_t. */
+
+#ifdef CURL_TYPEOF_CURL_OFF_T
+ typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
+#endif
+
+/*
+ * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow
+ * these to be visible and exported by the external libcurl interface API,
+ * while also making them visible to the library internals, simply including
+ * curl_setup.h, without actually needing to include curl.h internally.
+ * If some day this section would grow big enough, all this should be moved
+ * to its own header file.
+ */
+
+/*
+ * Figure out if we can use the ## preprocessor operator, which is supported
+ * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__
+ * or __cplusplus so we need to carefully check for them too.
+ */
+
+#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
+ defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
+ defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \
+ defined(__ILEC400__)
+ /* This compiler is believed to have an ISO compatible preprocessor */
+#define CURL_ISOCPP
+#else
+ /* This compiler is believed NOT to have an ISO compatible preprocessor */
+#undef CURL_ISOCPP
+#endif
+
+/*
+ * Macros for minimum-width signed and unsigned curl_off_t integer constants.
+ */
+
+#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551)
+# define CURLINC_OFF_T_C_HLPR2(x) x
+# define CURLINC_OFF_T_C_HLPR1(x) CURLINC_OFF_T_C_HLPR2(x)
+# define CURL_OFF_T_C(Val) CURLINC_OFF_T_C_HLPR1(Val) ## \
+ CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
+# define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val) ## \
+ CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
+#else
+# ifdef CURL_ISOCPP
+# define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
+# else
+# define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
+# endif
+# define CURLINC_OFF_T_C_HLPR1(Val,Suffix) CURLINC_OFF_T_C_HLPR2(Val,Suffix)
+# define CURL_OFF_T_C(Val) CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
+# define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
+#endif
+
+#endif /* CURLINC_SYSTEM_H */
diff --git a/iotdb-client/odbc/deps/curl-src/include/curl/typecheck-gcc.h b/iotdb-client/odbc/deps/curl-src/include/curl/typecheck-gcc.h
new file mode 100644
index 0000000000000..b880f3dc60552
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/include/curl/typecheck-gcc.h
@@ -0,0 +1,717 @@
+#ifndef CURLINC_TYPECHECK_GCC_H
+#define CURLINC_TYPECHECK_GCC_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+/* wraps curl_easy_setopt() with typechecking */
+
+/* To add a new kind of warning, add an
+ * if(curlcheck_sometype_option(_curl_opt))
+ * if(!curlcheck_sometype(value))
+ * _curl_easy_setopt_err_sometype();
+ * block and define curlcheck_sometype_option, curlcheck_sometype and
+ * _curl_easy_setopt_err_sometype below
+ *
+ * NOTE: We use two nested 'if' statements here instead of the && operator, in
+ * order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x
+ * when compiling with -Wlogical-op.
+ *
+ * To add an option that uses the same type as an existing option, you'll just
+ * need to extend the appropriate _curl_*_option macro
+ */
+#define curl_easy_setopt(handle, option, value) \
+ __extension__({ \
+ CURLoption _curl_opt = (option); \
+ if(__builtin_constant_p(_curl_opt)) { \
+ CURL_IGNORE_DEPRECATION( \
+ if(curlcheck_long_option(_curl_opt)) \
+ if(!curlcheck_long(value)) \
+ _curl_easy_setopt_err_long(); \
+ if(curlcheck_off_t_option(_curl_opt)) \
+ if(!curlcheck_off_t(value)) \
+ _curl_easy_setopt_err_curl_off_t(); \
+ if(curlcheck_string_option(_curl_opt)) \
+ if(!curlcheck_string(value)) \
+ _curl_easy_setopt_err_string(); \
+ if(curlcheck_write_cb_option(_curl_opt)) \
+ if(!curlcheck_write_cb(value)) \
+ _curl_easy_setopt_err_write_callback(); \
+ if((_curl_opt) == CURLOPT_RESOLVER_START_FUNCTION) \
+ if(!curlcheck_resolver_start_callback(value)) \
+ _curl_easy_setopt_err_resolver_start_callback(); \
+ if((_curl_opt) == CURLOPT_READFUNCTION) \
+ if(!curlcheck_read_cb(value)) \
+ _curl_easy_setopt_err_read_cb(); \
+ if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \
+ if(!curlcheck_ioctl_cb(value)) \
+ _curl_easy_setopt_err_ioctl_cb(); \
+ if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \
+ if(!curlcheck_sockopt_cb(value)) \
+ _curl_easy_setopt_err_sockopt_cb(); \
+ if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \
+ if(!curlcheck_opensocket_cb(value)) \
+ _curl_easy_setopt_err_opensocket_cb(); \
+ if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \
+ if(!curlcheck_progress_cb(value)) \
+ _curl_easy_setopt_err_progress_cb(); \
+ if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \
+ if(!curlcheck_debug_cb(value)) \
+ _curl_easy_setopt_err_debug_cb(); \
+ if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \
+ if(!curlcheck_ssl_ctx_cb(value)) \
+ _curl_easy_setopt_err_ssl_ctx_cb(); \
+ if(curlcheck_conv_cb_option(_curl_opt)) \
+ if(!curlcheck_conv_cb(value)) \
+ _curl_easy_setopt_err_conv_cb(); \
+ if((_curl_opt) == CURLOPT_SEEKFUNCTION) \
+ if(!curlcheck_seek_cb(value)) \
+ _curl_easy_setopt_err_seek_cb(); \
+ if(curlcheck_cb_data_option(_curl_opt)) \
+ if(!curlcheck_cb_data(value)) \
+ _curl_easy_setopt_err_cb_data(); \
+ if((_curl_opt) == CURLOPT_ERRORBUFFER) \
+ if(!curlcheck_error_buffer(value)) \
+ _curl_easy_setopt_err_error_buffer(); \
+ if((_curl_opt) == CURLOPT_STDERR) \
+ if(!curlcheck_FILE(value)) \
+ _curl_easy_setopt_err_FILE(); \
+ if(curlcheck_postfields_option(_curl_opt)) \
+ if(!curlcheck_postfields(value)) \
+ _curl_easy_setopt_err_postfields(); \
+ if((_curl_opt) == CURLOPT_HTTPPOST) \
+ if(!curlcheck_arr((value), struct curl_httppost)) \
+ _curl_easy_setopt_err_curl_httpost(); \
+ if((_curl_opt) == CURLOPT_MIMEPOST) \
+ if(!curlcheck_ptr((value), curl_mime)) \
+ _curl_easy_setopt_err_curl_mimepost(); \
+ if(curlcheck_slist_option(_curl_opt)) \
+ if(!curlcheck_arr((value), struct curl_slist)) \
+ _curl_easy_setopt_err_curl_slist(); \
+ if((_curl_opt) == CURLOPT_SHARE) \
+ if(!curlcheck_ptr((value), CURLSH)) \
+ _curl_easy_setopt_err_CURLSH(); \
+ ) \
+ } \
+ curl_easy_setopt(handle, _curl_opt, value); \
+ })
+
+/* wraps curl_easy_getinfo() with typechecking */
+#define curl_easy_getinfo(handle, info, arg) \
+ __extension__({ \
+ CURLINFO _curl_info = (info); \
+ if(__builtin_constant_p(_curl_info)) { \
+ CURL_IGNORE_DEPRECATION( \
+ if(curlcheck_string_info(_curl_info)) \
+ if(!curlcheck_arr((arg), char *)) \
+ _curl_easy_getinfo_err_string(); \
+ if(curlcheck_long_info(_curl_info)) \
+ if(!curlcheck_arr((arg), long)) \
+ _curl_easy_getinfo_err_long(); \
+ if(curlcheck_double_info(_curl_info)) \
+ if(!curlcheck_arr((arg), double)) \
+ _curl_easy_getinfo_err_double(); \
+ if(curlcheck_slist_info(_curl_info)) \
+ if(!curlcheck_arr((arg), struct curl_slist *)) \
+ _curl_easy_getinfo_err_curl_slist(); \
+ if(curlcheck_tlssessioninfo_info(_curl_info)) \
+ if(!curlcheck_arr((arg), struct curl_tlssessioninfo *)) \
+ _curl_easy_getinfo_err_curl_tlssesssioninfo(); \
+ if(curlcheck_certinfo_info(_curl_info)) \
+ if(!curlcheck_arr((arg), struct curl_certinfo *)) \
+ _curl_easy_getinfo_err_curl_certinfo(); \
+ if(curlcheck_socket_info(_curl_info)) \
+ if(!curlcheck_arr((arg), curl_socket_t)) \
+ _curl_easy_getinfo_err_curl_socket(); \
+ if(curlcheck_off_t_info(_curl_info)) \
+ if(!curlcheck_arr((arg), curl_off_t)) \
+ _curl_easy_getinfo_err_curl_off_t(); \
+ ) \
+ } \
+ curl_easy_getinfo(handle, _curl_info, arg); \
+ })
+
+/*
+ * For now, just make sure that the functions are called with three arguments
+ */
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+
+
+/* the actual warnings, triggered by calling the _curl_easy_setopt_err*
+ * functions */
+
+/* To define a new warning, use _CURL_WARNING(identifier, "message") */
+#define CURLWARNING(id, message) \
+ static void __attribute__((__warning__(message))) \
+ __attribute__((__unused__)) __attribute__((__noinline__)) \
+ id(void) { __asm__(""); }
+
+CURLWARNING(_curl_easy_setopt_err_long,
+ "curl_easy_setopt expects a long argument for this option")
+CURLWARNING(_curl_easy_setopt_err_curl_off_t,
+ "curl_easy_setopt expects a curl_off_t argument for this option")
+CURLWARNING(_curl_easy_setopt_err_string,
+ "curl_easy_setopt expects a "
+ "string ('char *' or char[]) argument for this option"
+ )
+CURLWARNING(_curl_easy_setopt_err_write_callback,
+ "curl_easy_setopt expects a curl_write_callback argument for this option")
+CURLWARNING(_curl_easy_setopt_err_resolver_start_callback,
+ "curl_easy_setopt expects a "
+ "curl_resolver_start_callback argument for this option"
+ )
+CURLWARNING(_curl_easy_setopt_err_read_cb,
+ "curl_easy_setopt expects a curl_read_callback argument for this option")
+CURLWARNING(_curl_easy_setopt_err_ioctl_cb,
+ "curl_easy_setopt expects a curl_ioctl_callback argument for this option")
+CURLWARNING(_curl_easy_setopt_err_sockopt_cb,
+ "curl_easy_setopt expects a curl_sockopt_callback argument for this option")
+CURLWARNING(_curl_easy_setopt_err_opensocket_cb,
+ "curl_easy_setopt expects a "
+ "curl_opensocket_callback argument for this option"
+ )
+CURLWARNING(_curl_easy_setopt_err_progress_cb,
+ "curl_easy_setopt expects a curl_progress_callback argument for this option")
+CURLWARNING(_curl_easy_setopt_err_debug_cb,
+ "curl_easy_setopt expects a curl_debug_callback argument for this option")
+CURLWARNING(_curl_easy_setopt_err_ssl_ctx_cb,
+ "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
+CURLWARNING(_curl_easy_setopt_err_conv_cb,
+ "curl_easy_setopt expects a curl_conv_callback argument for this option")
+CURLWARNING(_curl_easy_setopt_err_seek_cb,
+ "curl_easy_setopt expects a curl_seek_callback argument for this option")
+CURLWARNING(_curl_easy_setopt_err_cb_data,
+ "curl_easy_setopt expects a "
+ "private data pointer as argument for this option")
+CURLWARNING(_curl_easy_setopt_err_error_buffer,
+ "curl_easy_setopt expects a "
+ "char buffer of CURL_ERROR_SIZE as argument for this option")
+CURLWARNING(_curl_easy_setopt_err_FILE,
+ "curl_easy_setopt expects a 'FILE *' argument for this option")
+CURLWARNING(_curl_easy_setopt_err_postfields,
+ "curl_easy_setopt expects a 'void *' or 'char *' argument for this option")
+CURLWARNING(_curl_easy_setopt_err_curl_httpost,
+ "curl_easy_setopt expects a 'struct curl_httppost *' "
+ "argument for this option")
+CURLWARNING(_curl_easy_setopt_err_curl_mimepost,
+ "curl_easy_setopt expects a 'curl_mime *' "
+ "argument for this option")
+CURLWARNING(_curl_easy_setopt_err_curl_slist,
+ "curl_easy_setopt expects a 'struct curl_slist *' argument for this option")
+CURLWARNING(_curl_easy_setopt_err_CURLSH,
+ "curl_easy_setopt expects a CURLSH* argument for this option")
+
+CURLWARNING(_curl_easy_getinfo_err_string,
+ "curl_easy_getinfo expects a pointer to 'char *' for this info")
+CURLWARNING(_curl_easy_getinfo_err_long,
+ "curl_easy_getinfo expects a pointer to long for this info")
+CURLWARNING(_curl_easy_getinfo_err_double,
+ "curl_easy_getinfo expects a pointer to double for this info")
+CURLWARNING(_curl_easy_getinfo_err_curl_slist,
+ "curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info")
+CURLWARNING(_curl_easy_getinfo_err_curl_tlssesssioninfo,
+ "curl_easy_getinfo expects a pointer to "
+ "'struct curl_tlssessioninfo *' for this info")
+CURLWARNING(_curl_easy_getinfo_err_curl_certinfo,
+ "curl_easy_getinfo expects a pointer to "
+ "'struct curl_certinfo *' for this info")
+CURLWARNING(_curl_easy_getinfo_err_curl_socket,
+ "curl_easy_getinfo expects a pointer to curl_socket_t for this info")
+CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
+ "curl_easy_getinfo expects a pointer to curl_off_t for this info")
+
+/* groups of curl_easy_setops options that take the same type of argument */
+
+/* To add a new option to one of the groups, just add
+ * (option) == CURLOPT_SOMETHING
+ * to the or-expression. If the option takes a long or curl_off_t, you don't
+ * have to do anything
+ */
+
+/* evaluates to true if option takes a long argument */
+#define curlcheck_long_option(option) \
+ (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
+
+#define curlcheck_off_t_option(option) \
+ (((option) > CURLOPTTYPE_OFF_T) && ((option) < CURLOPTTYPE_BLOB))
+
+/* evaluates to true if option takes a char* argument */
+#define curlcheck_string_option(option) \
+ ((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \
+ (option) == CURLOPT_ACCEPT_ENCODING || \
+ (option) == CURLOPT_ALTSVC || \
+ (option) == CURLOPT_CAINFO || \
+ (option) == CURLOPT_CAPATH || \
+ (option) == CURLOPT_COOKIE || \
+ (option) == CURLOPT_COOKIEFILE || \
+ (option) == CURLOPT_COOKIEJAR || \
+ (option) == CURLOPT_COOKIELIST || \
+ (option) == CURLOPT_CRLFILE || \
+ (option) == CURLOPT_CUSTOMREQUEST || \
+ (option) == CURLOPT_DEFAULT_PROTOCOL || \
+ (option) == CURLOPT_DNS_INTERFACE || \
+ (option) == CURLOPT_DNS_LOCAL_IP4 || \
+ (option) == CURLOPT_DNS_LOCAL_IP6 || \
+ (option) == CURLOPT_DNS_SERVERS || \
+ (option) == CURLOPT_DOH_URL || \
+ (option) == CURLOPT_EGDSOCKET || \
+ (option) == CURLOPT_FTP_ACCOUNT || \
+ (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \
+ (option) == CURLOPT_FTPPORT || \
+ (option) == CURLOPT_HSTS || \
+ (option) == CURLOPT_HAPROXY_CLIENT_IP || \
+ (option) == CURLOPT_INTERFACE || \
+ (option) == CURLOPT_ISSUERCERT || \
+ (option) == CURLOPT_KEYPASSWD || \
+ (option) == CURLOPT_KRBLEVEL || \
+ (option) == CURLOPT_LOGIN_OPTIONS || \
+ (option) == CURLOPT_MAIL_AUTH || \
+ (option) == CURLOPT_MAIL_FROM || \
+ (option) == CURLOPT_NETRC_FILE || \
+ (option) == CURLOPT_NOPROXY || \
+ (option) == CURLOPT_PASSWORD || \
+ (option) == CURLOPT_PINNEDPUBLICKEY || \
+ (option) == CURLOPT_PRE_PROXY || \
+ (option) == CURLOPT_PROTOCOLS_STR || \
+ (option) == CURLOPT_PROXY || \
+ (option) == CURLOPT_PROXY_CAINFO || \
+ (option) == CURLOPT_PROXY_CAPATH || \
+ (option) == CURLOPT_PROXY_CRLFILE || \
+ (option) == CURLOPT_PROXY_ISSUERCERT || \
+ (option) == CURLOPT_PROXY_KEYPASSWD || \
+ (option) == CURLOPT_PROXY_PINNEDPUBLICKEY || \
+ (option) == CURLOPT_PROXY_SERVICE_NAME || \
+ (option) == CURLOPT_PROXY_SSL_CIPHER_LIST || \
+ (option) == CURLOPT_PROXY_SSLCERT || \
+ (option) == CURLOPT_PROXY_SSLCERTTYPE || \
+ (option) == CURLOPT_PROXY_SSLKEY || \
+ (option) == CURLOPT_PROXY_SSLKEYTYPE || \
+ (option) == CURLOPT_PROXY_TLS13_CIPHERS || \
+ (option) == CURLOPT_PROXY_TLSAUTH_PASSWORD || \
+ (option) == CURLOPT_PROXY_TLSAUTH_TYPE || \
+ (option) == CURLOPT_PROXY_TLSAUTH_USERNAME || \
+ (option) == CURLOPT_PROXYPASSWORD || \
+ (option) == CURLOPT_PROXYUSERNAME || \
+ (option) == CURLOPT_PROXYUSERPWD || \
+ (option) == CURLOPT_RANDOM_FILE || \
+ (option) == CURLOPT_RANGE || \
+ (option) == CURLOPT_REDIR_PROTOCOLS_STR || \
+ (option) == CURLOPT_REFERER || \
+ (option) == CURLOPT_REQUEST_TARGET || \
+ (option) == CURLOPT_RTSP_SESSION_ID || \
+ (option) == CURLOPT_RTSP_STREAM_URI || \
+ (option) == CURLOPT_RTSP_TRANSPORT || \
+ (option) == CURLOPT_SASL_AUTHZID || \
+ (option) == CURLOPT_SERVICE_NAME || \
+ (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \
+ (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \
+ (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256 || \
+ (option) == CURLOPT_SSH_KNOWNHOSTS || \
+ (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \
+ (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \
+ (option) == CURLOPT_SSLCERT || \
+ (option) == CURLOPT_SSLCERTTYPE || \
+ (option) == CURLOPT_SSLENGINE || \
+ (option) == CURLOPT_SSLKEY || \
+ (option) == CURLOPT_SSLKEYTYPE || \
+ (option) == CURLOPT_SSL_CIPHER_LIST || \
+ (option) == CURLOPT_TLS13_CIPHERS || \
+ (option) == CURLOPT_TLSAUTH_PASSWORD || \
+ (option) == CURLOPT_TLSAUTH_TYPE || \
+ (option) == CURLOPT_TLSAUTH_USERNAME || \
+ (option) == CURLOPT_UNIX_SOCKET_PATH || \
+ (option) == CURLOPT_URL || \
+ (option) == CURLOPT_USERAGENT || \
+ (option) == CURLOPT_USERNAME || \
+ (option) == CURLOPT_AWS_SIGV4 || \
+ (option) == CURLOPT_USERPWD || \
+ (option) == CURLOPT_XOAUTH2_BEARER || \
+ (option) == CURLOPT_SSL_EC_CURVES || \
+ 0)
+
+/* evaluates to true if option takes a curl_write_callback argument */
+#define curlcheck_write_cb_option(option) \
+ ((option) == CURLOPT_HEADERFUNCTION || \
+ (option) == CURLOPT_WRITEFUNCTION)
+
+/* evaluates to true if option takes a curl_conv_callback argument */
+#define curlcheck_conv_cb_option(option) \
+ ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \
+ (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \
+ (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
+
+/* evaluates to true if option takes a data argument to pass to a callback */
+#define curlcheck_cb_data_option(option) \
+ ((option) == CURLOPT_CHUNK_DATA || \
+ (option) == CURLOPT_CLOSESOCKETDATA || \
+ (option) == CURLOPT_DEBUGDATA || \
+ (option) == CURLOPT_FNMATCH_DATA || \
+ (option) == CURLOPT_HEADERDATA || \
+ (option) == CURLOPT_HSTSREADDATA || \
+ (option) == CURLOPT_HSTSWRITEDATA || \
+ (option) == CURLOPT_INTERLEAVEDATA || \
+ (option) == CURLOPT_IOCTLDATA || \
+ (option) == CURLOPT_OPENSOCKETDATA || \
+ (option) == CURLOPT_PREREQDATA || \
+ (option) == CURLOPT_PROGRESSDATA || \
+ (option) == CURLOPT_READDATA || \
+ (option) == CURLOPT_SEEKDATA || \
+ (option) == CURLOPT_SOCKOPTDATA || \
+ (option) == CURLOPT_SSH_KEYDATA || \
+ (option) == CURLOPT_SSL_CTX_DATA || \
+ (option) == CURLOPT_WRITEDATA || \
+ (option) == CURLOPT_RESOLVER_START_DATA || \
+ (option) == CURLOPT_TRAILERDATA || \
+ (option) == CURLOPT_SSH_HOSTKEYDATA || \
+ 0)
+
+/* evaluates to true if option takes a POST data argument (void* or char*) */
+#define curlcheck_postfields_option(option) \
+ ((option) == CURLOPT_POSTFIELDS || \
+ (option) == CURLOPT_COPYPOSTFIELDS || \
+ 0)
+
+/* evaluates to true if option takes a struct curl_slist * argument */
+#define curlcheck_slist_option(option) \
+ ((option) == CURLOPT_HTTP200ALIASES || \
+ (option) == CURLOPT_HTTPHEADER || \
+ (option) == CURLOPT_MAIL_RCPT || \
+ (option) == CURLOPT_POSTQUOTE || \
+ (option) == CURLOPT_PREQUOTE || \
+ (option) == CURLOPT_PROXYHEADER || \
+ (option) == CURLOPT_QUOTE || \
+ (option) == CURLOPT_RESOLVE || \
+ (option) == CURLOPT_TELNETOPTIONS || \
+ (option) == CURLOPT_CONNECT_TO || \
+ 0)
+
+/* groups of curl_easy_getinfo infos that take the same type of argument */
+
+/* evaluates to true if info expects a pointer to char * argument */
+#define curlcheck_string_info(info) \
+ (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG && \
+ (info) != CURLINFO_PRIVATE)
+
+/* evaluates to true if info expects a pointer to long argument */
+#define curlcheck_long_info(info) \
+ (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
+
+/* evaluates to true if info expects a pointer to double argument */
+#define curlcheck_double_info(info) \
+ (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
+
+/* true if info expects a pointer to struct curl_slist * argument */
+#define curlcheck_slist_info(info) \
+ (((info) == CURLINFO_SSL_ENGINES) || ((info) == CURLINFO_COOKIELIST))
+
+/* true if info expects a pointer to struct curl_tlssessioninfo * argument */
+#define curlcheck_tlssessioninfo_info(info) \
+ (((info) == CURLINFO_TLS_SSL_PTR) || ((info) == CURLINFO_TLS_SESSION))
+
+/* true if info expects a pointer to struct curl_certinfo * argument */
+#define curlcheck_certinfo_info(info) ((info) == CURLINFO_CERTINFO)
+
+/* true if info expects a pointer to struct curl_socket_t argument */
+#define curlcheck_socket_info(info) \
+ (CURLINFO_SOCKET < (info) && (info) < CURLINFO_OFF_T)
+
+/* true if info expects a pointer to curl_off_t argument */
+#define curlcheck_off_t_info(info) \
+ (CURLINFO_OFF_T < (info))
+
+
+/* typecheck helpers -- check whether given expression has requested type */
+
+/* For pointers, you can use the curlcheck_ptr/curlcheck_arr macros,
+ * otherwise define a new macro. Search for __builtin_types_compatible_p
+ * in the GCC manual.
+ * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
+ * the actual expression passed to the curl_easy_setopt macro. This
+ * means that you can only apply the sizeof and __typeof__ operators, no
+ * == or whatsoever.
+ */
+
+/* XXX: should evaluate to true if expr is a pointer */
+#define curlcheck_any_ptr(expr) \
+ (sizeof(expr) == sizeof(void *))
+
+/* evaluates to true if expr is NULL */
+/* XXX: must not evaluate expr, so this check is not accurate */
+#define curlcheck_NULL(expr) \
+ (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
+
+/* evaluates to true if expr is type*, const type* or NULL */
+#define curlcheck_ptr(expr, type) \
+ (curlcheck_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), type *) || \
+ __builtin_types_compatible_p(__typeof__(expr), const type *))
+
+/* evaluates to true if expr is one of type[], type*, NULL or const type* */
+#define curlcheck_arr(expr, type) \
+ (curlcheck_ptr((expr), type) || \
+ __builtin_types_compatible_p(__typeof__(expr), type []))
+
+/* evaluates to true if expr is a string */
+#define curlcheck_string(expr) \
+ (curlcheck_arr((expr), char) || \
+ curlcheck_arr((expr), signed char) || \
+ curlcheck_arr((expr), unsigned char))
+
+/* evaluates to true if expr is a long (no matter the signedness)
+ * XXX: for now, int is also accepted (and therefore short and char, which
+ * are promoted to int when passed to a variadic function) */
+#define curlcheck_long(expr) \
+ (__builtin_types_compatible_p(__typeof__(expr), long) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed long) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \
+ __builtin_types_compatible_p(__typeof__(expr), int) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed int) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \
+ __builtin_types_compatible_p(__typeof__(expr), short) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed short) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \
+ __builtin_types_compatible_p(__typeof__(expr), char) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed char) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned char))
+
+/* evaluates to true if expr is of type curl_off_t */
+#define curlcheck_off_t(expr) \
+ (__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
+
+/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
+/* XXX: also check size of an char[] array? */
+#define curlcheck_error_buffer(expr) \
+ (curlcheck_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), char *) || \
+ __builtin_types_compatible_p(__typeof__(expr), char[]))
+
+/* evaluates to true if expr is of type (const) void* or (const) FILE* */
+#if 0
+#define curlcheck_cb_data(expr) \
+ (curlcheck_ptr((expr), void) || \
+ curlcheck_ptr((expr), FILE))
+#else /* be less strict */
+#define curlcheck_cb_data(expr) \
+ curlcheck_any_ptr(expr)
+#endif
+
+/* evaluates to true if expr is of type FILE* */
+#define curlcheck_FILE(expr) \
+ (curlcheck_NULL(expr) || \
+ (__builtin_types_compatible_p(__typeof__(expr), FILE *)))
+
+/* evaluates to true if expr can be passed as POST data (void* or char*) */
+#define curlcheck_postfields(expr) \
+ (curlcheck_ptr((expr), void) || \
+ curlcheck_arr((expr), char) || \
+ curlcheck_arr((expr), unsigned char))
+
+/* helper: __builtin_types_compatible_p distinguishes between functions and
+ * function pointers, hide it */
+#define curlcheck_cb_compatible(func, type) \
+ (__builtin_types_compatible_p(__typeof__(func), type) || \
+ __builtin_types_compatible_p(__typeof__(func) *, type))
+
+/* evaluates to true if expr is of type curl_resolver_start_callback */
+#define curlcheck_resolver_start_callback(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), curl_resolver_start_callback))
+
+/* evaluates to true if expr is of type curl_read_callback or "similar" */
+#define curlcheck_read_cb(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), __typeof__(fread) *) || \
+ curlcheck_cb_compatible((expr), curl_read_callback) || \
+ curlcheck_cb_compatible((expr), _curl_read_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_read_callback2) || \
+ curlcheck_cb_compatible((expr), _curl_read_callback3) || \
+ curlcheck_cb_compatible((expr), _curl_read_callback4) || \
+ curlcheck_cb_compatible((expr), _curl_read_callback5) || \
+ curlcheck_cb_compatible((expr), _curl_read_callback6))
+typedef size_t (*_curl_read_callback1)(char *, size_t, size_t, void *);
+typedef size_t (*_curl_read_callback2)(char *, size_t, size_t, const void *);
+typedef size_t (*_curl_read_callback3)(char *, size_t, size_t, FILE *);
+typedef size_t (*_curl_read_callback4)(void *, size_t, size_t, void *);
+typedef size_t (*_curl_read_callback5)(void *, size_t, size_t, const void *);
+typedef size_t (*_curl_read_callback6)(void *, size_t, size_t, FILE *);
+
+/* evaluates to true if expr is of type curl_write_callback or "similar" */
+#define curlcheck_write_cb(expr) \
+ (curlcheck_read_cb(expr) || \
+ curlcheck_cb_compatible((expr), __typeof__(fwrite) *) || \
+ curlcheck_cb_compatible((expr), curl_write_callback) || \
+ curlcheck_cb_compatible((expr), _curl_write_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_write_callback2) || \
+ curlcheck_cb_compatible((expr), _curl_write_callback3) || \
+ curlcheck_cb_compatible((expr), _curl_write_callback4) || \
+ curlcheck_cb_compatible((expr), _curl_write_callback5) || \
+ curlcheck_cb_compatible((expr), _curl_write_callback6))
+typedef size_t (*_curl_write_callback1)(const char *, size_t, size_t, void *);
+typedef size_t (*_curl_write_callback2)(const char *, size_t, size_t,
+ const void *);
+typedef size_t (*_curl_write_callback3)(const char *, size_t, size_t, FILE *);
+typedef size_t (*_curl_write_callback4)(const void *, size_t, size_t, void *);
+typedef size_t (*_curl_write_callback5)(const void *, size_t, size_t,
+ const void *);
+typedef size_t (*_curl_write_callback6)(const void *, size_t, size_t, FILE *);
+
+/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
+#define curlcheck_ioctl_cb(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), curl_ioctl_callback) || \
+ curlcheck_cb_compatible((expr), _curl_ioctl_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_ioctl_callback2) || \
+ curlcheck_cb_compatible((expr), _curl_ioctl_callback3) || \
+ curlcheck_cb_compatible((expr), _curl_ioctl_callback4))
+typedef curlioerr (*_curl_ioctl_callback1)(CURL *, int, void *);
+typedef curlioerr (*_curl_ioctl_callback2)(CURL *, int, const void *);
+typedef curlioerr (*_curl_ioctl_callback3)(CURL *, curliocmd, void *);
+typedef curlioerr (*_curl_ioctl_callback4)(CURL *, curliocmd, const void *);
+
+/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
+#define curlcheck_sockopt_cb(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), curl_sockopt_callback) || \
+ curlcheck_cb_compatible((expr), _curl_sockopt_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_sockopt_callback2))
+typedef int (*_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
+typedef int (*_curl_sockopt_callback2)(const void *, curl_socket_t,
+ curlsocktype);
+
+/* evaluates to true if expr is of type curl_opensocket_callback or
+ "similar" */
+#define curlcheck_opensocket_cb(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), curl_opensocket_callback) || \
+ curlcheck_cb_compatible((expr), _curl_opensocket_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_opensocket_callback2) || \
+ curlcheck_cb_compatible((expr), _curl_opensocket_callback3) || \
+ curlcheck_cb_compatible((expr), _curl_opensocket_callback4))
+typedef curl_socket_t (*_curl_opensocket_callback1)
+ (void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (*_curl_opensocket_callback2)
+ (void *, curlsocktype, const struct curl_sockaddr *);
+typedef curl_socket_t (*_curl_opensocket_callback3)
+ (const void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (*_curl_opensocket_callback4)
+ (const void *, curlsocktype, const struct curl_sockaddr *);
+
+/* evaluates to true if expr is of type curl_progress_callback or "similar" */
+#define curlcheck_progress_cb(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), curl_progress_callback) || \
+ curlcheck_cb_compatible((expr), _curl_progress_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_progress_callback2))
+typedef int (*_curl_progress_callback1)(void *,
+ double, double, double, double);
+typedef int (*_curl_progress_callback2)(const void *,
+ double, double, double, double);
+
+/* evaluates to true if expr is of type curl_debug_callback or "similar" */
+#define curlcheck_debug_cb(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), curl_debug_callback) || \
+ curlcheck_cb_compatible((expr), _curl_debug_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_debug_callback2) || \
+ curlcheck_cb_compatible((expr), _curl_debug_callback3) || \
+ curlcheck_cb_compatible((expr), _curl_debug_callback4) || \
+ curlcheck_cb_compatible((expr), _curl_debug_callback5) || \
+ curlcheck_cb_compatible((expr), _curl_debug_callback6) || \
+ curlcheck_cb_compatible((expr), _curl_debug_callback7) || \
+ curlcheck_cb_compatible((expr), _curl_debug_callback8))
+typedef int (*_curl_debug_callback1) (CURL *,
+ curl_infotype, char *, size_t, void *);
+typedef int (*_curl_debug_callback2) (CURL *,
+ curl_infotype, char *, size_t, const void *);
+typedef int (*_curl_debug_callback3) (CURL *,
+ curl_infotype, const char *, size_t, void *);
+typedef int (*_curl_debug_callback4) (CURL *,
+ curl_infotype, const char *, size_t, const void *);
+typedef int (*_curl_debug_callback5) (CURL *,
+ curl_infotype, unsigned char *, size_t, void *);
+typedef int (*_curl_debug_callback6) (CURL *,
+ curl_infotype, unsigned char *, size_t, const void *);
+typedef int (*_curl_debug_callback7) (CURL *,
+ curl_infotype, const unsigned char *, size_t, void *);
+typedef int (*_curl_debug_callback8) (CURL *,
+ curl_infotype, const unsigned char *, size_t, const void *);
+
+/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
+/* this is getting even messier... */
+#define curlcheck_ssl_ctx_cb(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), curl_ssl_ctx_callback) || \
+ curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback2) || \
+ curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback3) || \
+ curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback4) || \
+ curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback5) || \
+ curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback6) || \
+ curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback7) || \
+ curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback8))
+typedef CURLcode (*_curl_ssl_ctx_callback1)(CURL *, void *, void *);
+typedef CURLcode (*_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
+typedef CURLcode (*_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
+typedef CURLcode (*_curl_ssl_ctx_callback4)(CURL *, const void *,
+ const void *);
+#ifdef HEADER_SSL_H
+/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
+ * this will of course break if we're included before OpenSSL headers...
+ */
+typedef CURLcode (*_curl_ssl_ctx_callback5)(CURL *, SSL_CTX *, void *);
+typedef CURLcode (*_curl_ssl_ctx_callback6)(CURL *, SSL_CTX *, const void *);
+typedef CURLcode (*_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX *, void *);
+typedef CURLcode (*_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX *,
+ const void *);
+#else
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
+#endif
+
+/* evaluates to true if expr is of type curl_conv_callback or "similar" */
+#define curlcheck_conv_cb(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), curl_conv_callback) || \
+ curlcheck_cb_compatible((expr), _curl_conv_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_conv_callback2) || \
+ curlcheck_cb_compatible((expr), _curl_conv_callback3) || \
+ curlcheck_cb_compatible((expr), _curl_conv_callback4))
+typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
+typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
+typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
+typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
+
+/* evaluates to true if expr is of type curl_seek_callback or "similar" */
+#define curlcheck_seek_cb(expr) \
+ (curlcheck_NULL(expr) || \
+ curlcheck_cb_compatible((expr), curl_seek_callback) || \
+ curlcheck_cb_compatible((expr), _curl_seek_callback1) || \
+ curlcheck_cb_compatible((expr), _curl_seek_callback2))
+typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
+typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
+
+
+#endif /* CURLINC_TYPECHECK_GCC_H */
diff --git a/iotdb-client/odbc/deps/curl-src/include/curl/urlapi.h b/iotdb-client/odbc/deps/curl-src/include/curl/urlapi.h
new file mode 100644
index 0000000000000..88cdeb3bca6db
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/include/curl/urlapi.h
@@ -0,0 +1,150 @@
+#ifndef CURLINC_URLAPI_H
+#define CURLINC_URLAPI_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* the error codes for the URL API */
+typedef enum {
+ CURLUE_OK,
+ CURLUE_BAD_HANDLE, /* 1 */
+ CURLUE_BAD_PARTPOINTER, /* 2 */
+ CURLUE_MALFORMED_INPUT, /* 3 */
+ CURLUE_BAD_PORT_NUMBER, /* 4 */
+ CURLUE_UNSUPPORTED_SCHEME, /* 5 */
+ CURLUE_URLDECODE, /* 6 */
+ CURLUE_OUT_OF_MEMORY, /* 7 */
+ CURLUE_USER_NOT_ALLOWED, /* 8 */
+ CURLUE_UNKNOWN_PART, /* 9 */
+ CURLUE_NO_SCHEME, /* 10 */
+ CURLUE_NO_USER, /* 11 */
+ CURLUE_NO_PASSWORD, /* 12 */
+ CURLUE_NO_OPTIONS, /* 13 */
+ CURLUE_NO_HOST, /* 14 */
+ CURLUE_NO_PORT, /* 15 */
+ CURLUE_NO_QUERY, /* 16 */
+ CURLUE_NO_FRAGMENT, /* 17 */
+ CURLUE_NO_ZONEID, /* 18 */
+ CURLUE_BAD_FILE_URL, /* 19 */
+ CURLUE_BAD_FRAGMENT, /* 20 */
+ CURLUE_BAD_HOSTNAME, /* 21 */
+ CURLUE_BAD_IPV6, /* 22 */
+ CURLUE_BAD_LOGIN, /* 23 */
+ CURLUE_BAD_PASSWORD, /* 24 */
+ CURLUE_BAD_PATH, /* 25 */
+ CURLUE_BAD_QUERY, /* 26 */
+ CURLUE_BAD_SCHEME, /* 27 */
+ CURLUE_BAD_SLASHES, /* 28 */
+ CURLUE_BAD_USER, /* 29 */
+ CURLUE_LACKS_IDN, /* 30 */
+ CURLUE_LAST
+} CURLUcode;
+
+typedef enum {
+ CURLUPART_URL,
+ CURLUPART_SCHEME,
+ CURLUPART_USER,
+ CURLUPART_PASSWORD,
+ CURLUPART_OPTIONS,
+ CURLUPART_HOST,
+ CURLUPART_PORT,
+ CURLUPART_PATH,
+ CURLUPART_QUERY,
+ CURLUPART_FRAGMENT,
+ CURLUPART_ZONEID /* added in 7.65.0 */
+} CURLUPart;
+
+#define CURLU_DEFAULT_PORT (1<<0) /* return default port number */
+#define CURLU_NO_DEFAULT_PORT (1<<1) /* act as if no port number was set,
+ if the port number matches the
+ default for the scheme */
+#define CURLU_DEFAULT_SCHEME (1<<2) /* return default scheme if
+ missing */
+#define CURLU_NON_SUPPORT_SCHEME (1<<3) /* allow non-supported scheme */
+#define CURLU_PATH_AS_IS (1<<4) /* leave dot sequences */
+#define CURLU_DISALLOW_USER (1<<5) /* no user+password allowed */
+#define CURLU_URLDECODE (1<<6) /* URL decode on get */
+#define CURLU_URLENCODE (1<<7) /* URL encode on set */
+#define CURLU_APPENDQUERY (1<<8) /* append a form style part */
+#define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */
+#define CURLU_NO_AUTHORITY (1<<10) /* Allow empty authority when the
+ scheme is unknown. */
+#define CURLU_ALLOW_SPACE (1<<11) /* Allow spaces in the URL */
+#define CURLU_PUNYCODE (1<<12) /* get the host name in punycode */
+#define CURLU_PUNY2IDN (1<<13) /* punycode => IDN conversion */
+
+typedef struct Curl_URL CURLU;
+
+/*
+ * curl_url() creates a new CURLU handle and returns a pointer to it.
+ * Must be freed with curl_url_cleanup().
+ */
+CURL_EXTERN CURLU *curl_url(void);
+
+/*
+ * curl_url_cleanup() frees the CURLU handle and related resources used for
+ * the URL parsing. It will not free strings previously returned with the URL
+ * API.
+ */
+CURL_EXTERN void curl_url_cleanup(CURLU *handle);
+
+/*
+ * curl_url_dup() duplicates a CURLU handle and returns a new copy. The new
+ * handle must also be freed with curl_url_cleanup().
+ */
+CURL_EXTERN CURLU *curl_url_dup(const CURLU *in);
+
+/*
+ * curl_url_get() extracts a specific part of the URL from a CURLU
+ * handle. Returns error code. The returned pointer MUST be freed with
+ * curl_free() afterwards.
+ */
+CURL_EXTERN CURLUcode curl_url_get(const CURLU *handle, CURLUPart what,
+ char **part, unsigned int flags);
+
+/*
+ * curl_url_set() sets a specific part of the URL in a CURLU handle. Returns
+ * error code. The passed in string will be copied. Passing a NULL instead of
+ * a part string, clears that part.
+ */
+CURL_EXTERN CURLUcode curl_url_set(CURLU *handle, CURLUPart what,
+ const char *part, unsigned int flags);
+
+/*
+ * curl_url_strerror() turns a CURLUcode value into the equivalent human
+ * readable error string. This is useful for printing meaningful error
+ * messages.
+ */
+CURL_EXTERN const char *curl_url_strerror(CURLUcode);
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif /* CURLINC_URLAPI_H */
diff --git a/iotdb-client/odbc/deps/curl-src/include/curl/websockets.h b/iotdb-client/odbc/deps/curl-src/include/curl/websockets.h
new file mode 100644
index 0000000000000..6ef6a2bc92ec5
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/include/curl/websockets.h
@@ -0,0 +1,84 @@
+#ifndef CURLINC_WEBSOCKETS_H
+#define CURLINC_WEBSOCKETS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct curl_ws_frame {
+ int age; /* zero */
+ int flags; /* See the CURLWS_* defines */
+ curl_off_t offset; /* the offset of this data into the frame */
+ curl_off_t bytesleft; /* number of pending bytes left of the payload */
+ size_t len; /* size of the current data chunk */
+};
+
+/* flag bits */
+#define CURLWS_TEXT (1<<0)
+#define CURLWS_BINARY (1<<1)
+#define CURLWS_CONT (1<<2)
+#define CURLWS_CLOSE (1<<3)
+#define CURLWS_PING (1<<4)
+#define CURLWS_OFFSET (1<<5)
+
+/*
+ * NAME curl_ws_recv()
+ *
+ * DESCRIPTION
+ *
+ * Receives data from the websocket connection. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen,
+ size_t *recv,
+ const struct curl_ws_frame **metap);
+
+/* flags for curl_ws_send() */
+#define CURLWS_PONG (1<<6)
+
+/*
+ * NAME curl_ws_send()
+ *
+ * DESCRIPTION
+ *
+ * Sends data over the websocket connection. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_ws_send(CURL *curl, const void *buffer,
+ size_t buflen, size_t *sent,
+ curl_off_t fragsize,
+ unsigned int flags);
+
+/* bits for the CURLOPT_WS_OPTIONS bitmask: */
+#define CURLWS_RAW_MODE (1<<0)
+
+CURL_EXTERN const struct curl_ws_frame *curl_ws_meta(CURL *curl);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CURLINC_WEBSOCKETS_H */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/.checksrc b/iotdb-client/odbc/deps/curl-src/lib/.checksrc
new file mode 100644
index 0000000000000..16133a44c56cb
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/.checksrc
@@ -0,0 +1 @@
+enable STRERROR
diff --git a/iotdb-client/odbc/deps/curl-src/lib/.gitattributes b/iotdb-client/odbc/deps/curl-src/lib/.gitattributes
new file mode 100644
index 0000000000000..7e1eea50ffa63
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/.gitattributes
@@ -0,0 +1,3 @@
+# Copyright (C) Daniel Stenberg, , et al.
+#
+# SPDX-License-Identifier: curl
diff --git a/iotdb-client/odbc/deps/curl-src/lib/.gitignore b/iotdb-client/odbc/deps/curl-src/lib/.gitignore
new file mode 100644
index 0000000000000..7528196ed2aa8
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/.gitignore
@@ -0,0 +1,17 @@
+# Copyright (C) Daniel Stenberg, , et al.
+#
+# SPDX-License-Identifier: curl
+
+*.a
+*.imp
+*.nlm
+*.orig
+*.rej
+*.res
+TAGS
+curl_config.h
+curl_config.h.in
+libcurl.plist.dist
+libcurl.plist
+libcurl.vers
+stamp-h1
diff --git a/iotdb-client/odbc/deps/curl-src/lib/CMakeLists.txt b/iotdb-client/odbc/deps/curl-src/lib/CMakeLists.txt
new file mode 100644
index 0000000000000..6f849199cba78
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/CMakeLists.txt
@@ -0,0 +1,235 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+set(LIB_NAME libcurl)
+set(LIBCURL_OUTPUT_NAME libcurl CACHE STRING "Basename of the curl library")
+add_definitions(-DBUILDING_LIBCURL)
+
+configure_file(curl_config.h.cmake
+ ${CMAKE_CURRENT_BINARY_DIR}/curl_config.h)
+
+transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
+include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake)
+
+list(APPEND HHEADERS
+ ${CMAKE_CURRENT_BINARY_DIR}/curl_config.h
+ )
+
+# The rest of the build
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR}/../include)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)
+include_directories(${CMAKE_CURRENT_BINARY_DIR}/..)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+if(USE_ARES)
+ include_directories(${CARES_INCLUDE_DIR})
+endif()
+
+add_library(
+ curlu # special libcurlu library just for unittests
+ STATIC
+ EXCLUDE_FROM_ALL
+ ${HHEADERS} ${CSOURCES}
+)
+target_compile_definitions(curlu PUBLIC UNITTESTS CURL_STATICLIB)
+
+if(ENABLE_CURLDEBUG)
+ # We must compile these sources separately to avoid memdebug.h redefinitions
+ # applying to them.
+ set_source_files_properties(memdebug.c curl_multibyte.c PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON)
+endif()
+target_link_libraries(curlu PRIVATE ${CURL_LIBS})
+
+transform_makefile_inc("Makefile.soname" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake")
+include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake)
+
+if(CMAKE_SYSTEM_NAME STREQUAL "AIX" OR
+ CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
+ CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
+ CMAKE_SYSTEM_NAME STREQUAL "SunOS" OR
+ CMAKE_SYSTEM_NAME STREQUAL "GNU/kFreeBSD" OR
+
+ # FreeBSD comes with the a.out and elf flavours
+ # but a.out was supported up to version 3.x and
+ # elf from 3.x. I cannot imagine someone running
+ # CMake on those ancient systems
+ CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
+
+ CMAKE_SYSTEM_NAME STREQUAL "Haiku")
+
+ math(EXPR CMAKESONAME "${VERSIONCHANGE} - ${VERSIONDEL}")
+ set(CMAKEVERSION "${CMAKESONAME}.${VERSIONDEL}.${VERSIONADD}")
+else()
+ unset(CMAKESONAME)
+endif()
+
+## Library definition
+
+# Add "_imp" as a suffix before the extension to avoid conflicting with
+# the statically linked "libcurl.lib" (typically with MSVC)
+if(WIN32 AND
+ NOT IMPORT_LIB_SUFFIX AND
+ CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL CMAKE_IMPORT_LIBRARY_SUFFIX)
+ set(IMPORT_LIB_SUFFIX "_imp")
+endif()
+
+# Whether to do a single compilation pass for libcurl sources and reuse these
+# objects to generate both static and shared target.
+if(NOT DEFINED SHARE_LIB_OBJECT)
+ # Enable it by default on platforms where PIC is the default for both shared
+ # and static and there is a way to tell the linker which libcurl symbols it
+ # should export (vs. marking these symbols exportable at compile-time).
+ if(WIN32)
+ set(SHARE_LIB_OBJECT ON)
+ else()
+ # On other platforms, make it an option disabled by default
+ set(SHARE_LIB_OBJECT OFF)
+ endif()
+endif()
+
+if(WIN32)
+ # Define CURL_STATICLIB always, to disable __declspec(dllexport) for exported
+ # libcurl symbols. We handle exports via libcurl.def instead. Except with
+ # symbol hiding disabled or debug mode enabled, when we export _all_ symbols
+ # from libcurl DLL, without using libcurl.def.
+ add_definitions("-DCURL_STATICLIB")
+endif()
+
+if(SHARE_LIB_OBJECT)
+ set(LIB_OBJECT "libcurl_object")
+ add_library(${LIB_OBJECT} OBJECT ${HHEADERS} ${CSOURCES})
+ target_link_libraries(${LIB_OBJECT} PRIVATE ${CURL_LIBS})
+ set_target_properties(${LIB_OBJECT} PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+ if(HIDES_CURL_PRIVATE_SYMBOLS)
+ set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_FLAGS "${CURL_CFLAG_SYMBOLS_HIDE}")
+ set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
+ endif()
+ if(CURL_HAS_LTO)
+ set_target_properties(${LIB_OBJECT} PROPERTIES
+ INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE
+ INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
+ endif()
+
+ target_include_directories(${LIB_OBJECT} INTERFACE
+ $
+ $)
+
+ set(LIB_SOURCE $)
+else()
+ set(LIB_SOURCE ${HHEADERS} ${CSOURCES})
+endif()
+
+# we want it to be called libcurl on all platforms
+if(BUILD_STATIC_LIBS)
+ list(APPEND libcurl_export ${LIB_STATIC})
+ add_library(${LIB_STATIC} STATIC ${LIB_SOURCE})
+ add_library(${PROJECT_NAME}::${LIB_STATIC} ALIAS ${LIB_STATIC})
+ target_link_libraries(${LIB_STATIC} PRIVATE ${CURL_LIBS})
+ # Remove the "lib" prefix since the library is already named "libcurl".
+ set_target_properties(${LIB_STATIC} PROPERTIES
+ PREFIX "" OUTPUT_NAME "${LIBCURL_OUTPUT_NAME}"
+ SUFFIX "${STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}"
+ INTERFACE_COMPILE_DEFINITIONS "CURL_STATICLIB")
+ if(HIDES_CURL_PRIVATE_SYMBOLS)
+ set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_FLAGS "${CURL_CFLAG_SYMBOLS_HIDE}")
+ set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
+ endif()
+ if(CURL_HAS_LTO)
+ set_target_properties(${LIB_STATIC} PROPERTIES
+ INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE
+ INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
+ endif()
+ if(CMAKEVERSION AND CMAKESONAME)
+ set_target_properties(${LIB_STATIC} PROPERTIES
+ VERSION ${CMAKEVERSION} SOVERSION ${CMAKESONAME})
+ endif()
+
+ target_include_directories(${LIB_STATIC} INTERFACE
+ $
+ $)
+endif()
+
+if(BUILD_SHARED_LIBS)
+ list(APPEND libcurl_export ${LIB_SHARED})
+ add_library(${LIB_SHARED} SHARED ${LIB_SOURCE})
+ add_library(${PROJECT_NAME}::${LIB_SHARED} ALIAS ${LIB_SHARED})
+ if(WIN32)
+ set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES libcurl.rc)
+ if(HIDES_CURL_PRIVATE_SYMBOLS)
+ set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES "${CURL_SOURCE_DIR}/libcurl.def")
+ endif()
+ endif()
+ target_link_libraries(${LIB_SHARED} PRIVATE ${CURL_LIBS})
+ # Remove the "lib" prefix since the library is already named "libcurl".
+ set_target_properties(${LIB_SHARED} PROPERTIES
+ PREFIX "" OUTPUT_NAME "${LIBCURL_OUTPUT_NAME}"
+ IMPORT_PREFIX "" IMPORT_SUFFIX "${IMPORT_LIB_SUFFIX}${CMAKE_IMPORT_LIBRARY_SUFFIX}"
+ POSITION_INDEPENDENT_CODE ON)
+ if(HIDES_CURL_PRIVATE_SYMBOLS)
+ set_property(TARGET ${LIB_SHARED} APPEND PROPERTY COMPILE_FLAGS "${CURL_CFLAG_SYMBOLS_HIDE}")
+ set_property(TARGET ${LIB_SHARED} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
+ endif()
+ if(CURL_HAS_LTO)
+ set_target_properties(${LIB_SHARED} PROPERTIES
+ INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE
+ INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
+ endif()
+ if(CMAKEVERSION AND CMAKESONAME)
+ set_target_properties(${LIB_SHARED} PROPERTIES
+ VERSION ${CMAKEVERSION} SOVERSION ${CMAKESONAME})
+ endif()
+
+ target_include_directories(${LIB_SHARED} INTERFACE
+ $
+ $)
+endif()
+
+add_library(${LIB_NAME} ALIAS ${LIB_SELECTED})
+add_library(${PROJECT_NAME}::${LIB_NAME} ALIAS ${LIB_SELECTED})
+
+if(CURL_ENABLE_EXPORT_TARGET)
+ if(BUILD_STATIC_LIBS)
+ install(TARGETS ${LIB_STATIC}
+ EXPORT ${TARGETS_EXPORT_NAME}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ )
+ endif()
+ if(BUILD_SHARED_LIBS)
+ install(TARGETS ${LIB_SHARED}
+ EXPORT ${TARGETS_EXPORT_NAME}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ )
+ endif()
+
+ export(TARGETS ${libcurl_export}
+ FILE ${PROJECT_BINARY_DIR}/libcurl-target.cmake
+ NAMESPACE ${PROJECT_NAME}::
+ )
+endif()
diff --git a/iotdb-client/odbc/deps/curl-src/lib/Makefile.am b/iotdb-client/odbc/deps/curl-src/lib/Makefile.am
new file mode 100644
index 0000000000000..3c0a709127dc1
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/Makefile.am
@@ -0,0 +1,149 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+AUTOMAKE_OPTIONS = foreign nostdinc
+
+CMAKE_DIST = CMakeLists.txt curl_config.h.cmake
+
+EXTRA_DIST = Makefile.mk config-win32.h config-win32ce.h config-plan9.h \
+ config-riscos.h config-mac.h curl_config.h.in config-dos.h \
+ libcurl.plist libcurl.rc config-amigaos.h config-win32ce.h \
+ config-os400.h setup-os400.h $(CMAKE_DIST) setup-win32.h .checksrc \
+ Makefile.soname
+
+lib_LTLIBRARIES = libcurl.la
+
+if BUILD_UNITTESTS
+noinst_LTLIBRARIES = libcurlu.la
+else
+noinst_LTLIBRARIES =
+endif
+
+# This might hold -Werror
+CFLAGS += @CURL_CFLAG_EXTRAS@
+
+# Specify our include paths here, and do it relative to $(top_srcdir) and
+# $(top_builddir), to ensure that these paths which belong to the library
+# being currently built and tested are searched before the library which
+# might possibly already be installed in the system.
+#
+# $(top_srcdir)/include is for libcurl's external include files
+# $(top_builddir)/lib is for libcurl's generated lib/curl_config.h file
+# $(top_srcdir)/lib for libcurl's lib/curl_setup.h and other "private" files
+
+AM_CPPFLAGS = -I$(top_srcdir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/lib
+
+# Prevent LIBS from being used for all link targets
+LIBS = $(BLANK_AT_MAKETIME)
+
+include Makefile.soname
+
+AM_CPPFLAGS += -DBUILDING_LIBCURL
+AM_LDFLAGS =
+AM_CFLAGS =
+
+# Makefile.inc provides the CSOURCES and HHEADERS defines
+include Makefile.inc
+
+libcurl_la_SOURCES = $(CSOURCES) $(HHEADERS)
+libcurlu_la_SOURCES = $(CSOURCES) $(HHEADERS)
+
+libcurl_la_CPPFLAGS_EXTRA =
+libcurl_la_LDFLAGS_EXTRA =
+libcurl_la_CFLAGS_EXTRA =
+
+if CURL_LT_SHLIB_USE_VERSION_INFO
+libcurl_la_LDFLAGS_EXTRA += $(VERSIONINFO)
+endif
+
+if CURL_LT_SHLIB_USE_NO_UNDEFINED
+libcurl_la_LDFLAGS_EXTRA += -no-undefined
+endif
+
+if CURL_LT_SHLIB_USE_MIMPURE_TEXT
+libcurl_la_LDFLAGS_EXTRA += -mimpure-text
+endif
+
+if CURL_LT_SHLIB_USE_VERSIONED_SYMBOLS
+libcurl_la_LDFLAGS_EXTRA += -Wl,--version-script=libcurl.vers
+else
+# if symbol-hiding is enabled, hide them!
+if DOING_CURL_SYMBOL_HIDING
+libcurl_la_LDFLAGS_EXTRA += -export-symbols-regex '^curl_.*'
+endif
+endif
+
+if USE_CPPFLAG_CURL_STATICLIB
+libcurl_la_CPPFLAGS_EXTRA += -DCURL_STATICLIB
+else
+if HAVE_WINDRES
+libcurl_la_SOURCES += $(LIB_RCFILES)
+$(LIB_RCFILES): $(top_srcdir)/include/curl/curlver.h
+endif
+endif
+
+if DOING_CURL_SYMBOL_HIDING
+libcurl_la_CPPFLAGS_EXTRA += -DCURL_HIDDEN_SYMBOLS
+libcurl_la_CFLAGS_EXTRA += $(CFLAG_CURL_SYMBOL_HIDING)
+endif
+
+libcurl_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcurl_la_CPPFLAGS_EXTRA)
+libcurl_la_LDFLAGS = $(AM_LDFLAGS) $(libcurl_la_LDFLAGS_EXTRA) $(LDFLAGS) $(LIBCURL_LIBS)
+libcurl_la_CFLAGS = $(AM_CFLAGS) $(libcurl_la_CFLAGS_EXTRA)
+
+libcurlu_la_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_STATICLIB -DUNITTESTS
+libcurlu_la_LDFLAGS = $(AM_LDFLAGS) -static $(LIBCURL_LIBS)
+libcurlu_la_CFLAGS = $(AM_CFLAGS)
+
+CHECKSRC = $(CS_$(V))
+CS_0 = @echo " RUN " $@;
+CS_1 =
+CS_ = $(CS_0)
+
+checksrc:
+ $(CHECKSRC)(@PERL@ $(top_srcdir)/scripts/checksrc.pl -D$(srcdir) \
+ -W$(srcdir)/curl_config.h $(srcdir)/*.[ch] $(srcdir)/vauth/*.[ch] \
+ $(srcdir)/vtls/*.[ch] $(srcdir)/vquic/*.[ch] $(srcdir)/vssh/*.[ch])
+
+if CURLDEBUG
+# for debug builds, we scan the sources on all regular make invokes
+all-local: checksrc
+endif
+
+# disable the tests that are mostly causing false positives
+TIDYFLAGS=-checks=-clang-analyzer-security.insecureAPI.strcpy,-clang-analyzer-optin.performance.Padding,-clang-analyzer-valist.Uninitialized,-clang-analyzer-core.NonNullParamChecker,-clang-analyzer-core.NullDereference -quiet
+
+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
+
+if HAVE_WINDRES
+.rc.lo:
+ $(LIBTOOL) --tag=RC --mode=compile $(RC) -I$(top_srcdir)/include $(RCFLAGS) -i $< -o $@
+endif
diff --git a/iotdb-client/odbc/deps/curl-src/lib/Makefile.inc b/iotdb-client/odbc/deps/curl-src/lib/Makefile.inc
new file mode 100644
index 0000000000000..e568ef9535339
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/Makefile.inc
@@ -0,0 +1,370 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+
+LIB_VAUTH_CFILES = \
+ vauth/cleartext.c \
+ vauth/cram.c \
+ vauth/digest.c \
+ vauth/digest_sspi.c \
+ vauth/gsasl.c \
+ vauth/krb5_gssapi.c \
+ vauth/krb5_sspi.c \
+ vauth/ntlm.c \
+ vauth/ntlm_sspi.c \
+ vauth/oauth2.c \
+ vauth/spnego_gssapi.c \
+ vauth/spnego_sspi.c \
+ vauth/vauth.c
+
+LIB_VAUTH_HFILES = \
+ vauth/digest.h \
+ vauth/ntlm.h \
+ vauth/vauth.h
+
+LIB_VTLS_CFILES = \
+ vtls/bearssl.c \
+ vtls/gtls.c \
+ vtls/hostcheck.c \
+ vtls/keylog.c \
+ vtls/mbedtls.c \
+ vtls/mbedtls_threadlock.c \
+ vtls/openssl.c \
+ vtls/rustls.c \
+ vtls/schannel.c \
+ vtls/schannel_verify.c \
+ vtls/sectransp.c \
+ vtls/vtls.c \
+ vtls/wolfssl.c \
+ vtls/x509asn1.c
+
+LIB_VTLS_HFILES = \
+ vtls/bearssl.h \
+ vtls/gtls.h \
+ vtls/hostcheck.h \
+ vtls/keylog.h \
+ vtls/mbedtls.h \
+ vtls/mbedtls_threadlock.h \
+ vtls/openssl.h \
+ vtls/rustls.h \
+ vtls/schannel.h \
+ vtls/schannel_int.h \
+ vtls/sectransp.h \
+ vtls/vtls.h \
+ vtls/vtls_int.h \
+ vtls/wolfssl.h \
+ vtls/x509asn1.h
+
+LIB_VQUIC_CFILES = \
+ vquic/curl_msh3.c \
+ vquic/curl_ngtcp2.c \
+ vquic/curl_quiche.c \
+ vquic/vquic.c
+
+LIB_VQUIC_HFILES = \
+ vquic/curl_msh3.h \
+ vquic/curl_ngtcp2.h \
+ vquic/curl_quiche.h \
+ vquic/vquic.h \
+ vquic/vquic_int.h
+
+LIB_VSSH_CFILES = \
+ vssh/libssh.c \
+ vssh/libssh2.c \
+ vssh/wolfssh.c
+
+LIB_VSSH_HFILES = \
+ vssh/ssh.h
+
+LIB_CFILES = \
+ altsvc.c \
+ amigaos.c \
+ asyn-ares.c \
+ asyn-thread.c \
+ base64.c \
+ bufq.c \
+ bufref.c \
+ c-hyper.c \
+ cf-h1-proxy.c \
+ cf-h2-proxy.c \
+ cf-haproxy.c \
+ cf-https-connect.c \
+ cf-socket.c \
+ cfilters.c \
+ conncache.c \
+ connect.c \
+ content_encoding.c \
+ cookie.c \
+ curl_addrinfo.c \
+ curl_des.c \
+ curl_endian.c \
+ curl_fnmatch.c \
+ curl_get_line.c \
+ curl_gethostname.c \
+ curl_gssapi.c \
+ curl_memrchr.c \
+ curl_multibyte.c \
+ curl_ntlm_core.c \
+ curl_ntlm_wb.c \
+ curl_path.c \
+ curl_range.c \
+ curl_rtmp.c \
+ curl_sasl.c \
+ curl_sspi.c \
+ curl_threads.c \
+ curl_trc.c \
+ dict.c \
+ doh.c \
+ dynbuf.c \
+ dynhds.c \
+ easy.c \
+ easygetopt.c \
+ easyoptions.c \
+ escape.c \
+ file.c \
+ fileinfo.c \
+ fopen.c \
+ formdata.c \
+ ftp.c \
+ ftplistparser.c \
+ getenv.c \
+ getinfo.c \
+ gopher.c \
+ hash.c \
+ headers.c \
+ hmac.c \
+ hostasyn.c \
+ hostip.c \
+ hostip4.c \
+ hostip6.c \
+ hostsyn.c \
+ hsts.c \
+ http.c \
+ http1.c \
+ http2.c \
+ http_aws_sigv4.c \
+ http_chunks.c \
+ http_digest.c \
+ http_negotiate.c \
+ http_ntlm.c \
+ http_proxy.c \
+ idn.c \
+ if2ip.c \
+ imap.c \
+ inet_ntop.c \
+ inet_pton.c \
+ krb5.c \
+ ldap.c \
+ llist.c \
+ macos.c \
+ md4.c \
+ md5.c \
+ memdebug.c \
+ mime.c \
+ mprintf.c \
+ mqtt.c \
+ multi.c \
+ netrc.c \
+ nonblock.c \
+ noproxy.c \
+ openldap.c \
+ parsedate.c \
+ pingpong.c \
+ pop3.c \
+ progress.c \
+ psl.c \
+ rand.c \
+ rename.c \
+ rtsp.c \
+ select.c \
+ sendf.c \
+ setopt.c \
+ sha256.c \
+ share.c \
+ slist.c \
+ smb.c \
+ smtp.c \
+ socketpair.c \
+ socks.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 \
+ timediff.c \
+ timeval.c \
+ transfer.c \
+ url.c \
+ urlapi.c \
+ version.c \
+ version_win32.c \
+ warnless.c \
+ ws.c
+
+LIB_HFILES = \
+ altsvc.h \
+ amigaos.h \
+ arpa_telnet.h \
+ asyn.h \
+ bufq.h \
+ bufref.h \
+ c-hyper.h \
+ cf-h1-proxy.h \
+ cf-h2-proxy.h \
+ cf-haproxy.h \
+ cf-https-connect.h \
+ cf-socket.h \
+ cfilters.h \
+ conncache.h \
+ connect.h \
+ content_encoding.h \
+ cookie.h \
+ curl_addrinfo.h \
+ curl_base64.h \
+ curl_ctype.h \
+ curl_des.h \
+ curl_endian.h \
+ curl_fnmatch.h \
+ curl_get_line.h \
+ curl_gethostname.h \
+ curl_gssapi.h \
+ curl_hmac.h \
+ curl_krb5.h \
+ curl_ldap.h \
+ curl_md4.h \
+ curl_md5.h \
+ curl_memory.h \
+ curl_memrchr.h \
+ curl_multibyte.h \
+ curl_ntlm_core.h \
+ curl_ntlm_wb.h \
+ curl_path.h \
+ curl_printf.h \
+ curl_range.h \
+ curl_rtmp.h \
+ curl_sasl.h \
+ curl_setup.h \
+ curl_setup_once.h \
+ curl_sha256.h \
+ curl_sspi.h \
+ curl_threads.h \
+ curl_trc.h \
+ curlx.h \
+ dict.h \
+ doh.h \
+ dynbuf.h \
+ dynhds.h \
+ easy_lock.h \
+ easyif.h \
+ easyoptions.h \
+ escape.h \
+ file.h \
+ fileinfo.h \
+ fopen.h \
+ formdata.h \
+ ftp.h \
+ ftplistparser.h \
+ functypes.h \
+ getinfo.h \
+ gopher.h \
+ hash.h \
+ headers.h \
+ hostip.h \
+ hsts.h \
+ http.h \
+ http1.h \
+ http2.h \
+ http_aws_sigv4.h \
+ http_chunks.h \
+ http_digest.h \
+ http_negotiate.h \
+ http_ntlm.h \
+ http_proxy.h \
+ idn.h \
+ if2ip.h \
+ imap.h \
+ inet_ntop.h \
+ inet_pton.h \
+ llist.h \
+ macos.h \
+ memdebug.h \
+ mime.h \
+ mqtt.h \
+ multihandle.h \
+ multiif.h \
+ netrc.h \
+ nonblock.h \
+ noproxy.h \
+ parsedate.h \
+ pingpong.h \
+ pop3.h \
+ progress.h \
+ psl.h \
+ rand.h \
+ rename.h \
+ rtsp.h \
+ select.h \
+ sendf.h \
+ setopt.h \
+ setup-vms.h \
+ share.h \
+ sigpipe.h \
+ slist.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 \
+ timediff.h \
+ timeval.h \
+ transfer.h \
+ url.h \
+ urlapi-int.h \
+ urldata.h \
+ version_win32.h \
+ warnless.h \
+ ws.h
+
+LIB_RCFILES = libcurl.rc
+
+CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES) \
+ $(LIB_VQUIC_CFILES) $(LIB_VSSH_CFILES)
+HHEADERS = $(LIB_HFILES) $(LIB_VAUTH_HFILES) $(LIB_VTLS_HFILES) \
+ $(LIB_VQUIC_HFILES) $(LIB_VSSH_HFILES)
diff --git a/iotdb-client/odbc/deps/curl-src/lib/Makefile.mk b/iotdb-client/odbc/deps/curl-src/lib/Makefile.mk
new file mode 100644
index 0000000000000..5071600b59d5d
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/Makefile.mk
@@ -0,0 +1,426 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+#***************************************************************************
+
+# Makefile to build curl parts with GCC-like toolchains and optional features.
+#
+# Usage: [mingw32-]make -f Makefile.mk CFG=-feat1[-feat2][-feat3][...]
+# Example: [mingw32-]make -f Makefile.mk CFG=-zlib-ssl-libssh2-ipv6
+#
+# Look for ' ?=' to find all accepted customization variables.
+
+# This script is reused by 'src' and 'docs/examples' Makefile.mk scripts.
+
+ifndef PROOT
+ PROOT := ..
+ LOCAL := 1
+endif
+
+### Common
+
+CFLAGS ?=
+CPPFLAGS ?=
+RCFLAGS ?=
+LDFLAGS ?=
+CURL_LDFLAGS_BIN ?=
+CURL_LDFLAGS_LIB ?=
+LIBS ?=
+
+CROSSPREFIX ?=
+
+ifeq ($(CC),cc)
+ CC := gcc
+endif
+CC := $(CROSSPREFIX)$(CC)
+AR := $(CROSSPREFIX)$(AR)
+RC ?= $(CROSSPREFIX)windres
+
+# For compatibility
+ARCH ?=
+ifeq ($(ARCH),w64)
+ TRIPLET := x86_64-w64-mingw32
+ CFLAGS += -m64
+ LDFLAGS += -m64
+ RCFLAGS += --target=pe-x86-64
+else ifdef ARCH
+ TRIPLET := i686-w64-mingw32
+ CFLAGS += -m32
+ LDFLAGS += -m32
+ RCFLAGS += --target=pe-i386
+else
+ TRIPLET ?= $(shell $(CC) -dumpmachine)
+endif
+
+BIN_EXT := .exe
+
+ifneq ($(findstring -w,$(TRIPLET)),)
+ WIN32 := 1
+else ifneq ($(findstring msdos,$(TRIPLET)),)
+ # Cross-tools: https://github.com/andrewwutw/build-djgpp
+ MSDOS := 1
+else ifneq ($(findstring amigaos,$(TRIPLET)),)
+ # Cross-tools: https://github.com/bebbo/amiga-gcc
+ AMIGA := 1
+endif
+
+CPPFLAGS += -I. -I$(PROOT)/include
+RCFLAGS += -I$(PROOT)/include
+
+ifndef WIN32
+ DYN :=
+endif
+
+ifdef AMIGA
+ BIN_EXT :=
+endif
+
+### Deprecated settings. For compatibility.
+
+ifdef WATT_ROOT
+ WATT_PATH := $(realpath $(WATT_ROOT))
+endif
+
+### Optional features
+
+ifneq ($(findstring -debug,$(CFG)),)
+ CFLAGS += -g
+ CPPFLAGS += -DDEBUGBUILD
+else
+ CPPFLAGS += -DNDEBUG
+endif
+ifneq ($(findstring -trackmem,$(CFG)),)
+ CPPFLAGS += -DCURLDEBUG
+endif
+ifneq ($(findstring -map,$(CFG)),)
+ MAP := 1
+endif
+
+ifdef WIN32
+ ifneq ($(findstring -unicode,$(CFG)),)
+ CPPFLAGS += -DUNICODE -D_UNICODE
+ CURL_LDFLAGS_BIN += -municode
+ endif
+endif
+
+# CPPFLAGS below are only necessary when building libcurl via 'lib' (see
+# comments below about exceptions). Always include them anyway to match
+# behavior of other build systems.
+
+# Linker options to exclude for shared mode executables.
+_LDFLAGS :=
+_LIBS :=
+
+ifneq ($(findstring -sync,$(CFG)),)
+ CPPFLAGS += -DUSE_SYNC_DNS
+else ifneq ($(findstring -ares,$(CFG)),)
+ LIBCARES_PATH ?= $(PROOT)/../c-ares
+ CPPFLAGS += -DUSE_ARES
+ CPPFLAGS += -I"$(LIBCARES_PATH)/include"
+ _LDFLAGS += -L"$(LIBCARES_PATH)/lib"
+ _LIBS += -lcares
+endif
+
+ifneq ($(findstring -rtmp,$(CFG)),)
+ LIBRTMP_PATH ?= $(PROOT)/../librtmp
+ CPPFLAGS += -DUSE_LIBRTMP
+ CPPFLAGS += -I"$(LIBRTMP_PATH)"
+ _LDFLAGS += -L"$(LIBRTMP_PATH)/librtmp"
+ _LIBS += -lrtmp -lwinmm
+ ZLIB := 1
+endif
+
+ifneq ($(findstring -ssh2,$(CFG)),)
+ LIBSSH2_PATH ?= $(PROOT)/../libssh2
+ CPPFLAGS += -DUSE_LIBSSH2
+ CPPFLAGS += -I"$(LIBSSH2_PATH)/include"
+ _LDFLAGS += -L"$(LIBSSH2_PATH)/lib"
+ ifdef WIN32
+ _LDFLAGS += -L"$(LIBSSH2_PATH)/win32"
+ endif
+ _LIBS += -lssh2
+else ifneq ($(findstring -libssh,$(CFG)),)
+ LIBSSH_PATH ?= $(PROOT)/../libssh
+ CPPFLAGS += -DUSE_LIBSSH
+ CPPFLAGS += -I"$(LIBSSH_PATH)/include"
+ _LDFLAGS += -L"$(LIBSSH_PATH)/lib"
+ _LIBS += -lssh
+else ifneq ($(findstring -wolfssh,$(CFG)),)
+ WOLFSSH_PATH ?= $(PROOT)/../wolfssh
+ CPPFLAGS += -DUSE_WOLFSSH
+ CPPFLAGS += -I"$(WOLFSSH_PATH)/include"
+ _LDFLAGS += -L"$(WOLFSSH_PATH)/lib"
+ _LIBS += -lwolfssh
+endif
+
+ifneq ($(findstring -ssl,$(CFG)),)
+ OPENSSL_PATH ?= $(PROOT)/../openssl
+ CPPFLAGS += -DUSE_OPENSSL
+ CPPFLAGS += -DCURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG
+ OPENSSL_INCLUDE ?= $(OPENSSL_PATH)/include
+ OPENSSL_LIBPATH ?= $(OPENSSL_PATH)/lib
+ CPPFLAGS += -I"$(OPENSSL_INCLUDE)"
+ _LDFLAGS += -L"$(OPENSSL_LIBPATH)"
+ OPENSSL_LIBS ?= -lssl -lcrypto
+ _LIBS += $(OPENSSL_LIBS)
+
+ ifneq ($(findstring -srp,$(CFG)),)
+ ifneq ($(wildcard $(OPENSSL_INCLUDE)/openssl/srp.h),)
+ # OpenSSL 1.0.1 and later.
+ CPPFLAGS += -DHAVE_OPENSSL_SRP -DUSE_TLS_SRP
+ endif
+ endif
+ SSLLIBS += 1
+endif
+ifneq ($(findstring -wolfssl,$(CFG)),)
+ WOLFSSL_PATH ?= $(PROOT)/../wolfssl
+ CPPFLAGS += -DUSE_WOLFSSL
+ CPPFLAGS += -DSIZEOF_LONG_LONG=8
+ CPPFLAGS += -I"$(WOLFSSL_PATH)/include"
+ _LDFLAGS += -L"$(WOLFSSL_PATH)/lib"
+ _LIBS += -lwolfssl
+ SSLLIBS += 1
+endif
+ifneq ($(findstring -mbedtls,$(CFG)),)
+ MBEDTLS_PATH ?= $(PROOT)/../mbedtls
+ CPPFLAGS += -DUSE_MBEDTLS
+ CPPFLAGS += -I"$(MBEDTLS_PATH)/include"
+ _LDFLAGS += -L"$(MBEDTLS_PATH)/lib"
+ _LIBS += -lmbedtls -lmbedx509 -lmbedcrypto
+ SSLLIBS += 1
+endif
+ifneq ($(findstring -schannel,$(CFG)),)
+ CPPFLAGS += -DUSE_SCHANNEL
+ SSLLIBS += 1
+endif
+
+ifneq ($(findstring -nghttp2,$(CFG)),)
+ NGHTTP2_PATH ?= $(PROOT)/../nghttp2
+ CPPFLAGS += -DUSE_NGHTTP2
+ CPPFLAGS += -I"$(NGHTTP2_PATH)/include"
+ _LDFLAGS += -L"$(NGHTTP2_PATH)/lib"
+ _LIBS += -lnghttp2
+endif
+
+ifeq ($(findstring -nghttp3,$(CFG))$(findstring -ngtcp2,$(CFG)),-nghttp3-ngtcp2)
+ NGHTTP3_PATH ?= $(PROOT)/../nghttp3
+ CPPFLAGS += -DUSE_NGHTTP3
+ CPPFLAGS += -I"$(NGHTTP3_PATH)/include"
+ _LDFLAGS += -L"$(NGHTTP3_PATH)/lib"
+ _LIBS += -lnghttp3
+
+ NGTCP2_PATH ?= $(PROOT)/../ngtcp2
+ CPPFLAGS += -DUSE_NGTCP2
+ CPPFLAGS += -I"$(NGTCP2_PATH)/include"
+ _LDFLAGS += -L"$(NGTCP2_PATH)/lib"
+
+ NGTCP2_LIBS ?=
+ ifeq ($(NGTCP2_LIBS),)
+ ifneq ($(findstring -ssl,$(CFG)),)
+ ifneq ($(wildcard $(OPENSSL_INCLUDE)/openssl/aead.h),)
+ NGTCP2_LIBS := -lngtcp2_crypto_boringssl
+ else # including libressl
+ NGTCP2_LIBS := -lngtcp2_crypto_quictls
+ endif
+ else ifneq ($(findstring -wolfssl,$(CFG)),)
+ NGTCP2_LIBS := -lngtcp2_crypto_wolfssl
+ endif
+ endif
+
+ _LIBS += -lngtcp2 $(NGTCP2_LIBS)
+endif
+
+ifneq ($(findstring -zlib,$(CFG))$(ZLIB),)
+ ZLIB_PATH ?= $(PROOT)/../zlib
+ # These CPPFLAGS are also required when compiling the curl tool via 'src'.
+ CPPFLAGS += -DHAVE_LIBZ
+ CPPFLAGS += -I"$(ZLIB_PATH)/include"
+ _LDFLAGS += -L"$(ZLIB_PATH)/lib"
+ ZLIB_LIBS ?= -lz
+ _LIBS += $(ZLIB_LIBS)
+ ZLIB := 1
+endif
+ifneq ($(findstring -zstd,$(CFG)),)
+ ZSTD_PATH ?= $(PROOT)/../zstd
+ CPPFLAGS += -DHAVE_ZSTD
+ CPPFLAGS += -I"$(ZSTD_PATH)/include"
+ _LDFLAGS += -L"$(ZSTD_PATH)/lib"
+ ZSTD_LIBS ?= -lzstd
+ _LIBS += $(ZSTD_LIBS)
+endif
+ifneq ($(findstring -brotli,$(CFG)),)
+ BROTLI_PATH ?= $(PROOT)/../brotli
+ CPPFLAGS += -DHAVE_BROTLI
+ CPPFLAGS += -I"$(BROTLI_PATH)/include"
+ _LDFLAGS += -L"$(BROTLI_PATH)/lib"
+ BROTLI_LIBS ?= -lbrotlidec -lbrotlicommon
+ _LIBS += $(BROTLI_LIBS)
+endif
+ifneq ($(findstring -gsasl,$(CFG)),)
+ LIBGSASL_PATH ?= $(PROOT)/../gsasl
+ CPPFLAGS += -DUSE_GSASL
+ CPPFLAGS += -I"$(LIBGSASL_PATH)/include"
+ _LDFLAGS += -L"$(LIBGSASL_PATH)/lib"
+ _LIBS += -lgsasl
+endif
+
+ifneq ($(findstring -idn2,$(CFG)),)
+ LIBIDN2_PATH ?= $(PROOT)/../libidn2
+ CPPFLAGS += -DUSE_LIBIDN2
+ CPPFLAGS += -I"$(LIBIDN2_PATH)/include"
+ _LDFLAGS += -L"$(LIBIDN2_PATH)/lib"
+ _LIBS += -lidn2
+
+ifneq ($(findstring -psl,$(CFG)),)
+ LIBPSL_PATH ?= $(PROOT)/../libpsl
+ CPPFLAGS += -DUSE_LIBPSL
+ CPPFLAGS += -I"$(LIBPSL_PATH)/include"
+ _LDFLAGS += -L"$(LIBPSL_PATH)/lib"
+ _LIBS += -lpsl
+endif
+else ifneq ($(findstring -winidn,$(CFG)),)
+ CPPFLAGS += -DUSE_WIN32_IDN
+ _LIBS += -lnormaliz
+endif
+
+ifneq ($(findstring -sspi,$(CFG)),)
+ ifdef WIN32
+ CPPFLAGS += -DUSE_WINDOWS_SSPI
+ endif
+endif
+ifneq ($(findstring -ipv6,$(CFG)),)
+ CPPFLAGS += -DENABLE_IPV6
+endif
+
+ifneq ($(findstring -watt,$(CFG))$(MSDOS),)
+ WATT_PATH ?= $(PROOT)/../watt
+ CPPFLAGS += -I"$(WATT_PATH)/inc"
+ _LDFLAGS += -L"$(WATT_PATH)/lib"
+ _LIBS += -lwatt
+endif
+
+ifdef WIN32
+ ifeq ($(findstring -lldap,$(LIBS)),)
+ _LIBS += -lwldap32
+ endif
+ _LIBS += -lws2_32 -lcrypt32 -lbcrypt
+endif
+
+ifneq ($(findstring 11,$(subst $(subst ,, ),,$(SSLLIBS))),)
+ CPPFLAGS += -DCURL_WITH_MULTI_SSL
+endif
+
+ifndef DYN
+ LDFLAGS += $(_LDFLAGS)
+ LIBS += $(_LIBS)
+endif
+
+### Common rules
+
+OBJ_DIR := $(TRIPLET)
+
+ifneq ($(findstring /sh,$(SHELL)),)
+DEL = rm -f $1
+COPY = -cp -afv $1 $2
+MKDIR = mkdir -p $1
+RMDIR = rm -fr $1
+WHICH = $(SHELL) -c "command -v $1"
+else
+DEL = -del 2>NUL /q /f $(subst /,\,$1)
+COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2)
+MKDIR = -md 2>NUL $(subst /,\,$1)
+RMDIR = -rd 2>NUL /q /s $(subst /,\,$1)
+WHICH = where $1
+endif
+
+all: $(TARGETS)
+
+$(OBJ_DIR):
+ -$(call MKDIR, $(OBJ_DIR))
+
+$(OBJ_DIR)/%.o: %.c
+ $(CC) -W -Wall $(CFLAGS) $(CPPFLAGS) -c $< -o $@
+
+$(OBJ_DIR)/%.res: %.rc
+ $(RC) -O coff $(RCFLAGS) -i $< -o $@
+
+clean:
+ @$(call DEL, $(TOCLEAN))
+ @$(RMDIR) $(OBJ_DIR)
+
+distclean vclean: clean
+ @$(call DEL, $(TARGETS) $(TOVCLEAN))
+
+### Local
+
+ifdef LOCAL
+
+CPPFLAGS += -DBUILDING_LIBCURL
+ifdef WIN32
+CPPFLAGS += -DCURL_STATICLIB
+endif
+
+### Sources and targets
+
+# Provides CSOURCES, HHEADERS, LIB_RCFILES
+include Makefile.inc
+
+vpath %.c vauth vquic vssh vtls
+
+libcurl_a_LIBRARY := libcurl.a
+ifdef WIN32
+CURL_DLL_SUFFIX ?=
+libcurl_dll_LIBRARY := libcurl$(CURL_DLL_SUFFIX).dll
+libcurl_dll_a_LIBRARY := libcurl.dll.a
+ifeq ($(findstring -trackmem,$(CFG)),)
+CURL_LDFLAGS_LIB += $(PROOT)/libcurl.def
+endif
+ifdef MAP
+libcurl_map_LIBRARY := libcurl$(CURL_DLL_SUFFIX).map
+CURL_LDFLAGS_LIB += -Wl,-Map,$(libcurl_map_LIBRARY)
+endif
+endif
+
+TARGETS := $(libcurl_a_LIBRARY) $(libcurl_dll_LIBRARY)
+
+libcurl_a_OBJECTS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(notdir $(strip $(CSOURCES))))
+libcurl_a_DEPENDENCIES := $(strip $(CSOURCES) $(HHEADERS))
+ifdef WIN32
+libcurl_dll_OBJECTS := $(libcurl_a_OBJECTS)
+libcurl_dll_OBJECTS += $(patsubst %.rc,$(OBJ_DIR)/%.res,$(strip $(LIB_RCFILES)))
+endif
+
+TOCLEAN := $(libcurl_dll_OBJECTS)
+TOVCLEAN := $(libcurl_dll_LIBRARY:.dll=.def) $(libcurl_dll_a_LIBRARY) $(libcurl_map_LIBRARY)
+
+### Rules
+
+$(libcurl_a_LIBRARY): $(libcurl_a_OBJECTS) $(libcurl_a_DEPENDENCIES)
+ @$(call DEL, $@)
+ $(AR) rcs $@ $(libcurl_a_OBJECTS)
+
+$(libcurl_dll_LIBRARY): $(libcurl_dll_OBJECTS)
+ $(CC) $(LDFLAGS) -shared $(CURL_LDFLAGS_LIB) -o $@ $(libcurl_dll_OBJECTS) $(LIBS) \
+ -Wl,--output-def,$(@:.dll=.def),--out-implib,$(libcurl_dll_a_LIBRARY)
+
+all: $(OBJ_DIR) $(TARGETS)
+endif
diff --git a/iotdb-client/odbc/deps/curl-src/lib/Makefile.soname b/iotdb-client/odbc/deps/curl-src/lib/Makefile.soname
new file mode 100644
index 0000000000000..02e003a8aa1b0
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/Makefile.soname
@@ -0,0 +1,42 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+
+VERSIONCHANGE=12
+VERSIONADD=0
+VERSIONDEL=8
+
+# libtool version:
+VERSIONINFO=-version-info $(VERSIONCHANGE):$(VERSIONADD):$(VERSIONDEL)
+# This flag accepts an argument of the form current[:revision[:age]]. So,
+# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to
+# 1.
+#
+# Here's the simplified rule guide on how to change -version-info:
+# (current version is C:R:A)
+#
+# 1. if there are only source changes, use C:R+1:A
+# 2. if interfaces were added use C+1:0:A+1
+# 3. if interfaces were removed, then use C+1:0:0
+#
+# For the full guide on libcurl ABI rules, see docs/libcurl/ABI
diff --git a/iotdb-client/odbc/deps/curl-src/lib/altsvc.c b/iotdb-client/odbc/deps/curl-src/lib/altsvc.c
new file mode 100644
index 0000000000000..22b0b69c77f62
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/altsvc.c
@@ -0,0 +1,719 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+/*
+ * The Alt-Svc: header is defined in RFC 7838:
+ * https://datatracker.ietf.org/doc/html/rfc7838
+ */
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_ALTSVC)
+#include
+#include "urldata.h"
+#include "altsvc.h"
+#include "curl_get_line.h"
+#include "strcase.h"
+#include "parsedate.h"
+#include "sendf.h"
+#include "warnless.h"
+#include "fopen.h"
+#include "rename.h"
+#include "strdup.h"
+#include "inet_pton.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define MAX_ALTSVC_LINE 4095
+#define MAX_ALTSVC_DATELENSTR "64"
+#define MAX_ALTSVC_DATELEN 64
+#define MAX_ALTSVC_HOSTLENSTR "512"
+#define MAX_ALTSVC_HOSTLEN 512
+#define MAX_ALTSVC_ALPNLENSTR "10"
+#define MAX_ALTSVC_ALPNLEN 10
+
+#define H3VERSION "h3"
+
+static enum alpnid alpn2alpnid(char *name)
+{
+ if(strcasecompare(name, "h1"))
+ return ALPN_h1;
+ if(strcasecompare(name, "h2"))
+ return ALPN_h2;
+ if(strcasecompare(name, H3VERSION))
+ return ALPN_h3;
+ return ALPN_none; /* unknown, probably rubbish input */
+}
+
+/* Given the ALPN ID, return the name */
+const char *Curl_alpnid2str(enum alpnid id)
+{
+ switch(id) {
+ case ALPN_h1:
+ return "h1";
+ case ALPN_h2:
+ return "h2";
+ case ALPN_h3:
+ return H3VERSION;
+ default:
+ return ""; /* bad */
+ }
+}
+
+
+static void altsvc_free(struct altsvc *as)
+{
+ free(as->src.host);
+ free(as->dst.host);
+ free(as);
+}
+
+static struct altsvc *altsvc_createid(const char *srchost,
+ const char *dsthost,
+ enum alpnid srcalpnid,
+ enum alpnid dstalpnid,
+ unsigned int srcport,
+ unsigned int dstport)
+{
+ struct altsvc *as = calloc(sizeof(struct altsvc), 1);
+ size_t hlen;
+ size_t dlen;
+ if(!as)
+ return NULL;
+ hlen = strlen(srchost);
+ dlen = strlen(dsthost);
+ DEBUGASSERT(hlen);
+ DEBUGASSERT(dlen);
+ if(!hlen || !dlen)
+ /* bad input */
+ return NULL;
+ if((hlen > 2) && srchost[0] == '[') {
+ /* IPv6 address, strip off brackets */
+ srchost++;
+ hlen -= 2;
+ }
+ else if(srchost[hlen - 1] == '.')
+ /* strip off trailing dot */
+ hlen--;
+ if((dlen > 2) && dsthost[0] == '[') {
+ /* IPv6 address, strip off brackets */
+ dsthost++;
+ dlen -= 2;
+ }
+
+ as->src.host = Curl_memdup(srchost, hlen + 1);
+ if(!as->src.host)
+ goto error;
+ as->src.host[hlen] = 0;
+
+ as->dst.host = Curl_memdup(dsthost, dlen + 1);
+ if(!as->dst.host)
+ goto error;
+ as->dst.host[dlen] = 0;
+
+ as->src.alpnid = srcalpnid;
+ as->dst.alpnid = dstalpnid;
+ as->src.port = curlx_ultous(srcport);
+ as->dst.port = curlx_ultous(dstport);
+
+ return as;
+error:
+ altsvc_free(as);
+ return NULL;
+}
+
+static struct altsvc *altsvc_create(char *srchost,
+ char *dsthost,
+ char *srcalpn,
+ char *dstalpn,
+ unsigned int srcport,
+ unsigned int dstport)
+{
+ enum alpnid dstalpnid = alpn2alpnid(dstalpn);
+ enum alpnid srcalpnid = alpn2alpnid(srcalpn);
+ if(!srcalpnid || !dstalpnid)
+ return NULL;
+ return altsvc_createid(srchost, dsthost, srcalpnid, dstalpnid,
+ srcport, dstport);
+}
+
+/* only returns SERIOUS errors */
+static CURLcode altsvc_add(struct altsvcinfo *asi, char *line)
+{
+ /* Example line:
+ h2 example.com 443 h3 shiny.example.com 8443 "20191231 10:00:00" 1
+ */
+ char srchost[MAX_ALTSVC_HOSTLEN + 1];
+ char dsthost[MAX_ALTSVC_HOSTLEN + 1];
+ char srcalpn[MAX_ALTSVC_ALPNLEN + 1];
+ char dstalpn[MAX_ALTSVC_ALPNLEN + 1];
+ char date[MAX_ALTSVC_DATELEN + 1];
+ unsigned int srcport;
+ unsigned int dstport;
+ unsigned int prio;
+ unsigned int persist;
+ int rc;
+
+ rc = sscanf(line,
+ "%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u "
+ "%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u "
+ "\"%" MAX_ALTSVC_DATELENSTR "[^\"]\" %u %u",
+ srcalpn, srchost, &srcport,
+ dstalpn, dsthost, &dstport,
+ date, &persist, &prio);
+ if(9 == rc) {
+ struct altsvc *as;
+ time_t expires = Curl_getdate_capped(date);
+ as = altsvc_create(srchost, dsthost, srcalpn, dstalpn, srcport, dstport);
+ if(as) {
+ as->expires = expires;
+ as->prio = prio;
+ as->persist = persist ? 1 : 0;
+ Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
+ }
+ }
+
+ return CURLE_OK;
+}
+
+/*
+ * Load alt-svc entries from the given file. The text based line-oriented file
+ * format is documented here: https://curl.se/docs/alt-svc.html
+ *
+ * This function only returns error on major problems that prevent alt-svc
+ * handling to work completely. It will ignore individual syntactical errors
+ * etc.
+ */
+static CURLcode altsvc_load(struct altsvcinfo *asi, const char *file)
+{
+ CURLcode result = CURLE_OK;
+ char *line = NULL;
+ FILE *fp;
+
+ /* we need a private copy of the file name so that the altsvc cache file
+ name survives an easy handle reset */
+ free(asi->filename);
+ asi->filename = strdup(file);
+ if(!asi->filename)
+ return CURLE_OUT_OF_MEMORY;
+
+ fp = fopen(file, FOPEN_READTEXT);
+ if(fp) {
+ line = malloc(MAX_ALTSVC_LINE);
+ if(!line)
+ goto fail;
+ while(Curl_get_line(line, MAX_ALTSVC_LINE, fp)) {
+ char *lineptr = line;
+ while(*lineptr && ISBLANK(*lineptr))
+ lineptr++;
+ if(*lineptr == '#')
+ /* skip commented lines */
+ continue;
+
+ altsvc_add(asi, lineptr);
+ }
+ free(line); /* free the line buffer */
+ fclose(fp);
+ }
+ return result;
+
+fail:
+ Curl_safefree(asi->filename);
+ free(line);
+ fclose(fp);
+ return CURLE_OUT_OF_MEMORY;
+}
+
+/*
+ * Write this single altsvc entry to a single output line
+ */
+
+static CURLcode altsvc_out(struct altsvc *as, FILE *fp)
+{
+ struct tm stamp;
+ const char *dst6_pre = "";
+ const char *dst6_post = "";
+ const char *src6_pre = "";
+ const char *src6_post = "";
+ CURLcode result = Curl_gmtime(as->expires, &stamp);
+ if(result)
+ return result;
+#ifdef ENABLE_IPV6
+ else {
+ char ipv6_unused[16];
+ if(1 == Curl_inet_pton(AF_INET6, as->dst.host, ipv6_unused)) {
+ dst6_pre = "[";
+ dst6_post = "]";
+ }
+ if(1 == Curl_inet_pton(AF_INET6, as->src.host, ipv6_unused)) {
+ src6_pre = "[";
+ src6_post = "]";
+ }
+ }
+#endif
+ fprintf(fp,
+ "%s %s%s%s %u "
+ "%s %s%s%s %u "
+ "\"%d%02d%02d "
+ "%02d:%02d:%02d\" "
+ "%u %d\n",
+ Curl_alpnid2str(as->src.alpnid),
+ src6_pre, as->src.host, src6_post,
+ as->src.port,
+
+ Curl_alpnid2str(as->dst.alpnid),
+ dst6_pre, as->dst.host, dst6_post,
+ as->dst.port,
+
+ stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday,
+ stamp.tm_hour, stamp.tm_min, stamp.tm_sec,
+ as->persist, as->prio);
+ return CURLE_OK;
+}
+
+/* ---- library-wide functions below ---- */
+
+/*
+ * Curl_altsvc_init() creates a new altsvc cache.
+ * It returns the new instance or NULL if something goes wrong.
+ */
+struct altsvcinfo *Curl_altsvc_init(void)
+{
+ struct altsvcinfo *asi = calloc(sizeof(struct altsvcinfo), 1);
+ if(!asi)
+ return NULL;
+ Curl_llist_init(&asi->list, NULL);
+
+ /* set default behavior */
+ asi->flags = CURLALTSVC_H1
+#ifdef USE_HTTP2
+ | CURLALTSVC_H2
+#endif
+#ifdef ENABLE_QUIC
+ | CURLALTSVC_H3
+#endif
+ ;
+ return asi;
+}
+
+/*
+ * Curl_altsvc_load() loads alt-svc from file.
+ */
+CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file)
+{
+ CURLcode result;
+ DEBUGASSERT(asi);
+ result = altsvc_load(asi, file);
+ return result;
+}
+
+/*
+ * Curl_altsvc_ctrl() passes on the external bitmask.
+ */
+CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl)
+{
+ DEBUGASSERT(asi);
+ if(!ctrl)
+ /* unexpected */
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ asi->flags = ctrl;
+ return CURLE_OK;
+}
+
+/*
+ * Curl_altsvc_cleanup() frees an altsvc cache instance and all associated
+ * resources.
+ */
+void Curl_altsvc_cleanup(struct altsvcinfo **altsvcp)
+{
+ struct Curl_llist_element *e;
+ struct Curl_llist_element *n;
+ if(*altsvcp) {
+ struct altsvcinfo *altsvc = *altsvcp;
+ for(e = altsvc->list.head; e; e = n) {
+ struct altsvc *as = e->ptr;
+ n = e->next;
+ altsvc_free(as);
+ }
+ free(altsvc->filename);
+ free(altsvc);
+ *altsvcp = NULL; /* clear the pointer */
+ }
+}
+
+/*
+ * Curl_altsvc_save() writes the altsvc cache to a file.
+ */
+CURLcode Curl_altsvc_save(struct Curl_easy *data,
+ struct altsvcinfo *altsvc, const char *file)
+{
+ struct Curl_llist_element *e;
+ struct Curl_llist_element *n;
+ CURLcode result = CURLE_OK;
+ FILE *out;
+ char *tempstore = NULL;
+
+ if(!altsvc)
+ /* no cache activated */
+ return CURLE_OK;
+
+ /* if not new name is given, use the one we stored from the load */
+ if(!file && altsvc->filename)
+ file = altsvc->filename;
+
+ if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file || !file[0])
+ /* marked as read-only, no file or zero length file name */
+ return CURLE_OK;
+
+ result = Curl_fopen(data, file, &out, &tempstore);
+ if(!result) {
+ fputs("# Your alt-svc cache. https://curl.se/docs/alt-svc.html\n"
+ "# This file was generated by libcurl! Edit at your own risk.\n",
+ out);
+ for(e = altsvc->list.head; e; e = n) {
+ struct altsvc *as = e->ptr;
+ n = e->next;
+ result = altsvc_out(as, out);
+ if(result)
+ break;
+ }
+ fclose(out);
+ if(!result && tempstore && Curl_rename(tempstore, file))
+ result = CURLE_WRITE_ERROR;
+
+ if(result && tempstore)
+ unlink(tempstore);
+ }
+ free(tempstore);
+ return result;
+}
+
+static CURLcode getalnum(const char **ptr, char *alpnbuf, size_t buflen)
+{
+ size_t len;
+ const char *protop;
+ const char *p = *ptr;
+ while(*p && ISBLANK(*p))
+ p++;
+ protop = p;
+ while(*p && !ISBLANK(*p) && (*p != ';') && (*p != '='))
+ p++;
+ len = p - protop;
+ *ptr = p;
+
+ if(!len || (len >= buflen))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ memcpy(alpnbuf, protop, len);
+ alpnbuf[len] = 0;
+ return CURLE_OK;
+}
+
+/* hostcompare() returns true if 'host' matches 'check'. The first host
+ * argument may have a trailing dot present that will be ignored.
+ */
+static bool hostcompare(const char *host, const char *check)
+{
+ size_t hlen = strlen(host);
+ size_t clen = strlen(check);
+
+ if(hlen && (host[hlen - 1] == '.'))
+ hlen--;
+ if(hlen != clen)
+ /* they can't match if they have different lengths */
+ return FALSE;
+ return strncasecompare(host, check, hlen);
+}
+
+/* altsvc_flush() removes all alternatives for this source origin from the
+ list */
+static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid,
+ const char *srchost, unsigned short srcport)
+{
+ struct Curl_llist_element *e;
+ struct Curl_llist_element *n;
+ for(e = asi->list.head; e; e = n) {
+ struct altsvc *as = e->ptr;
+ n = e->next;
+ if((srcalpnid == as->src.alpnid) &&
+ (srcport == as->src.port) &&
+ hostcompare(srchost, as->src.host)) {
+ Curl_llist_remove(&asi->list, e, NULL);
+ altsvc_free(as);
+ }
+ }
+}
+
+#ifdef DEBUGBUILD
+/* to play well with debug builds, we can *set* a fixed time this will
+ return */
+static time_t altsvc_debugtime(void *unused)
+{
+ char *timestr = getenv("CURL_TIME");
+ (void)unused;
+ if(timestr) {
+ unsigned long val = strtol(timestr, NULL, 10);
+ return (time_t)val;
+ }
+ return time(NULL);
+}
+#undef time
+#define time(x) altsvc_debugtime(x)
+#endif
+
+#define ISNEWLINE(x) (((x) == '\n') || (x) == '\r')
+
+/*
+ * Curl_altsvc_parse() takes an incoming alt-svc response header and stores
+ * the data correctly in the cache.
+ *
+ * 'value' points to the header *value*. That's contents to the right of the
+ * header name.
+ *
+ * Currently this function rejects invalid data without returning an error.
+ * Invalid host name, port number will result in the specific alternative
+ * being rejected. Unknown protocols are skipped.
+ */
+CURLcode Curl_altsvc_parse(struct Curl_easy *data,
+ struct altsvcinfo *asi, const char *value,
+ enum alpnid srcalpnid, const char *srchost,
+ unsigned short srcport)
+{
+ const char *p = value;
+ size_t len;
+ char namebuf[MAX_ALTSVC_HOSTLEN] = "";
+ char alpnbuf[MAX_ALTSVC_ALPNLEN] = "";
+ struct altsvc *as;
+ unsigned short dstport = srcport; /* the same by default */
+ CURLcode result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
+ size_t entries = 0;
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+ (void)data;
+#endif
+ if(result) {
+ infof(data, "Excessive alt-svc header, ignoring.");
+ return CURLE_OK;
+ }
+
+ DEBUGASSERT(asi);
+
+ /* "clear" is a magic keyword */
+ if(strcasecompare(alpnbuf, "clear")) {
+ /* Flush cached alternatives for this source origin */
+ altsvc_flush(asi, srcalpnid, srchost, srcport);
+ return CURLE_OK;
+ }
+
+ do {
+ if(*p == '=') {
+ /* [protocol]="[host][:port]" */
+ enum alpnid dstalpnid = alpn2alpnid(alpnbuf); /* the same by default */
+ p++;
+ if(*p == '\"') {
+ const char *dsthost = "";
+ const char *value_ptr;
+ char option[32];
+ unsigned long num;
+ char *end_ptr;
+ bool quoted = FALSE;
+ time_t maxage = 24 * 3600; /* default is 24 hours */
+ bool persist = FALSE;
+ bool valid = TRUE;
+ p++;
+ if(*p != ':') {
+ /* host name starts here */
+ const char *hostp = p;
+ if(*p == '[') {
+ /* pass all valid IPv6 letters - does not handle zone id */
+ len = strspn(++p, "0123456789abcdefABCDEF:.");
+ if(p[len] != ']')
+ /* invalid host syntax, bail out */
+ break;
+ /* we store the IPv6 numerical address *with* brackets */
+ len += 2;
+ p = &p[len-1];
+ }
+ else {
+ while(*p && (ISALNUM(*p) || (*p == '.') || (*p == '-')))
+ p++;
+ len = p - hostp;
+ }
+ if(!len || (len >= MAX_ALTSVC_HOSTLEN)) {
+ infof(data, "Excessive alt-svc host name, ignoring.");
+ valid = FALSE;
+ }
+ else {
+ memcpy(namebuf, hostp, len);
+ namebuf[len] = 0;
+ dsthost = namebuf;
+ }
+ }
+ else {
+ /* no destination name, use source host */
+ dsthost = srchost;
+ }
+ if(*p == ':') {
+ unsigned long port = 0;
+ p++;
+ if(ISDIGIT(*p))
+ /* a port number */
+ port = strtoul(p, &end_ptr, 10);
+ else
+ end_ptr = (char *)p; /* not left uninitialized */
+ if(!port || port > USHRT_MAX || end_ptr == p || *end_ptr != '\"') {
+ infof(data, "Unknown alt-svc port number, ignoring.");
+ valid = FALSE;
+ }
+ else {
+ dstport = curlx_ultous(port);
+ p = end_ptr;
+ }
+ }
+ if(*p++ != '\"')
+ break;
+ /* Handle the optional 'ma' and 'persist' flags. Unknown flags
+ are skipped. */
+ for(;;) {
+ while(ISBLANK(*p))
+ p++;
+ if(*p != ';')
+ break;
+ p++; /* pass the semicolon */
+ if(!*p || ISNEWLINE(*p))
+ break;
+ result = getalnum(&p, option, sizeof(option));
+ if(result) {
+ /* skip option if name is too long */
+ option[0] = '\0';
+ }
+ while(*p && ISBLANK(*p))
+ p++;
+ if(*p != '=')
+ return CURLE_OK;
+ p++;
+ while(*p && ISBLANK(*p))
+ p++;
+ if(!*p)
+ return CURLE_OK;
+ if(*p == '\"') {
+ /* quoted value */
+ p++;
+ quoted = TRUE;
+ }
+ value_ptr = p;
+ if(quoted) {
+ while(*p && *p != '\"')
+ p++;
+ if(!*p++)
+ return CURLE_OK;
+ }
+ else {
+ while(*p && !ISBLANK(*p) && *p!= ';' && *p != ',')
+ p++;
+ }
+ num = strtoul(value_ptr, &end_ptr, 10);
+ if((end_ptr != value_ptr) && (num < ULONG_MAX)) {
+ if(strcasecompare("ma", option))
+ maxage = num;
+ else if(strcasecompare("persist", option) && (num == 1))
+ persist = TRUE;
+ }
+ }
+ if(dstalpnid && valid) {
+ if(!entries++)
+ /* Flush cached alternatives for this source origin, if any - when
+ this is the first entry of the line. */
+ altsvc_flush(asi, srcalpnid, srchost, srcport);
+
+ as = altsvc_createid(srchost, dsthost,
+ srcalpnid, dstalpnid,
+ srcport, dstport);
+ if(as) {
+ /* The expires time also needs to take the Age: value (if any) into
+ account. [See RFC 7838 section 3.1] */
+ as->expires = maxage + time(NULL);
+ as->persist = persist;
+ Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
+ infof(data, "Added alt-svc: %s:%d over %s", dsthost, dstport,
+ Curl_alpnid2str(dstalpnid));
+ }
+ }
+ }
+ else
+ break;
+ /* after the double quote there can be a comma if there's another
+ string or a semicolon if no more */
+ if(*p == ',') {
+ /* comma means another alternative is presented */
+ p++;
+ result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
+ if(result)
+ break;
+ }
+ }
+ else
+ break;
+ } while(*p && (*p != ';') && (*p != '\n') && (*p != '\r'));
+
+ return CURLE_OK;
+}
+
+/*
+ * Return TRUE on a match
+ */
+bool Curl_altsvc_lookup(struct altsvcinfo *asi,
+ enum alpnid srcalpnid, const char *srchost,
+ int srcport,
+ struct altsvc **dstentry,
+ const int versions) /* one or more bits */
+{
+ struct Curl_llist_element *e;
+ struct Curl_llist_element *n;
+ time_t now = time(NULL);
+ DEBUGASSERT(asi);
+ DEBUGASSERT(srchost);
+ DEBUGASSERT(dstentry);
+
+ for(e = asi->list.head; e; e = n) {
+ struct altsvc *as = e->ptr;
+ n = e->next;
+ if(as->expires < now) {
+ /* an expired entry, remove */
+ Curl_llist_remove(&asi->list, e, NULL);
+ altsvc_free(as);
+ continue;
+ }
+ if((as->src.alpnid == srcalpnid) &&
+ hostcompare(srchost, as->src.host) &&
+ (as->src.port == srcport) &&
+ (versions & as->dst.alpnid)) {
+ /* match */
+ *dstentry = as;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_ALTSVC */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/altsvc.h b/iotdb-client/odbc/deps/curl-src/lib/altsvc.h
new file mode 100644
index 0000000000000..7fea1434a543a
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/altsvc.h
@@ -0,0 +1,81 @@
+#ifndef HEADER_CURL_ALTSVC_H
+#define HEADER_CURL_ALTSVC_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_ALTSVC)
+#include
+#include "llist.h"
+
+enum alpnid {
+ ALPN_none = 0,
+ ALPN_h1 = CURLALTSVC_H1,
+ ALPN_h2 = CURLALTSVC_H2,
+ ALPN_h3 = CURLALTSVC_H3
+};
+
+struct althost {
+ char *host;
+ unsigned short port;
+ enum alpnid alpnid;
+};
+
+struct altsvc {
+ struct althost src;
+ struct althost dst;
+ time_t expires;
+ bool persist;
+ int prio;
+ struct Curl_llist_element node;
+};
+
+struct altsvcinfo {
+ char *filename;
+ struct Curl_llist list; /* list of entries */
+ long flags; /* the publicly set bitmask */
+};
+
+const char *Curl_alpnid2str(enum alpnid id);
+struct altsvcinfo *Curl_altsvc_init(void);
+CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file);
+CURLcode Curl_altsvc_save(struct Curl_easy *data,
+ struct altsvcinfo *asi, const char *file);
+CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl);
+void Curl_altsvc_cleanup(struct altsvcinfo **altsvc);
+CURLcode Curl_altsvc_parse(struct Curl_easy *data,
+ struct altsvcinfo *altsvc, const char *value,
+ enum alpnid srcalpn, const char *srchost,
+ unsigned short srcport);
+bool Curl_altsvc_lookup(struct altsvcinfo *asi,
+ enum alpnid srcalpnid, const char *srchost,
+ int srcport,
+ struct altsvc **dstentry,
+ const int versions); /* CURLALTSVC_H* bits */
+#else
+/* disabled */
+#define Curl_altsvc_save(a,b,c)
+#define Curl_altsvc_cleanup(x)
+#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_ALTSVC */
+#endif /* HEADER_CURL_ALTSVC_H */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/amigaos.c b/iotdb-client/odbc/deps/curl-src/lib/amigaos.c
new file mode 100644
index 0000000000000..139309b1162b3
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/amigaos.c
@@ -0,0 +1,247 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef __AMIGA__
+
+#include
+
+#include "hostip.h"
+#include "amigaos.h"
+
+#ifdef HAVE_PROTO_BSDSOCKET_H
+# if defined(__amigaos4__)
+# include
+# elif !defined(USE_AMISSL)
+# include
+# endif
+# ifdef __libnix__
+# include
+# endif
+#endif
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifdef HAVE_PROTO_BSDSOCKET_H
+
+#ifdef __amigaos4__
+/*
+ * AmigaOS 4.x specific code
+ */
+
+/*
+ * hostip4.c - Curl_ipv4_resolve_r() replacement code
+ *
+ * Logic that needs to be considered are the following build cases:
+ * - newlib networking
+ * - clib2 networking
+ * - direct bsdsocket.library networking (usually AmiSSL builds)
+ * Each with the threaded resolver enabled or not.
+ *
+ * With the threaded resolver enabled, try to use gethostbyname_r() where
+ * available, otherwise (re)open bsdsocket.library and fallback to
+ * gethostbyname().
+ */
+
+#include
+
+static struct SocketIFace *__CurlISocket = NULL;
+static uint32 SocketFeatures = 0;
+
+#define HAVE_BSDSOCKET_GETHOSTBYNAME_R 0x01
+#define HAVE_BSDSOCKET_GETADDRINFO 0x02
+
+CURLcode Curl_amiga_init(void)
+{
+ struct SocketIFace *ISocket;
+ struct Library *base = OpenLibrary("bsdsocket.library", 4);
+
+ if(base) {
+ ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL);
+ if(ISocket) {
+ ULONG enabled = 0;
+
+ SocketBaseTags(SBTM_SETVAL(SBTC_CAN_SHARE_LIBRARY_BASES), TRUE,
+ SBTM_GETREF(SBTC_HAVE_GETHOSTADDR_R_API), (ULONG)&enabled,
+ TAG_DONE);
+
+ if(enabled) {
+ SocketFeatures |= HAVE_BSDSOCKET_GETHOSTBYNAME_R;
+ }
+
+ __CurlISocket = ISocket;
+
+ atexit(Curl_amiga_cleanup);
+
+ return CURLE_OK;
+ }
+ CloseLibrary(base);
+ }
+
+ return CURLE_FAILED_INIT;
+}
+
+void Curl_amiga_cleanup(void)
+{
+ if(__CurlISocket) {
+ struct Library *base = __CurlISocket->Data.LibBase;
+ DropInterface((struct Interface *)__CurlISocket);
+ CloseLibrary(base);
+ __CurlISocket = NULL;
+ }
+}
+
+#ifdef CURLRES_AMIGA
+/*
+ * Because we need to handle the different cases in hostip4.c at run-time,
+ * not at compile-time, based on what was detected in Curl_amiga_init(),
+ * we replace it completely with our own as to not complicate the baseline
+ * code. Assumes malloc/calloc/free are thread safe because Curl_he2ai()
+ * allocates memory also.
+ */
+
+struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
+ int port)
+{
+ struct Curl_addrinfo *ai = NULL;
+ struct hostent *h;
+ struct SocketIFace *ISocket = __CurlISocket;
+
+ if(SocketFeatures & HAVE_BSDSOCKET_GETHOSTBYNAME_R) {
+ LONG h_errnop = 0;
+ struct hostent *buf;
+
+ buf = calloc(1, CURL_HOSTENT_SIZE);
+ if(buf) {
+ h = gethostbyname_r((STRPTR)hostname, buf,
+ (char *)buf + sizeof(struct hostent),
+ CURL_HOSTENT_SIZE - sizeof(struct hostent),
+ &h_errnop);
+ if(h) {
+ ai = Curl_he2ai(h, port);
+ }
+ free(buf);
+ }
+ }
+ else {
+ #ifdef CURLRES_THREADED
+ /* gethostbyname() is not thread safe, so we need to reopen bsdsocket
+ * on the thread's context
+ */
+ struct Library *base = OpenLibrary("bsdsocket.library", 4);
+ if(base) {
+ ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL);
+ if(ISocket) {
+ h = gethostbyname((STRPTR)hostname);
+ if(h) {
+ ai = Curl_he2ai(h, port);
+ }
+ DropInterface((struct Interface *)ISocket);
+ }
+ CloseLibrary(base);
+ }
+ #else
+ /* not using threaded resolver - safe to use this as-is */
+ h = gethostbyname(hostname);
+ if(h) {
+ ai = Curl_he2ai(h, port);
+ }
+ #endif
+ }
+
+ return ai;
+}
+#endif /* CURLRES_AMIGA */
+
+#ifdef USE_AMISSL
+#include
+int Curl_amiga_select(int nfds, fd_set *readfds, fd_set *writefds,
+ fd_set *errorfds, struct timeval *timeout)
+{
+ int r = WaitSelect(nfds, readfds, writefds, errorfds, timeout, 0);
+ /* Ensure Ctrl-C signal is actioned */
+ if((r == -1) && (SOCKERRNO == EINTR))
+ raise(SIGINT);
+ return r;
+}
+#endif /* USE_AMISSL */
+
+#elif !defined(USE_AMISSL) /* __amigaos4__ */
+/*
+ * Amiga OS3 specific code
+ */
+
+struct Library *SocketBase = NULL;
+extern int errno, h_errno;
+
+#ifdef __libnix__
+void __request(const char *msg);
+#else
+# define __request(msg) Printf(msg "\n\a")
+#endif
+
+void Curl_amiga_cleanup(void)
+{
+ if(SocketBase) {
+ CloseLibrary(SocketBase);
+ SocketBase = NULL;
+ }
+}
+
+CURLcode Curl_amiga_init(void)
+{
+ if(!SocketBase)
+ SocketBase = OpenLibrary("bsdsocket.library", 4);
+
+ if(!SocketBase) {
+ __request("No TCP/IP Stack running!");
+ return CURLE_FAILED_INIT;
+ }
+
+ if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno,
+ SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "curl",
+ TAG_DONE)) {
+ __request("SocketBaseTags ERROR");
+ return CURLE_FAILED_INIT;
+ }
+
+#ifndef __libnix__
+ atexit(Curl_amiga_cleanup);
+#endif
+
+ return CURLE_OK;
+}
+
+#ifdef __libnix__
+ADD2EXIT(Curl_amiga_cleanup, -50);
+#endif
+
+#endif /* !USE_AMISSL */
+
+#endif /* HAVE_PROTO_BSDSOCKET_H */
+
+#endif /* __AMIGA__ */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/amigaos.h b/iotdb-client/odbc/deps/curl-src/lib/amigaos.h
new file mode 100644
index 0000000000000..c99d963ececc5
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/amigaos.h
@@ -0,0 +1,41 @@
+#ifndef HEADER_CURL_AMIGAOS_H
+#define HEADER_CURL_AMIGAOS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if defined(__AMIGA__) && defined(HAVE_PROTO_BSDSOCKET_H) && \
+ (!defined(USE_AMISSL) || defined(__amigaos4__))
+
+CURLcode Curl_amiga_init(void);
+void Curl_amiga_cleanup(void);
+
+#else
+
+#define Curl_amiga_init() CURLE_OK
+#define Curl_amiga_cleanup() Curl_nop_stmt
+
+#endif
+
+#endif /* HEADER_CURL_AMIGAOS_H */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/arpa_telnet.h b/iotdb-client/odbc/deps/curl-src/lib/arpa_telnet.h
new file mode 100644
index 0000000000000..de1373800ce6e
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/arpa_telnet.h
@@ -0,0 +1,110 @@
+#ifndef HEADER_CURL_ARPA_TELNET_H
+#define HEADER_CURL_ARPA_TELNET_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#ifndef CURL_DISABLE_TELNET
+/*
+ * Telnet option defines. Add more here if in need.
+ */
+#define CURL_TELOPT_BINARY 0 /* binary 8bit data */
+#define CURL_TELOPT_ECHO 1 /* just echo! */
+#define CURL_TELOPT_SGA 3 /* Suppress Go Ahead */
+#define CURL_TELOPT_EXOPL 255 /* EXtended OPtions List */
+#define CURL_TELOPT_TTYPE 24 /* Terminal TYPE */
+#define CURL_TELOPT_NAWS 31 /* Negotiate About Window Size */
+#define CURL_TELOPT_XDISPLOC 35 /* X DISPlay LOCation */
+
+#define CURL_TELOPT_NEW_ENVIRON 39 /* NEW ENVIRONment variables */
+#define CURL_NEW_ENV_VAR 0
+#define CURL_NEW_ENV_VALUE 1
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+/*
+ * The telnet options represented as strings
+ */
+static const char * const telnetoptions[]=
+{
+ "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD",
+ "NAME", "STATUS", "TIMING MARK", "RCTE",
+ "NAOL", "NAOP", "NAOCRD", "NAOHTS",
+ "NAOHTD", "NAOFFD", "NAOVTS", "NAOVTD",
+ "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
+ "DE TERMINAL", "SUPDUP", "SUPDUP OUTPUT", "SEND LOCATION",
+ "TERM TYPE", "END OF RECORD", "TACACS UID", "OUTPUT MARKING",
+ "TTYLOC", "3270 REGIME", "X3 PAD", "NAWS",
+ "TERM SPEED", "LFLOW", "LINEMODE", "XDISPLOC",
+ "OLD-ENVIRON", "AUTHENTICATION", "ENCRYPT", "NEW-ENVIRON"
+};
+#endif
+
+#define CURL_TELOPT_MAXIMUM CURL_TELOPT_NEW_ENVIRON
+
+#define CURL_TELOPT_OK(x) ((x) <= CURL_TELOPT_MAXIMUM)
+#define CURL_TELOPT(x) telnetoptions[x]
+
+#define CURL_NTELOPTS 40
+
+/*
+ * First some defines
+ */
+#define CURL_xEOF 236 /* End Of File */
+#define CURL_SE 240 /* Sub negotiation End */
+#define CURL_NOP 241 /* No OPeration */
+#define CURL_DM 242 /* Data Mark */
+#define CURL_GA 249 /* Go Ahead, reverse the line */
+#define CURL_SB 250 /* SuBnegotiation */
+#define CURL_WILL 251 /* Our side WILL use this option */
+#define CURL_WONT 252 /* Our side WON'T use this option */
+#define CURL_DO 253 /* DO use this option! */
+#define CURL_DONT 254 /* DON'T use this option! */
+#define CURL_IAC 255 /* Interpret As Command */
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+/*
+ * Then those numbers represented as strings:
+ */
+static const char * const telnetcmds[]=
+{
+ "EOF", "SUSP", "ABORT", "EOR", "SE",
+ "NOP", "DMARK", "BRK", "IP", "AO",
+ "AYT", "EC", "EL", "GA", "SB",
+ "WILL", "WONT", "DO", "DONT", "IAC"
+};
+#endif
+
+#define CURL_TELCMD_MINIMUM CURL_xEOF /* the first one */
+#define CURL_TELCMD_MAXIMUM CURL_IAC /* surprise, 255 is the last one! ;-) */
+
+#define CURL_TELQUAL_IS 0
+#define CURL_TELQUAL_SEND 1
+#define CURL_TELQUAL_INFO 2
+#define CURL_TELQUAL_NAME 3
+
+#define CURL_TELCMD_OK(x) ( ((unsigned int)(x) >= CURL_TELCMD_MINIMUM) && \
+ ((unsigned int)(x) <= CURL_TELCMD_MAXIMUM) )
+#define CURL_TELCMD(x) telnetcmds[(x)-CURL_TELCMD_MINIMUM]
+
+#endif /* CURL_DISABLE_TELNET */
+
+#endif /* HEADER_CURL_ARPA_TELNET_H */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/asyn-ares.c b/iotdb-client/odbc/deps/curl-src/lib/asyn-ares.c
new file mode 100644
index 0000000000000..e73e41dab9fe3
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/asyn-ares.c
@@ -0,0 +1,939 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+/***********************************************************************
+ * Only for ares-enabled builds
+ * And only for functions that fulfill the asynch resolver backend API
+ * as defined in asyn.h, nothing else belongs in this file!
+ **********************************************************************/
+
+#ifdef CURLRES_ARES
+
+#include
+#ifdef HAVE_NETINET_IN_H
+#include
+#endif
+#ifdef HAVE_NETDB_H
+#include
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include
+#endif
+#ifdef __VMS
+#include
+#include
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "url.h"
+#include "multiif.h"
+#include "inet_pton.h"
+#include "connect.h"
+#include "select.h"
+#include "progress.h"
+#include "timediff.h"
+
+# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
+ defined(WIN32)
+# define CARES_STATICLIB
+# endif
+# include
+# include /* really old c-ares didn't include this by
+ itself */
+
+#if ARES_VERSION >= 0x010500
+/* c-ares 1.5.0 or later, the callback proto is modified */
+#define HAVE_CARES_CALLBACK_TIMEOUTS 1
+#endif
+
+#if ARES_VERSION >= 0x010601
+/* IPv6 supported since 1.6.1 */
+#define HAVE_CARES_IPV6 1
+#endif
+
+#if ARES_VERSION >= 0x010704
+#define HAVE_CARES_SERVERS_CSV 1
+#define HAVE_CARES_LOCAL_DEV 1
+#define HAVE_CARES_SET_LOCAL 1
+#endif
+
+#if ARES_VERSION >= 0x010b00
+#define HAVE_CARES_PORTS_CSV 1
+#endif
+
+#if ARES_VERSION >= 0x011000
+/* 1.16.0 or later has ares_getaddrinfo */
+#define HAVE_CARES_GETADDRINFO 1
+#endif
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+struct thread_data {
+ int num_pending; /* number of outstanding c-ares requests */
+ struct Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares
+ parts */
+ int last_status;
+#ifndef HAVE_CARES_GETADDRINFO
+ struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */
+#endif
+ char hostname[1];
+};
+
+/* How long we are willing to wait for additional parallel responses after
+ obtaining a "definitive" one. For old c-ares without getaddrinfo.
+
+ This is intended to equal the c-ares default timeout. cURL always uses that
+ default value. Unfortunately, c-ares doesn't expose its default timeout in
+ its API, but it is officially documented as 5 seconds.
+
+ See query_completed_cb() for an explanation of how this is used.
+ */
+#define HAPPY_EYEBALLS_DNS_TIMEOUT 5000
+
+#define CARES_TIMEOUT_PER_ATTEMPT 2000
+
+/*
+ * Curl_resolver_global_init() - the generic low-level asynchronous name
+ * resolve API. Called from curl_global_init() to initialize global resolver
+ * environment. Initializes ares library.
+ */
+int Curl_resolver_global_init(void)
+{
+#ifdef CARES_HAVE_ARES_LIBRARY_INIT
+ if(ares_library_init(ARES_LIB_INIT_ALL)) {
+ return CURLE_FAILED_INIT;
+ }
+#endif
+ return CURLE_OK;
+}
+
+/*
+ * Curl_resolver_global_cleanup()
+ *
+ * Called from curl_global_cleanup() to destroy global resolver environment.
+ * Deinitializes ares library.
+ */
+void Curl_resolver_global_cleanup(void)
+{
+#ifdef CARES_HAVE_ARES_LIBRARY_CLEANUP
+ ares_library_cleanup();
+#endif
+}
+
+
+static void sock_state_cb(void *data, ares_socket_t socket_fd,
+ int readable, int writable)
+{
+ struct Curl_easy *easy = data;
+ if(!readable && !writable) {
+ DEBUGASSERT(easy);
+ Curl_multi_closed(easy, socket_fd);
+ }
+}
+
+/*
+ * Curl_resolver_init()
+ *
+ * Called from curl_easy_init() -> Curl_open() to initialize resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure). Fills the passed pointer by the initialized ares_channel.
+ */
+CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver)
+{
+ int status;
+ struct ares_options options;
+ int optmask = ARES_OPT_SOCK_STATE_CB;
+ options.sock_state_cb = sock_state_cb;
+ options.sock_state_cb_data = easy;
+ options.timeout = CARES_TIMEOUT_PER_ATTEMPT;
+ optmask |= ARES_OPT_TIMEOUTMS;
+
+ status = ares_init_options((ares_channel*)resolver, &options, optmask);
+ if(status != ARES_SUCCESS) {
+ if(status == ARES_ENOMEM)
+ return CURLE_OUT_OF_MEMORY;
+ else
+ return CURLE_FAILED_INIT;
+ }
+ return CURLE_OK;
+ /* make sure that all other returns from this function should destroy the
+ ares channel before returning error! */
+}
+
+/*
+ * Curl_resolver_cleanup()
+ *
+ * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure). Destroys the ares channel.
+ */
+void Curl_resolver_cleanup(void *resolver)
+{
+ ares_destroy((ares_channel)resolver);
+}
+
+/*
+ * Curl_resolver_duphandle()
+ *
+ * Called from curl_easy_duphandle() to duplicate resolver URL-state specific
+ * environment ('resolver' member of the UrlState structure). Duplicates the
+ * 'from' ares channel and passes the resulting channel to the 'to' pointer.
+ */
+CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to, void *from)
+{
+ (void)from;
+ /*
+ * it would be better to call ares_dup instead, but right now
+ * it is not possible to set 'sock_state_cb_data' outside of
+ * ares_init_options
+ */
+ return Curl_resolver_init(easy, to);
+}
+
+static void destroy_async_data(struct Curl_async *async);
+
+/*
+ * Cancel all possibly still on-going resolves for this connection.
+ */
+void Curl_resolver_cancel(struct Curl_easy *data)
+{
+ DEBUGASSERT(data);
+ if(data->state.async.resolver)
+ ares_cancel((ares_channel)data->state.async.resolver);
+ destroy_async_data(&data->state.async);
+}
+
+/*
+ * We're equivalent to Curl_resolver_cancel() for the c-ares resolver. We
+ * never block.
+ */
+void Curl_resolver_kill(struct Curl_easy *data)
+{
+ /* We don't need to check the resolver state because we can be called safely
+ at any time and we always do the same thing. */
+ Curl_resolver_cancel(data);
+}
+
+/*
+ * destroy_async_data() cleans up async resolver data.
+ */
+static void destroy_async_data(struct Curl_async *async)
+{
+ if(async->tdata) {
+ struct thread_data *res = async->tdata;
+ if(res) {
+ if(res->temp_ai) {
+ Curl_freeaddrinfo(res->temp_ai);
+ res->temp_ai = NULL;
+ }
+ free(res);
+ }
+ async->tdata = NULL;
+ }
+}
+
+/*
+ * Curl_resolver_getsock() is called when someone from the outside world
+ * (using curl_multi_fdset()) wants to get our fd_set setup and we're talking
+ * with ares. The caller must make sure that this function is only called when
+ * we have a working ares channel.
+ *
+ * Returns: sockets-in-use-bitmap
+ */
+
+int Curl_resolver_getsock(struct Curl_easy *data,
+ curl_socket_t *socks)
+{
+ struct timeval maxtime;
+ struct timeval timebuf;
+ struct timeval *timeout;
+ long milli;
+ int max = ares_getsock((ares_channel)data->state.async.resolver,
+ (ares_socket_t *)socks, MAX_SOCKSPEREASYHANDLE);
+
+ maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
+ maxtime.tv_usec = 0;
+
+ timeout = ares_timeout((ares_channel)data->state.async.resolver, &maxtime,
+ &timebuf);
+ milli = (long)curlx_tvtoms(timeout);
+ if(milli == 0)
+ milli += 10;
+ Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
+
+ return max;
+}
+
+/*
+ * waitperform()
+ *
+ * 1) Ask ares what sockets it currently plays with, then
+ * 2) wait for the timeout period to check for action on ares' sockets.
+ * 3) tell ares to act on all the sockets marked as "with action"
+ *
+ * return number of sockets it worked on, or -1 on error
+ */
+
+static int waitperform(struct Curl_easy *data, timediff_t timeout_ms)
+{
+ int nfds;
+ int bitmask;
+ ares_socket_t socks[ARES_GETSOCK_MAXNUM];
+ struct pollfd pfd[ARES_GETSOCK_MAXNUM];
+ int i;
+ int num = 0;
+
+ bitmask = ares_getsock((ares_channel)data->state.async.resolver, socks,
+ ARES_GETSOCK_MAXNUM);
+
+ for(i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
+ pfd[i].events = 0;
+ pfd[i].revents = 0;
+ if(ARES_GETSOCK_READABLE(bitmask, i)) {
+ pfd[i].fd = socks[i];
+ pfd[i].events |= POLLRDNORM|POLLIN;
+ }
+ if(ARES_GETSOCK_WRITABLE(bitmask, i)) {
+ pfd[i].fd = socks[i];
+ pfd[i].events |= POLLWRNORM|POLLOUT;
+ }
+ if(pfd[i].events)
+ num++;
+ else
+ break;
+ }
+
+ if(num) {
+ nfds = Curl_poll(pfd, num, timeout_ms);
+ if(nfds < 0)
+ return -1;
+ }
+ else
+ nfds = 0;
+
+ if(!nfds)
+ /* Call ares_process() unconditionally here, even if we simply timed out
+ above, as otherwise the ares name resolve won't timeout! */
+ ares_process_fd((ares_channel)data->state.async.resolver, ARES_SOCKET_BAD,
+ ARES_SOCKET_BAD);
+ else {
+ /* move through the descriptors and ask for processing on them */
+ for(i = 0; i < num; i++)
+ ares_process_fd((ares_channel)data->state.async.resolver,
+ (pfd[i].revents & (POLLRDNORM|POLLIN))?
+ pfd[i].fd:ARES_SOCKET_BAD,
+ (pfd[i].revents & (POLLWRNORM|POLLOUT))?
+ pfd[i].fd:ARES_SOCKET_BAD);
+ }
+ return nfds;
+}
+
+/*
+ * Curl_resolver_is_resolved() is called repeatedly to check if a previous
+ * name resolve request has completed. It should also make sure to time-out if
+ * the operation seems to take too long.
+ *
+ * Returns normal CURLcode errors.
+ */
+CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
+ struct Curl_dns_entry **dns)
+{
+ struct thread_data *res = data->state.async.tdata;
+ CURLcode result = CURLE_OK;
+
+ DEBUGASSERT(dns);
+ *dns = NULL;
+
+ if(waitperform(data, 0) < 0)
+ return CURLE_UNRECOVERABLE_POLL;
+
+#ifndef HAVE_CARES_GETADDRINFO
+ /* Now that we've checked for any last minute results above, see if there are
+ any responses still pending when the EXPIRE_HAPPY_EYEBALLS_DNS timer
+ expires. */
+ if(res
+ && res->num_pending
+ /* This is only set to non-zero if the timer was started. */
+ && (res->happy_eyeballs_dns_time.tv_sec
+ || res->happy_eyeballs_dns_time.tv_usec)
+ && (Curl_timediff(Curl_now(), res->happy_eyeballs_dns_time)
+ >= HAPPY_EYEBALLS_DNS_TIMEOUT)) {
+ /* Remember that the EXPIRE_HAPPY_EYEBALLS_DNS timer is no longer
+ running. */
+ memset(
+ &res->happy_eyeballs_dns_time, 0, sizeof(res->happy_eyeballs_dns_time));
+
+ /* Cancel the raw c-ares request, which will fire query_completed_cb() with
+ ARES_ECANCELLED synchronously for all pending responses. This will
+ leave us with res->num_pending == 0, which is perfect for the next
+ block. */
+ ares_cancel((ares_channel)data->state.async.resolver);
+ DEBUGASSERT(res->num_pending == 0);
+ }
+#endif
+
+ if(res && !res->num_pending) {
+ (void)Curl_addrinfo_callback(data, res->last_status, res->temp_ai);
+ /* temp_ai ownership is moved to the connection, so we need not free-up
+ them */
+ res->temp_ai = NULL;
+
+ if(!data->state.async.dns)
+ result = Curl_resolver_error(data);
+ else
+ *dns = data->state.async.dns;
+
+ destroy_async_data(&data->state.async);
+ }
+
+ return result;
+}
+
+/*
+ * Curl_resolver_wait_resolv()
+ *
+ * Waits for a resolve to finish. This function should be avoided since using
+ * this risk getting the multi interface to "hang".
+ *
+ * 'entry' MUST be non-NULL.
+ *
+ * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved,
+ * CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
+ */
+CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data,
+ struct Curl_dns_entry **entry)
+{
+ CURLcode result = CURLE_OK;
+ timediff_t timeout;
+ struct curltime now = Curl_now();
+
+ DEBUGASSERT(entry);
+ *entry = NULL; /* clear on entry */
+
+ timeout = Curl_timeleft(data, &now, TRUE);
+ if(timeout < 0) {
+ /* already expired! */
+ connclose(data->conn, "Timed out before name resolve started");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+ if(!timeout)
+ timeout = CURL_TIMEOUT_RESOLVE * 1000; /* default name resolve timeout */
+
+ /* Wait for the name resolve query to complete. */
+ while(!result) {
+ struct timeval *tvp, tv, store;
+ int itimeout;
+ timediff_t timeout_ms;
+
+#if TIMEDIFF_T_MAX > INT_MAX
+ itimeout = (timeout > INT_MAX) ? INT_MAX : (int)timeout;
+#else
+ itimeout = (int)timeout;
+#endif
+
+ store.tv_sec = itimeout/1000;
+ store.tv_usec = (itimeout%1000)*1000;
+
+ tvp = ares_timeout((ares_channel)data->state.async.resolver, &store, &tv);
+
+ /* use the timeout period ares returned to us above if less than one
+ second is left, otherwise just use 1000ms to make sure the progress
+ callback gets called frequent enough */
+ if(!tvp->tv_sec)
+ timeout_ms = (timediff_t)(tvp->tv_usec/1000);
+ else
+ timeout_ms = 1000;
+
+ if(waitperform(data, timeout_ms) < 0)
+ return CURLE_UNRECOVERABLE_POLL;
+ result = Curl_resolver_is_resolved(data, entry);
+
+ if(result || data->state.async.done)
+ break;
+
+ if(Curl_pgrsUpdate(data))
+ result = CURLE_ABORTED_BY_CALLBACK;
+ else {
+ struct curltime now2 = Curl_now();
+ timediff_t timediff = Curl_timediff(now2, now); /* spent time */
+ if(timediff <= 0)
+ timeout -= 1; /* always deduct at least 1 */
+ else if(timediff > timeout)
+ timeout = -1;
+ else
+ timeout -= timediff;
+ now = now2; /* for next loop */
+ }
+ if(timeout < 0)
+ result = CURLE_OPERATION_TIMEDOUT;
+ }
+ if(result)
+ /* failure, so we cancel the ares operation */
+ ares_cancel((ares_channel)data->state.async.resolver);
+
+ /* Operation complete, if the lookup was successful we now have the entry
+ in the cache. */
+ if(entry)
+ *entry = data->state.async.dns;
+
+ if(result)
+ /* close the connection, since we can't return failure here without
+ cleaning up this connection properly. */
+ connclose(data->conn, "c-ares resolve failed");
+
+ return result;
+}
+
+#ifndef HAVE_CARES_GETADDRINFO
+
+/* Connects results to the list */
+static void compound_results(struct thread_data *res,
+ struct Curl_addrinfo *ai)
+{
+ if(!ai)
+ return;
+
+#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
+ if(res->temp_ai && res->temp_ai->ai_family == PF_INET6) {
+ /* We have results already, put the new IPv6 entries at the head of the
+ list. */
+ struct Curl_addrinfo *temp_ai_tail = res->temp_ai;
+
+ while(temp_ai_tail->ai_next)
+ temp_ai_tail = temp_ai_tail->ai_next;
+
+ temp_ai_tail->ai_next = ai;
+ }
+ else
+#endif /* CURLRES_IPV6 */
+ {
+ /* Add the new results to the list of old results. */
+ struct Curl_addrinfo *ai_tail = ai;
+ while(ai_tail->ai_next)
+ ai_tail = ai_tail->ai_next;
+
+ ai_tail->ai_next = res->temp_ai;
+ res->temp_ai = ai;
+ }
+}
+
+/*
+ * ares_query_completed_cb() is the callback that ares will call when
+ * the host query initiated by ares_gethostbyname() from Curl_getaddrinfo(),
+ * when using ares, is completed either successfully or with failure.
+ */
+static void query_completed_cb(void *arg, /* (struct connectdata *) */
+ int status,
+#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
+ int timeouts,
+#endif
+ struct hostent *hostent)
+{
+ struct Curl_easy *data = (struct Curl_easy *)arg;
+ struct thread_data *res;
+
+#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
+ (void)timeouts; /* ignored */
+#endif
+
+ if(ARES_EDESTRUCTION == status)
+ /* when this ares handle is getting destroyed, the 'arg' pointer may not
+ be valid so only defer it when we know the 'status' says its fine! */
+ return;
+
+ res = data->state.async.tdata;
+ if(res) {
+ res->num_pending--;
+
+ if(CURL_ASYNC_SUCCESS == status) {
+ struct Curl_addrinfo *ai = Curl_he2ai(hostent, data->state.async.port);
+ if(ai) {
+ compound_results(res, ai);
+ }
+ }
+ /* A successful result overwrites any previous error */
+ if(res->last_status != ARES_SUCCESS)
+ res->last_status = status;
+
+ /* If there are responses still pending, we presume they must be the
+ complementary IPv4 or IPv6 lookups that we started in parallel in
+ Curl_resolver_getaddrinfo() (for Happy Eyeballs). If we've got a
+ "definitive" response from one of a set of parallel queries, we need to
+ think about how long we're willing to wait for more responses. */
+ if(res->num_pending
+ /* Only these c-ares status values count as "definitive" for these
+ purposes. For example, ARES_ENODATA is what we expect when there is
+ no IPv6 entry for a domain name, and that's not a reason to get more
+ aggressive in our timeouts for the other response. Other errors are
+ either a result of bad input (which should affect all parallel
+ requests), local or network conditions, non-definitive server
+ responses, or us cancelling the request. */
+ && (status == ARES_SUCCESS || status == ARES_ENOTFOUND)) {
+ /* Right now, there can only be up to two parallel queries, so don't
+ bother handling any other cases. */
+ DEBUGASSERT(res->num_pending == 1);
+
+ /* It's possible that one of these parallel queries could succeed
+ quickly, but the other could always fail or timeout (when we're
+ talking to a pool of DNS servers that can only successfully resolve
+ IPv4 address, for example).
+
+ It's also possible that the other request could always just take
+ longer because it needs more time or only the second DNS server can
+ fulfill it successfully. But, to align with the philosophy of Happy
+ Eyeballs, we don't want to wait _too_ long or users will think
+ requests are slow when IPv6 lookups don't actually work (but IPv4 ones
+ do).
+
+ So, now that we have a usable answer (some IPv4 addresses, some IPv6
+ addresses, or "no such domain"), we start a timeout for the remaining
+ pending responses. Even though it is typical that this resolved
+ request came back quickly, that needn't be the case. It might be that
+ this completing request didn't get a result from the first DNS server
+ or even the first round of the whole DNS server pool. So it could
+ already be quite some time after we issued the DNS queries in the
+ first place. Without modifying c-ares, we can't know exactly where in
+ its retry cycle we are. We could guess based on how much time has
+ gone by, but it doesn't really matter. Happy Eyeballs tells us that,
+ given usable information in hand, we simply don't want to wait "too
+ much longer" after we get a result.
+
+ We simply wait an additional amount of time equal to the default
+ c-ares query timeout. That is enough time for a typical parallel
+ response to arrive without being "too long". Even on a network
+ where one of the two types of queries is failing or timing out
+ constantly, this will usually mean we wait a total of the default
+ c-ares timeout (5 seconds) plus the round trip time for the successful
+ request, which seems bearable. The downside is that c-ares might race
+ with us to issue one more retry just before we give up, but it seems
+ better to "waste" that request instead of trying to guess the perfect
+ timeout to prevent it. After all, we don't even know where in the
+ c-ares retry cycle each request is.
+ */
+ res->happy_eyeballs_dns_time = Curl_now();
+ Curl_expire(data, HAPPY_EYEBALLS_DNS_TIMEOUT,
+ EXPIRE_HAPPY_EYEBALLS_DNS);
+ }
+ }
+}
+#else
+/* c-ares 1.16.0 or later */
+
+/*
+ * ares2addr() converts an address list provided by c-ares to an internal
+ * libcurl compatible list
+ */
+static struct Curl_addrinfo *ares2addr(struct ares_addrinfo_node *node)
+{
+ /* traverse the ares_addrinfo_node list */
+ struct ares_addrinfo_node *ai;
+ struct Curl_addrinfo *cafirst = NULL;
+ struct Curl_addrinfo *calast = NULL;
+ int error = 0;
+
+ for(ai = node; ai != NULL; ai = ai->ai_next) {
+ size_t ss_size;
+ struct Curl_addrinfo *ca;
+ /* ignore elements with unsupported address family, */
+ /* settle family-specific sockaddr structure size. */
+ if(ai->ai_family == AF_INET)
+ ss_size = sizeof(struct sockaddr_in);
+#ifdef ENABLE_IPV6
+ else if(ai->ai_family == AF_INET6)
+ ss_size = sizeof(struct sockaddr_in6);
+#endif
+ else
+ continue;
+
+ /* ignore elements without required address info */
+ if(!ai->ai_addr || !(ai->ai_addrlen > 0))
+ continue;
+
+ /* ignore elements with bogus address size */
+ if((size_t)ai->ai_addrlen < ss_size)
+ continue;
+
+ ca = malloc(sizeof(struct Curl_addrinfo) + ss_size);
+ if(!ca) {
+ error = EAI_MEMORY;
+ break;
+ }
+
+ /* copy each structure member individually, member ordering, */
+ /* size, or padding might be different for each platform. */
+
+ ca->ai_flags = ai->ai_flags;
+ ca->ai_family = ai->ai_family;
+ ca->ai_socktype = ai->ai_socktype;
+ ca->ai_protocol = ai->ai_protocol;
+ ca->ai_addrlen = (curl_socklen_t)ss_size;
+ ca->ai_addr = NULL;
+ ca->ai_canonname = NULL;
+ ca->ai_next = NULL;
+
+ ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
+ memcpy(ca->ai_addr, ai->ai_addr, ss_size);
+
+ /* if the return list is empty, this becomes the first element */
+ if(!cafirst)
+ cafirst = ca;
+
+ /* add this element last in the return list */
+ if(calast)
+ calast->ai_next = ca;
+ calast = ca;
+ }
+
+ /* if we failed, destroy the Curl_addrinfo list */
+ if(error) {
+ Curl_freeaddrinfo(cafirst);
+ cafirst = NULL;
+ }
+
+ return cafirst;
+}
+
+static void addrinfo_cb(void *arg, int status, int timeouts,
+ struct ares_addrinfo *result)
+{
+ struct Curl_easy *data = (struct Curl_easy *)arg;
+ struct thread_data *res = data->state.async.tdata;
+ (void)timeouts;
+ if(ARES_SUCCESS == status) {
+ res->temp_ai = ares2addr(result->nodes);
+ res->last_status = CURL_ASYNC_SUCCESS;
+ ares_freeaddrinfo(result);
+ }
+ res->num_pending--;
+}
+
+#endif
+/*
+ * Curl_resolver_getaddrinfo() - when using ares
+ *
+ * Returns name information about the given hostname and port number. If
+ * successful, the 'hostent' is returned and the fourth argument will point to
+ * memory we need to free after use. That memory *MUST* be freed with
+ * Curl_freeaddrinfo(), nothing else.
+ */
+struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
+ const char *hostname,
+ int port,
+ int *waitp)
+{
+ struct thread_data *res = NULL;
+ size_t namelen = strlen(hostname);
+ *waitp = 0; /* default to synchronous response */
+
+ res = calloc(sizeof(struct thread_data) + namelen, 1);
+ if(res) {
+ strcpy(res->hostname, hostname);
+ data->state.async.hostname = res->hostname;
+ data->state.async.port = port;
+ data->state.async.done = FALSE; /* not done */
+ data->state.async.status = 0; /* clear */
+ data->state.async.dns = NULL; /* clear */
+ data->state.async.tdata = res;
+
+ /* initial status - failed */
+ res->last_status = ARES_ENOTFOUND;
+
+#ifdef HAVE_CARES_GETADDRINFO
+ {
+ struct ares_addrinfo_hints hints;
+ char service[12];
+ int pf = PF_INET;
+ memset(&hints, 0, sizeof(hints));
+#ifdef CURLRES_IPV6
+ if((data->conn->ip_version != CURL_IPRESOLVE_V4) &&
+ Curl_ipv6works(data)) {
+ /* The stack seems to be IPv6-enabled */
+ if(data->conn->ip_version == CURL_IPRESOLVE_V6)
+ pf = PF_INET6;
+ else
+ pf = PF_UNSPEC;
+ }
+#endif /* CURLRES_IPV6 */
+ hints.ai_family = pf;
+ hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP)?
+ SOCK_STREAM : SOCK_DGRAM;
+ /* Since the service is a numerical one, set the hint flags
+ * accordingly to save a call to getservbyname in inside C-Ares
+ */
+ hints.ai_flags = ARES_AI_NUMERICSERV;
+ msnprintf(service, sizeof(service), "%d", port);
+ res->num_pending = 1;
+ ares_getaddrinfo((ares_channel)data->state.async.resolver, hostname,
+ service, &hints, addrinfo_cb, data);
+ }
+#else
+
+#ifdef HAVE_CARES_IPV6
+ if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data)) {
+ /* The stack seems to be IPv6-enabled */
+ res->num_pending = 2;
+
+ /* areschannel is already setup in the Curl_open() function */
+ ares_gethostbyname((ares_channel)data->state.async.resolver, hostname,
+ PF_INET, query_completed_cb, data);
+ ares_gethostbyname((ares_channel)data->state.async.resolver, hostname,
+ PF_INET6, query_completed_cb, data);
+ }
+ else
+#endif
+ {
+ res->num_pending = 1;
+
+ /* areschannel is already setup in the Curl_open() function */
+ ares_gethostbyname((ares_channel)data->state.async.resolver,
+ hostname, PF_INET,
+ query_completed_cb, data);
+ }
+#endif
+ *waitp = 1; /* expect asynchronous response */
+ }
+ return NULL; /* no struct yet */
+}
+
+CURLcode Curl_set_dns_servers(struct Curl_easy *data,
+ char *servers)
+{
+ CURLcode result = CURLE_NOT_BUILT_IN;
+ int ares_result;
+
+ /* If server is NULL or empty, this would purge all DNS servers
+ * from ares library, which will cause any and all queries to fail.
+ * So, just return OK if none are configured and don't actually make
+ * any changes to c-ares. This lets c-ares use it's defaults, which
+ * it gets from the OS (for instance from /etc/resolv.conf on Linux).
+ */
+ if(!(servers && servers[0]))
+ return CURLE_OK;
+
+#ifdef HAVE_CARES_SERVERS_CSV
+#ifdef HAVE_CARES_PORTS_CSV
+ ares_result = ares_set_servers_ports_csv(data->state.async.resolver,
+ servers);
+#else
+ ares_result = ares_set_servers_csv(data->state.async.resolver, servers);
+#endif
+ switch(ares_result) {
+ case ARES_SUCCESS:
+ result = CURLE_OK;
+ break;
+ case ARES_ENOMEM:
+ result = CURLE_OUT_OF_MEMORY;
+ break;
+ case ARES_ENOTINITIALIZED:
+ case ARES_ENODATA:
+ case ARES_EBADSTR:
+ default:
+ result = CURLE_BAD_FUNCTION_ARGUMENT;
+ break;
+ }
+#else /* too old c-ares version! */
+ (void)data;
+ (void)(ares_result);
+#endif
+ return result;
+}
+
+CURLcode Curl_set_dns_interface(struct Curl_easy *data,
+ const char *interf)
+{
+#ifdef HAVE_CARES_LOCAL_DEV
+ if(!interf)
+ interf = "";
+
+ ares_set_local_dev((ares_channel)data->state.async.resolver, interf);
+
+ return CURLE_OK;
+#else /* c-ares version too old! */
+ (void)data;
+ (void)interf;
+ return CURLE_NOT_BUILT_IN;
+#endif
+}
+
+CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data,
+ const char *local_ip4)
+{
+#ifdef HAVE_CARES_SET_LOCAL
+ struct in_addr a4;
+
+ if((!local_ip4) || (local_ip4[0] == 0)) {
+ a4.s_addr = 0; /* disabled: do not bind to a specific address */
+ }
+ else {
+ if(Curl_inet_pton(AF_INET, local_ip4, &a4) != 1) {
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+ }
+
+ ares_set_local_ip4((ares_channel)data->state.async.resolver,
+ ntohl(a4.s_addr));
+
+ return CURLE_OK;
+#else /* c-ares version too old! */
+ (void)data;
+ (void)local_ip4;
+ return CURLE_NOT_BUILT_IN;
+#endif
+}
+
+CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
+ const char *local_ip6)
+{
+#if defined(HAVE_CARES_SET_LOCAL) && defined(ENABLE_IPV6)
+ unsigned char a6[INET6_ADDRSTRLEN];
+
+ if((!local_ip6) || (local_ip6[0] == 0)) {
+ /* disabled: do not bind to a specific address */
+ memset(a6, 0, sizeof(a6));
+ }
+ else {
+ if(Curl_inet_pton(AF_INET6, local_ip6, a6) != 1) {
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+ }
+
+ ares_set_local_ip6((ares_channel)data->state.async.resolver, a6);
+
+ return CURLE_OK;
+#else /* c-ares version too old! */
+ (void)data;
+ (void)local_ip6;
+ return CURLE_NOT_BUILT_IN;
+#endif
+}
+#endif /* CURLRES_ARES */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/asyn-thread.c b/iotdb-client/odbc/deps/curl-src/lib/asyn-thread.c
new file mode 100644
index 0000000000000..a2e294f8f5142
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/asyn-thread.c
@@ -0,0 +1,760 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "socketpair.h"
+
+/***********************************************************************
+ * Only for threaded name resolves builds
+ **********************************************************************/
+#ifdef CURLRES_THREADED
+
+#ifdef HAVE_NETINET_IN_H
+#include
+#endif
+#ifdef HAVE_NETDB_H
+#include
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include
+#endif
+#ifdef __VMS
+#include
+#include
+#endif
+
+#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
+# include
+#endif
+
+#ifdef HAVE_GETADDRINFO
+# define RESOLVER_ENOMEM EAI_MEMORY
+#else
+# define RESOLVER_ENOMEM ENOMEM
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "url.h"
+#include "multiif.h"
+#include "inet_ntop.h"
+#include "curl_threads.h"
+#include "connect.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+struct resdata {
+ struct curltime start;
+};
+
+/*
+ * Curl_resolver_global_init()
+ * Called from curl_global_init() to initialize global resolver environment.
+ * Does nothing here.
+ */
+int Curl_resolver_global_init(void)
+{
+ return CURLE_OK;
+}
+
+/*
+ * Curl_resolver_global_cleanup()
+ * Called from curl_global_cleanup() to destroy global resolver environment.
+ * Does nothing here.
+ */
+void Curl_resolver_global_cleanup(void)
+{
+}
+
+/*
+ * Curl_resolver_init()
+ * Called from curl_easy_init() -> Curl_open() to initialize resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure).
+ */
+CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver)
+{
+ (void)easy;
+ *resolver = calloc(1, sizeof(struct resdata));
+ if(!*resolver)
+ return CURLE_OUT_OF_MEMORY;
+ return CURLE_OK;
+}
+
+/*
+ * Curl_resolver_cleanup()
+ * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure).
+ */
+void Curl_resolver_cleanup(void *resolver)
+{
+ free(resolver);
+}
+
+/*
+ * Curl_resolver_duphandle()
+ * Called from curl_easy_duphandle() to duplicate resolver URL state-specific
+ * environment ('resolver' member of the UrlState structure).
+ */
+CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to, void *from)
+{
+ (void)from;
+ return Curl_resolver_init(easy, to);
+}
+
+static void destroy_async_data(struct Curl_async *);
+
+/*
+ * Cancel all possibly still on-going resolves for this connection.
+ */
+void Curl_resolver_cancel(struct Curl_easy *data)
+{
+ destroy_async_data(&data->state.async);
+}
+
+/* This function is used to init a threaded resolve */
+static bool init_resolve_thread(struct Curl_easy *data,
+ const char *hostname, int port,
+ const struct addrinfo *hints);
+
+
+/* Data for synchronization between resolver thread and its parent */
+struct thread_sync_data {
+ curl_mutex_t *mtx;
+ int done;
+ int port;
+ char *hostname; /* hostname to resolve, Curl_async.hostname
+ duplicate */
+#ifndef CURL_DISABLE_SOCKETPAIR
+ struct Curl_easy *data;
+ curl_socket_t sock_pair[2]; /* socket pair */
+#endif
+ int sock_error;
+ struct Curl_addrinfo *res;
+#ifdef HAVE_GETADDRINFO
+ struct addrinfo hints;
+#endif
+ struct thread_data *td; /* for thread-self cleanup */
+};
+
+struct thread_data {
+ curl_thread_t thread_hnd;
+ unsigned int poll_interval;
+ timediff_t interval_end;
+ struct thread_sync_data tsd;
+};
+
+static struct thread_sync_data *conn_thread_sync_data(struct Curl_easy *data)
+{
+ return &(data->state.async.tdata->tsd);
+}
+
+/* Destroy resolver thread synchronization data */
+static
+void destroy_thread_sync_data(struct thread_sync_data *tsd)
+{
+ if(tsd->mtx) {
+ Curl_mutex_destroy(tsd->mtx);
+ free(tsd->mtx);
+ }
+
+ free(tsd->hostname);
+
+ if(tsd->res)
+ Curl_freeaddrinfo(tsd->res);
+
+#ifndef CURL_DISABLE_SOCKETPAIR
+ /*
+ * close one end of the socket pair (may be done in resolver thread);
+ * the other end (for reading) is always closed in the parent thread.
+ */
+ if(tsd->sock_pair[1] != CURL_SOCKET_BAD) {
+ sclose(tsd->sock_pair[1]);
+ }
+#endif
+ memset(tsd, 0, sizeof(*tsd));
+}
+
+/* Initialize resolver thread synchronization data */
+static
+int init_thread_sync_data(struct thread_data *td,
+ const char *hostname,
+ int port,
+ const struct addrinfo *hints)
+{
+ struct thread_sync_data *tsd = &td->tsd;
+
+ memset(tsd, 0, sizeof(*tsd));
+
+ tsd->td = td;
+ tsd->port = port;
+ /* Treat the request as done until the thread actually starts so any early
+ * cleanup gets done properly.
+ */
+ tsd->done = 1;
+#ifdef HAVE_GETADDRINFO
+ DEBUGASSERT(hints);
+ tsd->hints = *hints;
+#else
+ (void) hints;
+#endif
+
+ tsd->mtx = malloc(sizeof(curl_mutex_t));
+ if(!tsd->mtx)
+ goto err_exit;
+
+ Curl_mutex_init(tsd->mtx);
+
+#ifndef CURL_DISABLE_SOCKETPAIR
+ /* create socket pair, avoid AF_LOCAL since it doesn't build on Solaris */
+ if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) {
+ tsd->sock_pair[0] = CURL_SOCKET_BAD;
+ tsd->sock_pair[1] = CURL_SOCKET_BAD;
+ goto err_exit;
+ }
+#endif
+ tsd->sock_error = CURL_ASYNC_SUCCESS;
+
+ /* Copying hostname string because original can be destroyed by parent
+ * thread during gethostbyname execution.
+ */
+ tsd->hostname = strdup(hostname);
+ if(!tsd->hostname)
+ goto err_exit;
+
+ return 1;
+
+err_exit:
+#ifndef CURL_DISABLE_SOCKETPAIR
+ if(tsd->sock_pair[0] != CURL_SOCKET_BAD) {
+ sclose(tsd->sock_pair[0]);
+ tsd->sock_pair[0] = CURL_SOCKET_BAD;
+ }
+#endif
+ destroy_thread_sync_data(tsd);
+ return 0;
+}
+
+static CURLcode getaddrinfo_complete(struct Curl_easy *data)
+{
+ struct thread_sync_data *tsd = conn_thread_sync_data(data);
+ CURLcode result;
+
+ result = Curl_addrinfo_callback(data, tsd->sock_error, tsd->res);
+ /* The tsd->res structure has been copied to async.dns and perhaps the DNS
+ cache. Set our copy to NULL so destroy_thread_sync_data doesn't free it.
+ */
+ tsd->res = NULL;
+
+ return result;
+}
+
+
+#ifdef HAVE_GETADDRINFO
+
+/*
+ * getaddrinfo_thread() resolves a name and then exits.
+ *
+ * For builds without ARES, but with ENABLE_IPV6, create a resolver thread
+ * and wait on it.
+ */
+static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
+{
+ struct thread_sync_data *tsd = (struct thread_sync_data *)arg;
+ struct thread_data *td = tsd->td;
+ char service[12];
+ int rc;
+#ifndef CURL_DISABLE_SOCKETPAIR
+ char buf[1];
+#endif
+
+ msnprintf(service, sizeof(service), "%d", tsd->port);
+
+ rc = Curl_getaddrinfo_ex(tsd->hostname, service, &tsd->hints, &tsd->res);
+
+ if(rc) {
+ tsd->sock_error = SOCKERRNO?SOCKERRNO:rc;
+ if(tsd->sock_error == 0)
+ tsd->sock_error = RESOLVER_ENOMEM;
+ }
+ else {
+ Curl_addrinfo_set_port(tsd->res, tsd->port);
+ }
+
+ Curl_mutex_acquire(tsd->mtx);
+ if(tsd->done) {
+ /* too late, gotta clean up the mess */
+ Curl_mutex_release(tsd->mtx);
+ destroy_thread_sync_data(tsd);
+ free(td);
+ }
+ else {
+#ifndef CURL_DISABLE_SOCKETPAIR
+ if(tsd->sock_pair[1] != CURL_SOCKET_BAD) {
+ /* DNS has been resolved, signal client task */
+ buf[0] = 1;
+ if(swrite(tsd->sock_pair[1], buf, sizeof(buf)) < 0) {
+ /* update sock_erro to errno */
+ tsd->sock_error = SOCKERRNO;
+ }
+ }
+#endif
+ tsd->done = 1;
+ Curl_mutex_release(tsd->mtx);
+ }
+
+ return 0;
+}
+
+#else /* HAVE_GETADDRINFO */
+
+/*
+ * gethostbyname_thread() resolves a name and then exits.
+ */
+static unsigned int CURL_STDCALL gethostbyname_thread(void *arg)
+{
+ struct thread_sync_data *tsd = (struct thread_sync_data *)arg;
+ struct thread_data *td = tsd->td;
+
+ tsd->res = Curl_ipv4_resolve_r(tsd->hostname, tsd->port);
+
+ if(!tsd->res) {
+ tsd->sock_error = SOCKERRNO;
+ if(tsd->sock_error == 0)
+ tsd->sock_error = RESOLVER_ENOMEM;
+ }
+
+ Curl_mutex_acquire(tsd->mtx);
+ if(tsd->done) {
+ /* too late, gotta clean up the mess */
+ Curl_mutex_release(tsd->mtx);
+ destroy_thread_sync_data(tsd);
+ free(td);
+ }
+ else {
+ tsd->done = 1;
+ Curl_mutex_release(tsd->mtx);
+ }
+
+ return 0;
+}
+
+#endif /* HAVE_GETADDRINFO */
+
+/*
+ * destroy_async_data() cleans up async resolver data and thread handle.
+ */
+static void destroy_async_data(struct Curl_async *async)
+{
+ if(async->tdata) {
+ struct thread_data *td = async->tdata;
+ int done;
+#ifndef CURL_DISABLE_SOCKETPAIR
+ curl_socket_t sock_rd = td->tsd.sock_pair[0];
+ struct Curl_easy *data = td->tsd.data;
+#endif
+
+ /*
+ * if the thread is still blocking in the resolve syscall, detach it and
+ * let the thread do the cleanup...
+ */
+ Curl_mutex_acquire(td->tsd.mtx);
+ done = td->tsd.done;
+ td->tsd.done = 1;
+ Curl_mutex_release(td->tsd.mtx);
+
+ if(!done) {
+ Curl_thread_destroy(td->thread_hnd);
+ }
+ else {
+ if(td->thread_hnd != curl_thread_t_null)
+ Curl_thread_join(&td->thread_hnd);
+
+ destroy_thread_sync_data(&td->tsd);
+
+ free(async->tdata);
+ }
+#ifndef CURL_DISABLE_SOCKETPAIR
+ /*
+ * ensure CURLMOPT_SOCKETFUNCTION fires CURL_POLL_REMOVE
+ * before the FD is invalidated to avoid EBADF on EPOLL_CTL_DEL
+ */
+ Curl_multi_closed(data, sock_rd);
+ sclose(sock_rd);
+#endif
+ }
+ async->tdata = NULL;
+
+ free(async->hostname);
+ async->hostname = NULL;
+}
+
+/*
+ * init_resolve_thread() starts a new thread that performs the actual
+ * resolve. This function returns before the resolve is done.
+ *
+ * Returns FALSE in case of failure, otherwise TRUE.
+ */
+static bool init_resolve_thread(struct Curl_easy *data,
+ const char *hostname, int port,
+ const struct addrinfo *hints)
+{
+ struct thread_data *td = calloc(1, sizeof(struct thread_data));
+ int err = ENOMEM;
+ struct Curl_async *asp = &data->state.async;
+
+ data->state.async.tdata = td;
+ if(!td)
+ goto errno_exit;
+
+ asp->port = port;
+ asp->done = FALSE;
+ asp->status = 0;
+ asp->dns = NULL;
+ td->thread_hnd = curl_thread_t_null;
+
+ if(!init_thread_sync_data(td, hostname, port, hints)) {
+ asp->tdata = NULL;
+ free(td);
+ goto errno_exit;
+ }
+
+ free(asp->hostname);
+ asp->hostname = strdup(hostname);
+ if(!asp->hostname)
+ goto err_exit;
+
+ /* The thread will set this to 1 when complete. */
+ td->tsd.done = 0;
+
+#ifdef HAVE_GETADDRINFO
+ td->thread_hnd = Curl_thread_create(getaddrinfo_thread, &td->tsd);
+#else
+ td->thread_hnd = Curl_thread_create(gethostbyname_thread, &td->tsd);
+#endif
+
+ if(!td->thread_hnd) {
+ /* The thread never started, so mark it as done here for proper cleanup. */
+ td->tsd.done = 1;
+ err = errno;
+ goto err_exit;
+ }
+
+ return TRUE;
+
+err_exit:
+ destroy_async_data(asp);
+
+errno_exit:
+ errno = err;
+ return FALSE;
+}
+
+/*
+ * 'entry' may be NULL and then no data is returned
+ */
+static CURLcode thread_wait_resolv(struct Curl_easy *data,
+ struct Curl_dns_entry **entry,
+ bool report)
+{
+ struct thread_data *td;
+ CURLcode result = CURLE_OK;
+
+ DEBUGASSERT(data);
+ td = data->state.async.tdata;
+ DEBUGASSERT(td);
+ DEBUGASSERT(td->thread_hnd != curl_thread_t_null);
+
+ /* wait for the thread to resolve the name */
+ if(Curl_thread_join(&td->thread_hnd)) {
+ if(entry)
+ result = getaddrinfo_complete(data);
+ }
+ else
+ DEBUGASSERT(0);
+
+ data->state.async.done = TRUE;
+
+ if(entry)
+ *entry = data->state.async.dns;
+
+ if(!data->state.async.dns && report)
+ /* a name was not resolved, report error */
+ result = Curl_resolver_error(data);
+
+ destroy_async_data(&data->state.async);
+
+ if(!data->state.async.dns && report)
+ connclose(data->conn, "asynch resolve failed");
+
+ return result;
+}
+
+
+/*
+ * Until we gain a way to signal the resolver threads to stop early, we must
+ * simply wait for them and ignore their results.
+ */
+void Curl_resolver_kill(struct Curl_easy *data)
+{
+ struct thread_data *td = data->state.async.tdata;
+
+ /* If we're still resolving, we must wait for the threads to fully clean up,
+ unfortunately. Otherwise, we can simply cancel to clean up any resolver
+ data. */
+ if(td && td->thread_hnd != curl_thread_t_null
+ && (data->set.quick_exit != 1L))
+ (void)thread_wait_resolv(data, NULL, FALSE);
+ else
+ Curl_resolver_cancel(data);
+}
+
+/*
+ * Curl_resolver_wait_resolv()
+ *
+ * Waits for a resolve to finish. This function should be avoided since using
+ * this risk getting the multi interface to "hang".
+ *
+ * If 'entry' is non-NULL, make it point to the resolved dns entry
+ *
+ * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved,
+ * CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
+ *
+ * This is the version for resolves-in-a-thread.
+ */
+CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data,
+ struct Curl_dns_entry **entry)
+{
+ return thread_wait_resolv(data, entry, TRUE);
+}
+
+/*
+ * Curl_resolver_is_resolved() is called repeatedly to check if a previous
+ * name resolve request has completed. It should also make sure to time-out if
+ * the operation seems to take too long.
+ */
+CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
+ struct Curl_dns_entry **entry)
+{
+ struct thread_data *td = data->state.async.tdata;
+ int done = 0;
+
+ DEBUGASSERT(entry);
+ *entry = NULL;
+
+ if(!td) {
+ DEBUGASSERT(td);
+ return CURLE_COULDNT_RESOLVE_HOST;
+ }
+
+ Curl_mutex_acquire(td->tsd.mtx);
+ done = td->tsd.done;
+ Curl_mutex_release(td->tsd.mtx);
+
+ if(done) {
+ getaddrinfo_complete(data);
+
+ if(!data->state.async.dns) {
+ CURLcode result = Curl_resolver_error(data);
+ destroy_async_data(&data->state.async);
+ return result;
+ }
+ destroy_async_data(&data->state.async);
+ *entry = data->state.async.dns;
+ }
+ else {
+ /* poll for name lookup done with exponential backoff up to 250ms */
+ /* should be fine even if this converts to 32 bit */
+ timediff_t elapsed = Curl_timediff(Curl_now(),
+ data->progress.t_startsingle);
+ if(elapsed < 0)
+ elapsed = 0;
+
+ if(td->poll_interval == 0)
+ /* Start at 1ms poll interval */
+ td->poll_interval = 1;
+ else if(elapsed >= td->interval_end)
+ /* Back-off exponentially if last interval expired */
+ td->poll_interval *= 2;
+
+ if(td->poll_interval > 250)
+ td->poll_interval = 250;
+
+ td->interval_end = elapsed + td->poll_interval;
+ Curl_expire(data, td->poll_interval, EXPIRE_ASYNC_NAME);
+ }
+
+ return CURLE_OK;
+}
+
+int Curl_resolver_getsock(struct Curl_easy *data, curl_socket_t *socks)
+{
+ int ret_val = 0;
+ timediff_t milli;
+ timediff_t ms;
+ struct resdata *reslv = (struct resdata *)data->state.async.resolver;
+#ifndef CURL_DISABLE_SOCKETPAIR
+ struct thread_data *td = data->state.async.tdata;
+#else
+ (void)socks;
+#endif
+
+#ifndef CURL_DISABLE_SOCKETPAIR
+ if(td) {
+ /* return read fd to client for polling the DNS resolution status */
+ socks[0] = td->tsd.sock_pair[0];
+ td->tsd.data = data;
+ ret_val = GETSOCK_READSOCK(0);
+ }
+ else {
+#endif
+ ms = Curl_timediff(Curl_now(), reslv->start);
+ if(ms < 3)
+ milli = 0;
+ else if(ms <= 50)
+ milli = ms/3;
+ else if(ms <= 250)
+ milli = 50;
+ else
+ milli = 200;
+ Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
+#ifndef CURL_DISABLE_SOCKETPAIR
+ }
+#endif
+
+
+ return ret_val;
+}
+
+#ifndef HAVE_GETADDRINFO
+/*
+ * Curl_getaddrinfo() - for platforms without getaddrinfo
+ */
+struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
+ const char *hostname,
+ int port,
+ int *waitp)
+{
+ struct resdata *reslv = (struct resdata *)data->state.async.resolver;
+
+ *waitp = 0; /* default to synchronous response */
+
+ reslv->start = Curl_now();
+
+ /* fire up a new resolver thread! */
+ if(init_resolve_thread(data, hostname, port, NULL)) {
+ *waitp = 1; /* expect asynchronous response */
+ return NULL;
+ }
+
+ failf(data, "getaddrinfo() thread failed");
+
+ return NULL;
+}
+
+#else /* !HAVE_GETADDRINFO */
+
+/*
+ * Curl_resolver_getaddrinfo() - for getaddrinfo
+ */
+struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
+ const char *hostname,
+ int port,
+ int *waitp)
+{
+ struct addrinfo hints;
+ int pf = PF_INET;
+ struct resdata *reslv = (struct resdata *)data->state.async.resolver;
+
+ *waitp = 0; /* default to synchronous response */
+
+#ifdef CURLRES_IPV6
+ if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data)) {
+ /* The stack seems to be IPv6-enabled */
+ if(data->conn->ip_version == CURL_IPRESOLVE_V6)
+ pf = PF_INET6;
+ else
+ pf = PF_UNSPEC;
+ }
+#endif /* CURLRES_IPV6 */
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = pf;
+ hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP)?
+ SOCK_STREAM : SOCK_DGRAM;
+
+ reslv->start = Curl_now();
+ /* fire up a new resolver thread! */
+ if(init_resolve_thread(data, hostname, port, &hints)) {
+ *waitp = 1; /* expect asynchronous response */
+ return NULL;
+ }
+
+ failf(data, "getaddrinfo() thread failed to start");
+ return NULL;
+
+}
+
+#endif /* !HAVE_GETADDRINFO */
+
+CURLcode Curl_set_dns_servers(struct Curl_easy *data,
+ char *servers)
+{
+ (void)data;
+ (void)servers;
+ return CURLE_NOT_BUILT_IN;
+
+}
+
+CURLcode Curl_set_dns_interface(struct Curl_easy *data,
+ const char *interf)
+{
+ (void)data;
+ (void)interf;
+ return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data,
+ const char *local_ip4)
+{
+ (void)data;
+ (void)local_ip4;
+ return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
+ const char *local_ip6)
+{
+ (void)data;
+ (void)local_ip6;
+ return CURLE_NOT_BUILT_IN;
+}
+
+#endif /* CURLRES_THREADED */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/asyn.h b/iotdb-client/odbc/deps/curl-src/lib/asyn.h
new file mode 100644
index 0000000000000..7e207c4f564fe
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/asyn.h
@@ -0,0 +1,184 @@
+#ifndef HEADER_CURL_ASYN_H
+#define HEADER_CURL_ASYN_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "curl_addrinfo.h"
+
+struct addrinfo;
+struct hostent;
+struct Curl_easy;
+struct connectdata;
+struct Curl_dns_entry;
+
+/*
+ * This header defines all functions in the internal asynch resolver interface.
+ * All asynch resolvers need to provide these functions.
+ * asyn-ares.c and asyn-thread.c are the current implementations of asynch
+ * resolver backends.
+ */
+
+/*
+ * Curl_resolver_global_init()
+ *
+ * Called from curl_global_init() to initialize global resolver environment.
+ * Returning anything else than CURLE_OK fails curl_global_init().
+ */
+int Curl_resolver_global_init(void);
+
+/*
+ * Curl_resolver_global_cleanup()
+ * Called from curl_global_cleanup() to destroy global resolver environment.
+ */
+void Curl_resolver_global_cleanup(void);
+
+/*
+ * Curl_resolver_init()
+ * Called from curl_easy_init() -> Curl_open() to initialize resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure). Should fill the passed pointer by the initialized handler.
+ * Returning anything else than CURLE_OK fails curl_easy_init() with the
+ * correspondent code.
+ */
+CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver);
+
+/*
+ * Curl_resolver_cleanup()
+ * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure). Should destroy the handler and free all resources connected to
+ * it.
+ */
+void Curl_resolver_cleanup(void *resolver);
+
+/*
+ * Curl_resolver_duphandle()
+ * Called from curl_easy_duphandle() to duplicate resolver URL-state specific
+ * environment ('resolver' member of the UrlState structure). Should
+ * duplicate the 'from' handle and pass the resulting handle to the 'to'
+ * pointer. Returning anything else than CURLE_OK causes failed
+ * curl_easy_duphandle() call.
+ */
+CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to,
+ void *from);
+
+/*
+ * Curl_resolver_cancel().
+ *
+ * It is called from inside other functions to cancel currently performing
+ * resolver request. Should also free any temporary resources allocated to
+ * perform a request. This never waits for resolver threads to complete.
+ *
+ * It is safe to call this when conn is in any state.
+ */
+void Curl_resolver_cancel(struct Curl_easy *data);
+
+/*
+ * Curl_resolver_kill().
+ *
+ * This acts like Curl_resolver_cancel() except it will block until any threads
+ * associated with the resolver are complete. This never blocks for resolvers
+ * that do not use threads. This is intended to be the "last chance" function
+ * that cleans up an in-progress resolver completely (before its owner is about
+ * to die).
+ *
+ * It is safe to call this when conn is in any state.
+ */
+void Curl_resolver_kill(struct Curl_easy *data);
+
+/* Curl_resolver_getsock()
+ *
+ * This function is called from the multi_getsock() function. 'sock' is a
+ * pointer to an array to hold the file descriptors, with 'numsock' being the
+ * size of that array (in number of entries). This function is supposed to
+ * return bitmask indicating what file descriptors (referring to array indexes
+ * in the 'sock' array) to wait for, read/write.
+ */
+int Curl_resolver_getsock(struct Curl_easy *data, curl_socket_t *sock);
+
+/*
+ * Curl_resolver_is_resolved()
+ *
+ * Called repeatedly to check if a previous name resolve request has
+ * completed. It should also make sure to time-out if the operation seems to
+ * take too long.
+ *
+ * Returns normal CURLcode errors.
+ */
+CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
+ struct Curl_dns_entry **dns);
+
+/*
+ * Curl_resolver_wait_resolv()
+ *
+ * Waits for a resolve to finish. This function should be avoided since using
+ * this risk getting the multi interface to "hang".
+ *
+ * If 'entry' is non-NULL, make it point to the resolved dns entry
+ *
+ * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved,
+ * CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
+ */
+CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data,
+ struct Curl_dns_entry **dnsentry);
+
+/*
+ * Curl_resolver_getaddrinfo() - when using this resolver
+ *
+ * Returns name information about the given hostname and port number. If
+ * successful, the 'hostent' is returned and the fourth argument will point to
+ * memory we need to free after use. That memory *MUST* be freed with
+ * Curl_freeaddrinfo(), nothing else.
+ *
+ * Each resolver backend must of course make sure to return data in the
+ * correct format to comply with this.
+ */
+struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
+ const char *hostname,
+ int port,
+ int *waitp);
+
+#ifndef CURLRES_ASYNCH
+/* convert these functions if an asynch resolver isn't used */
+#define Curl_resolver_cancel(x) Curl_nop_stmt
+#define Curl_resolver_kill(x) Curl_nop_stmt
+#define Curl_resolver_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
+#define Curl_resolver_wait_resolv(x,y) CURLE_COULDNT_RESOLVE_HOST
+#define Curl_resolver_duphandle(x,y,z) CURLE_OK
+#define Curl_resolver_init(x,y) CURLE_OK
+#define Curl_resolver_global_init() CURLE_OK
+#define Curl_resolver_global_cleanup() Curl_nop_stmt
+#define Curl_resolver_cleanup(x) Curl_nop_stmt
+#endif
+
+#ifdef CURLRES_ASYNCH
+#define Curl_resolver_asynch() 1
+#else
+#define Curl_resolver_asynch() 0
+#endif
+
+
+/********** end of generic resolver interface functions *****************/
+#endif /* HEADER_CURL_ASYN_H */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/base64.c b/iotdb-client/odbc/deps/curl-src/lib/base64.c
new file mode 100644
index 0000000000000..2a49b5acd6a5b
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/base64.c
@@ -0,0 +1,292 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+/* Base64 encoding/decoding */
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP_AUTH) || defined(USE_SSH) || \
+ !defined(CURL_DISABLE_LDAP) || \
+ !defined(CURL_DISABLE_SMTP) || \
+ !defined(CURL_DISABLE_POP3) || \
+ !defined(CURL_DISABLE_IMAP) || \
+ !defined(CURL_DISABLE_DOH) || defined(USE_SSL) || defined(BUILDING_CURL)
+#include "curl/curl.h"
+#include "warnless.h"
+#include "curl_base64.h"
+
+/* The last 2 #include files should be in this order */
+#ifdef BUILDING_LIBCURL
+#include "curl_memory.h"
+#endif
+#include "memdebug.h"
+
+/* ---- Base64 Encoding/Decoding Table --- */
+/* Padding character string starts at offset 64. */
+static const char base64encdec[]=
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+
+/* The Base 64 encoding with a URL and filename safe alphabet, RFC 4648
+ section 5 */
+static const char base64url[]=
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
+
+static const unsigned char decodetable[] =
+{ 62, 255, 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255,
+ 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, 255, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51 };
+/*
+ * Curl_base64_decode()
+ *
+ * Given a base64 NUL-terminated string at src, decode it and return a
+ * pointer in *outptr to a newly allocated memory area holding decoded
+ * data. Size of decoded data is returned in variable pointed by outlen.
+ *
+ * Returns CURLE_OK on success, otherwise specific error code. Function
+ * output shall not be considered valid unless CURLE_OK is returned.
+ *
+ * When decoded data length is 0, returns NULL in *outptr.
+ *
+ * @unittest: 1302
+ */
+CURLcode Curl_base64_decode(const char *src,
+ unsigned char **outptr, size_t *outlen)
+{
+ size_t srclen = 0;
+ size_t padding = 0;
+ size_t i;
+ size_t numQuantums;
+ size_t fullQuantums;
+ size_t rawlen = 0;
+ unsigned char *pos;
+ unsigned char *newstr;
+ unsigned char lookup[256];
+
+ *outptr = NULL;
+ *outlen = 0;
+ srclen = strlen(src);
+
+ /* Check the length of the input string is valid */
+ if(!srclen || srclen % 4)
+ return CURLE_BAD_CONTENT_ENCODING;
+
+ /* srclen is at least 4 here */
+ while(src[srclen - 1 - padding] == '=') {
+ /* count padding characters */
+ padding++;
+ /* A maximum of two = padding characters is allowed */
+ if(padding > 2)
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ /* Calculate the number of quantums */
+ numQuantums = srclen / 4;
+ fullQuantums = numQuantums - (padding ? 1 : 0);
+
+ /* Calculate the size of the decoded string */
+ rawlen = (numQuantums * 3) - padding;
+
+ /* Allocate our buffer including room for a null-terminator */
+ newstr = malloc(rawlen + 1);
+ if(!newstr)
+ return CURLE_OUT_OF_MEMORY;
+
+ pos = newstr;
+
+ memset(lookup, 0xff, sizeof(lookup));
+ memcpy(&lookup['+'], decodetable, sizeof(decodetable));
+ /* replaces
+ {
+ unsigned char c;
+ const unsigned char *p = (const unsigned char *)base64encdec;
+ for(c = 0; *p; c++, p++)
+ lookup[*p] = c;
+ }
+ */
+
+ /* Decode the complete quantums first */
+ for(i = 0; i < fullQuantums; i++) {
+ unsigned char val;
+ unsigned int x = 0;
+ int j;
+
+ for(j = 0; j < 4; j++) {
+ val = lookup[(unsigned char)*src++];
+ if(val == 0xff) /* bad symbol */
+ goto bad;
+ x = (x << 6) | val;
+ }
+ pos[2] = x & 0xff;
+ pos[1] = (x >> 8) & 0xff;
+ pos[0] = (x >> 16) & 0xff;
+ pos += 3;
+ }
+ if(padding) {
+ /* this means either 8 or 16 bits output */
+ unsigned char val;
+ unsigned int x = 0;
+ int j;
+ size_t padc = 0;
+ for(j = 0; j < 4; j++) {
+ if(*src == '=') {
+ x <<= 6;
+ src++;
+ if(++padc > padding)
+ /* this is a badly placed '=' symbol! */
+ goto bad;
+ }
+ else {
+ val = lookup[(unsigned char)*src++];
+ if(val == 0xff) /* bad symbol */
+ goto bad;
+ x = (x << 6) | val;
+ }
+ }
+ if(padding == 1)
+ pos[1] = (x >> 8) & 0xff;
+ pos[0] = (x >> 16) & 0xff;
+ pos += 3 - padding;
+ }
+
+ /* Zero terminate */
+ *pos = '\0';
+
+ /* Return the decoded data */
+ *outptr = newstr;
+ *outlen = rawlen;
+
+ return CURLE_OK;
+bad:
+ free(newstr);
+ return CURLE_BAD_CONTENT_ENCODING;
+}
+
+static CURLcode base64_encode(const char *table64,
+ const char *inputbuff, size_t insize,
+ char **outptr, size_t *outlen)
+{
+ char *output;
+ char *base64data;
+ const unsigned char *in = (unsigned char *)inputbuff;
+ const char *padstr = &table64[64]; /* Point to padding string. */
+
+ *outptr = NULL;
+ *outlen = 0;
+
+ if(!insize)
+ insize = strlen(inputbuff);
+
+#if SIZEOF_SIZE_T == 4
+ if(insize > UINT_MAX/4)
+ return CURLE_OUT_OF_MEMORY;
+#endif
+
+ base64data = output = malloc((insize + 2) / 3 * 4 + 1);
+ if(!output)
+ return CURLE_OUT_OF_MEMORY;
+
+ while(insize >= 3) {
+ *output++ = table64[ in[0] >> 2 ];
+ *output++ = table64[ ((in[0] & 0x03) << 4) | (in[1] >> 4) ];
+ *output++ = table64[ ((in[1] & 0x0F) << 2) | ((in[2] & 0xC0) >> 6) ];
+ *output++ = table64[ in[2] & 0x3F ];
+ insize -= 3;
+ in += 3;
+ }
+ if(insize) {
+ /* this is only one or two bytes now */
+ *output++ = table64[ in[0] >> 2 ];
+ if(insize == 1) {
+ *output++ = table64[ ((in[0] & 0x03) << 4) ];
+ if(*padstr) {
+ *output++ = *padstr;
+ *output++ = *padstr;
+ }
+ }
+ else {
+ /* insize == 2 */
+ *output++ = table64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xF0) >> 4) ];
+ *output++ = table64[ ((in[1] & 0x0F) << 2) ];
+ if(*padstr)
+ *output++ = *padstr;
+ }
+ }
+
+ /* Zero terminate */
+ *output = '\0';
+
+ /* Return the pointer to the new data (allocated memory) */
+ *outptr = base64data;
+
+ /* Return the length of the new data */
+ *outlen = output - base64data;
+
+ return CURLE_OK;
+}
+
+/*
+ * Curl_base64_encode()
+ *
+ * Given a pointer to an input buffer and an input size, encode it and
+ * return a pointer in *outptr to a newly allocated memory area holding
+ * encoded data. Size of encoded data is returned in variable pointed by
+ * outlen.
+ *
+ * Input length of 0 indicates input buffer holds a NUL-terminated string.
+ *
+ * Returns CURLE_OK on success, otherwise specific error code. Function
+ * output shall not be considered valid unless CURLE_OK is returned.
+ *
+ * @unittest: 1302
+ */
+CURLcode Curl_base64_encode(const char *inputbuff, size_t insize,
+ char **outptr, size_t *outlen)
+{
+ return base64_encode(base64encdec, inputbuff, insize, outptr, outlen);
+}
+
+/*
+ * Curl_base64url_encode()
+ *
+ * Given a pointer to an input buffer and an input size, encode it and
+ * return a pointer in *outptr to a newly allocated memory area holding
+ * encoded data. Size of encoded data is returned in variable pointed by
+ * outlen.
+ *
+ * Input length of 0 indicates input buffer holds a NUL-terminated string.
+ *
+ * Returns CURLE_OK on success, otherwise specific error code. Function
+ * output shall not be considered valid unless CURLE_OK is returned.
+ *
+ * @unittest: 1302
+ */
+CURLcode Curl_base64url_encode(const char *inputbuff, size_t insize,
+ char **outptr, size_t *outlen)
+{
+ return base64_encode(base64url, inputbuff, insize, outptr, outlen);
+}
+
+#endif /* no users so disabled */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/bufq.c b/iotdb-client/odbc/deps/curl-src/lib/bufq.c
new file mode 100644
index 0000000000000..d03906d166def
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/bufq.c
@@ -0,0 +1,656 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "bufq.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+static bool chunk_is_empty(const struct buf_chunk *chunk)
+{
+ return chunk->r_offset >= chunk->w_offset;
+}
+
+static bool chunk_is_full(const struct buf_chunk *chunk)
+{
+ return chunk->w_offset >= chunk->dlen;
+}
+
+static size_t chunk_len(const struct buf_chunk *chunk)
+{
+ return chunk->w_offset - chunk->r_offset;
+}
+
+static size_t chunk_space(const struct buf_chunk *chunk)
+{
+ return chunk->dlen - chunk->w_offset;
+}
+
+static void chunk_reset(struct buf_chunk *chunk)
+{
+ chunk->next = NULL;
+ chunk->r_offset = chunk->w_offset = 0;
+}
+
+static size_t chunk_append(struct buf_chunk *chunk,
+ const unsigned char *buf, size_t len)
+{
+ unsigned char *p = &chunk->x.data[chunk->w_offset];
+ size_t n = chunk->dlen - chunk->w_offset;
+ DEBUGASSERT(chunk->dlen >= chunk->w_offset);
+ if(n) {
+ n = CURLMIN(n, len);
+ memcpy(p, buf, n);
+ chunk->w_offset += n;
+ }
+ return n;
+}
+
+static size_t chunk_read(struct buf_chunk *chunk,
+ unsigned char *buf, size_t len)
+{
+ unsigned char *p = &chunk->x.data[chunk->r_offset];
+ size_t n = chunk->w_offset - chunk->r_offset;
+ DEBUGASSERT(chunk->w_offset >= chunk->r_offset);
+ if(!n) {
+ return 0;
+ }
+ else if(n <= len) {
+ memcpy(buf, p, n);
+ chunk->r_offset = chunk->w_offset = 0;
+ return n;
+ }
+ else {
+ memcpy(buf, p, len);
+ chunk->r_offset += len;
+ return len;
+ }
+}
+
+static ssize_t chunk_slurpn(struct buf_chunk *chunk, size_t max_len,
+ Curl_bufq_reader *reader,
+ void *reader_ctx, CURLcode *err)
+{
+ unsigned char *p = &chunk->x.data[chunk->w_offset];
+ size_t n = chunk->dlen - chunk->w_offset; /* free amount */
+ ssize_t nread;
+
+ DEBUGASSERT(chunk->dlen >= chunk->w_offset);
+ if(!n) {
+ *err = CURLE_AGAIN;
+ return -1;
+ }
+ if(max_len && n > max_len)
+ n = max_len;
+ nread = reader(reader_ctx, p, n, err);
+ if(nread > 0) {
+ DEBUGASSERT((size_t)nread <= n);
+ chunk->w_offset += nread;
+ }
+ return nread;
+}
+
+static void chunk_peek(const struct buf_chunk *chunk,
+ const unsigned char **pbuf, size_t *plen)
+{
+ DEBUGASSERT(chunk->w_offset >= chunk->r_offset);
+ *pbuf = &chunk->x.data[chunk->r_offset];
+ *plen = chunk->w_offset - chunk->r_offset;
+}
+
+static void chunk_peek_at(const struct buf_chunk *chunk, size_t offset,
+ const unsigned char **pbuf, size_t *plen)
+{
+ offset += chunk->r_offset;
+ DEBUGASSERT(chunk->w_offset >= offset);
+ *pbuf = &chunk->x.data[offset];
+ *plen = chunk->w_offset - offset;
+}
+
+static size_t chunk_skip(struct buf_chunk *chunk, size_t amount)
+{
+ size_t n = chunk->w_offset - chunk->r_offset;
+ DEBUGASSERT(chunk->w_offset >= chunk->r_offset);
+ if(n) {
+ n = CURLMIN(n, amount);
+ chunk->r_offset += n;
+ if(chunk->r_offset == chunk->w_offset)
+ chunk->r_offset = chunk->w_offset = 0;
+ }
+ return n;
+}
+
+static void chunk_list_free(struct buf_chunk **anchor)
+{
+ struct buf_chunk *chunk;
+ while(*anchor) {
+ chunk = *anchor;
+ *anchor = chunk->next;
+ free(chunk);
+ }
+}
+
+
+
+void Curl_bufcp_init(struct bufc_pool *pool,
+ size_t chunk_size, size_t spare_max)
+{
+ DEBUGASSERT(chunk_size > 0);
+ DEBUGASSERT(spare_max > 0);
+ memset(pool, 0, sizeof(*pool));
+ pool->chunk_size = chunk_size;
+ pool->spare_max = spare_max;
+}
+
+static CURLcode bufcp_take(struct bufc_pool *pool,
+ struct buf_chunk **pchunk)
+{
+ struct buf_chunk *chunk = NULL;
+
+ if(pool->spare) {
+ chunk = pool->spare;
+ pool->spare = chunk->next;
+ --pool->spare_count;
+ chunk_reset(chunk);
+ *pchunk = chunk;
+ return CURLE_OK;
+ }
+
+ chunk = calloc(1, sizeof(*chunk) + pool->chunk_size);
+ if(!chunk) {
+ *pchunk = NULL;
+ return CURLE_OUT_OF_MEMORY;
+ }
+ chunk->dlen = pool->chunk_size;
+ *pchunk = chunk;
+ return CURLE_OK;
+}
+
+static void bufcp_put(struct bufc_pool *pool,
+ struct buf_chunk *chunk)
+{
+ if(pool->spare_count >= pool->spare_max) {
+ free(chunk);
+ }
+ else {
+ chunk_reset(chunk);
+ chunk->next = pool->spare;
+ pool->spare = chunk;
+ ++pool->spare_count;
+ }
+}
+
+void Curl_bufcp_free(struct bufc_pool *pool)
+{
+ chunk_list_free(&pool->spare);
+ pool->spare_count = 0;
+}
+
+static void bufq_init(struct bufq *q, struct bufc_pool *pool,
+ size_t chunk_size, size_t max_chunks, int opts)
+{
+ DEBUGASSERT(chunk_size > 0);
+ DEBUGASSERT(max_chunks > 0);
+ memset(q, 0, sizeof(*q));
+ q->chunk_size = chunk_size;
+ q->max_chunks = max_chunks;
+ q->pool = pool;
+ q->opts = opts;
+}
+
+void Curl_bufq_init2(struct bufq *q, size_t chunk_size, size_t max_chunks,
+ int opts)
+{
+ bufq_init(q, NULL, chunk_size, max_chunks, opts);
+}
+
+void Curl_bufq_init(struct bufq *q, size_t chunk_size, size_t max_chunks)
+{
+ bufq_init(q, NULL, chunk_size, max_chunks, BUFQ_OPT_NONE);
+}
+
+void Curl_bufq_initp(struct bufq *q, struct bufc_pool *pool,
+ size_t max_chunks, int opts)
+{
+ bufq_init(q, pool, pool->chunk_size, max_chunks, opts);
+}
+
+void Curl_bufq_free(struct bufq *q)
+{
+ chunk_list_free(&q->head);
+ chunk_list_free(&q->spare);
+ q->tail = NULL;
+ q->chunk_count = 0;
+}
+
+void Curl_bufq_reset(struct bufq *q)
+{
+ struct buf_chunk *chunk;
+ while(q->head) {
+ chunk = q->head;
+ q->head = chunk->next;
+ chunk->next = q->spare;
+ q->spare = chunk;
+ }
+ q->tail = NULL;
+}
+
+size_t Curl_bufq_len(const struct bufq *q)
+{
+ const struct buf_chunk *chunk = q->head;
+ size_t len = 0;
+ while(chunk) {
+ len += chunk_len(chunk);
+ chunk = chunk->next;
+ }
+ return len;
+}
+
+size_t Curl_bufq_space(const struct bufq *q)
+{
+ size_t space = 0;
+ if(q->tail)
+ space += chunk_space(q->tail);
+ if(q->spare) {
+ struct buf_chunk *chunk = q->spare;
+ while(chunk) {
+ space += chunk->dlen;
+ chunk = chunk->next;
+ }
+ }
+ if(q->chunk_count < q->max_chunks) {
+ space += (q->max_chunks - q->chunk_count) * q->chunk_size;
+ }
+ return space;
+}
+
+bool Curl_bufq_is_empty(const struct bufq *q)
+{
+ return !q->head || chunk_is_empty(q->head);
+}
+
+bool Curl_bufq_is_full(const struct bufq *q)
+{
+ if(!q->tail || q->spare)
+ return FALSE;
+ if(q->chunk_count < q->max_chunks)
+ return FALSE;
+ if(q->chunk_count > q->max_chunks)
+ return TRUE;
+ /* we have no spares and cannot make more, is the tail full? */
+ return chunk_is_full(q->tail);
+}
+
+static struct buf_chunk *get_spare(struct bufq *q)
+{
+ struct buf_chunk *chunk = NULL;
+
+ if(q->spare) {
+ chunk = q->spare;
+ q->spare = chunk->next;
+ chunk_reset(chunk);
+ return chunk;
+ }
+
+ if(q->chunk_count >= q->max_chunks && (!(q->opts & BUFQ_OPT_SOFT_LIMIT)))
+ return NULL;
+
+ if(q->pool) {
+ if(bufcp_take(q->pool, &chunk))
+ return NULL;
+ ++q->chunk_count;
+ return chunk;
+ }
+ else {
+ chunk = calloc(1, sizeof(*chunk) + q->chunk_size);
+ if(!chunk)
+ return NULL;
+ chunk->dlen = q->chunk_size;
+ ++q->chunk_count;
+ return chunk;
+ }
+}
+
+static void prune_head(struct bufq *q)
+{
+ struct buf_chunk *chunk;
+
+ while(q->head && chunk_is_empty(q->head)) {
+ chunk = q->head;
+ q->head = chunk->next;
+ if(q->tail == chunk)
+ q->tail = q->head;
+ if(q->pool) {
+ bufcp_put(q->pool, chunk);
+ --q->chunk_count;
+ }
+ else if((q->chunk_count > q->max_chunks) ||
+ (q->opts & BUFQ_OPT_NO_SPARES)) {
+ /* SOFT_LIMIT allowed us more than max. free spares until
+ * we are at max again. Or free them if we are configured
+ * to not use spares. */
+ free(chunk);
+ --q->chunk_count;
+ }
+ else {
+ chunk->next = q->spare;
+ q->spare = chunk;
+ }
+ }
+}
+
+static struct buf_chunk *get_non_full_tail(struct bufq *q)
+{
+ struct buf_chunk *chunk;
+
+ if(q->tail && !chunk_is_full(q->tail))
+ return q->tail;
+ chunk = get_spare(q);
+ if(chunk) {
+ /* new tail, and possibly new head */
+ if(q->tail) {
+ q->tail->next = chunk;
+ q->tail = chunk;
+ }
+ else {
+ DEBUGASSERT(!q->head);
+ q->head = q->tail = chunk;
+ }
+ }
+ return chunk;
+}
+
+ssize_t Curl_bufq_write(struct bufq *q,
+ const unsigned char *buf, size_t len,
+ CURLcode *err)
+{
+ struct buf_chunk *tail;
+ ssize_t nwritten = 0;
+ size_t n;
+
+ DEBUGASSERT(q->max_chunks > 0);
+ while(len) {
+ tail = get_non_full_tail(q);
+ if(!tail) {
+ if(q->chunk_count < q->max_chunks) {
+ *err = CURLE_OUT_OF_MEMORY;
+ return -1;
+ }
+ break;
+ }
+ n = chunk_append(tail, buf, len);
+ if(!n)
+ break;
+ nwritten += n;
+ buf += n;
+ len -= n;
+ }
+ if(nwritten == 0 && len) {
+ *err = CURLE_AGAIN;
+ return -1;
+ }
+ *err = CURLE_OK;
+ return nwritten;
+}
+
+ssize_t Curl_bufq_read(struct bufq *q, unsigned char *buf, size_t len,
+ CURLcode *err)
+{
+ ssize_t nread = 0;
+ size_t n;
+
+ *err = CURLE_OK;
+ while(len && q->head) {
+ n = chunk_read(q->head, buf, len);
+ if(n) {
+ nread += n;
+ buf += n;
+ len -= n;
+ }
+ prune_head(q);
+ }
+ if(nread == 0) {
+ *err = CURLE_AGAIN;
+ return -1;
+ }
+ return nread;
+}
+
+bool Curl_bufq_peek(struct bufq *q,
+ const unsigned char **pbuf, size_t *plen)
+{
+ if(q->head && chunk_is_empty(q->head)) {
+ prune_head(q);
+ }
+ if(q->head && !chunk_is_empty(q->head)) {
+ chunk_peek(q->head, pbuf, plen);
+ return TRUE;
+ }
+ *pbuf = NULL;
+ *plen = 0;
+ return FALSE;
+}
+
+bool Curl_bufq_peek_at(struct bufq *q, size_t offset,
+ const unsigned char **pbuf, size_t *plen)
+{
+ struct buf_chunk *c = q->head;
+ size_t clen;
+
+ while(c) {
+ clen = chunk_len(c);
+ if(!clen)
+ break;
+ if(offset >= clen) {
+ offset -= clen;
+ c = c->next;
+ continue;
+ }
+ chunk_peek_at(c, offset, pbuf, plen);
+ return TRUE;
+ }
+ *pbuf = NULL;
+ *plen = 0;
+ return FALSE;
+}
+
+void Curl_bufq_skip(struct bufq *q, size_t amount)
+{
+ size_t n;
+
+ while(amount && q->head) {
+ n = chunk_skip(q->head, amount);
+ amount -= n;
+ prune_head(q);
+ }
+}
+
+ssize_t Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer,
+ void *writer_ctx, CURLcode *err)
+{
+ const unsigned char *buf;
+ size_t blen;
+ ssize_t nwritten = 0;
+
+ while(Curl_bufq_peek(q, &buf, &blen)) {
+ ssize_t chunk_written;
+
+ chunk_written = writer(writer_ctx, buf, blen, err);
+ if(chunk_written < 0) {
+ if(!nwritten || *err != CURLE_AGAIN) {
+ /* blocked on first write or real error, fail */
+ nwritten = -1;
+ }
+ break;
+ }
+ if(!chunk_written) {
+ if(!nwritten) {
+ /* treat as blocked */
+ *err = CURLE_AGAIN;
+ nwritten = -1;
+ }
+ break;
+ }
+ Curl_bufq_skip(q, (size_t)chunk_written);
+ nwritten += chunk_written;
+ }
+ return nwritten;
+}
+
+ssize_t Curl_bufq_write_pass(struct bufq *q,
+ const unsigned char *buf, size_t len,
+ Curl_bufq_writer *writer, void *writer_ctx,
+ CURLcode *err)
+{
+ ssize_t nwritten = 0, n;
+
+ *err = CURLE_OK;
+ while(len) {
+ if(Curl_bufq_is_full(q)) {
+ /* try to make room in case we are full */
+ n = Curl_bufq_pass(q, writer, writer_ctx, err);
+ if(n < 0) {
+ if(*err != CURLE_AGAIN) {
+ /* real error, fail */
+ return -1;
+ }
+ /* would block, bufq is full, give up */
+ break;
+ }
+ }
+
+ /* Add whatever is remaining now to bufq */
+ n = Curl_bufq_write(q, buf, len, err);
+ if(n < 0) {
+ if(*err != CURLE_AGAIN) {
+ /* real error, fail */
+ return -1;
+ }
+ /* no room in bufq */
+ break;
+ }
+ /* edge case of writer returning 0 (and len is >0)
+ * break or we might enter an infinite loop here */
+ if(n == 0)
+ break;
+
+ /* Maybe only part of `data` has been added, continue to loop */
+ buf += (size_t)n;
+ len -= (size_t)n;
+ nwritten += (size_t)n;
+ }
+
+ if(!nwritten && len) {
+ *err = CURLE_AGAIN;
+ return -1;
+ }
+ *err = CURLE_OK;
+ return nwritten;
+}
+
+ssize_t Curl_bufq_sipn(struct bufq *q, size_t max_len,
+ Curl_bufq_reader *reader, void *reader_ctx,
+ CURLcode *err)
+{
+ struct buf_chunk *tail = NULL;
+ ssize_t nread;
+
+ *err = CURLE_AGAIN;
+ tail = get_non_full_tail(q);
+ if(!tail) {
+ if(q->chunk_count < q->max_chunks) {
+ *err = CURLE_OUT_OF_MEMORY;
+ return -1;
+ }
+ /* full, blocked */
+ *err = CURLE_AGAIN;
+ return -1;
+ }
+
+ nread = chunk_slurpn(tail, max_len, reader, reader_ctx, err);
+ if(nread < 0) {
+ return -1;
+ }
+ else if(nread == 0) {
+ /* eof */
+ *err = CURLE_OK;
+ }
+ return nread;
+}
+
+/**
+ * Read up to `max_len` bytes and append it to the end of the buffer queue.
+ * if `max_len` is 0, no limit is imposed and the call behaves exactly
+ * the same as `Curl_bufq_slurp()`.
+ * Returns the total amount of buf read (may be 0) or -1 on other
+ * reader errors.
+ * Note that even in case of a -1 chunks may have been read and
+ * the buffer queue will have different length than before.
+ */
+static ssize_t bufq_slurpn(struct bufq *q, size_t max_len,
+ Curl_bufq_reader *reader, void *reader_ctx,
+ CURLcode *err)
+{
+ ssize_t nread = 0, n;
+
+ *err = CURLE_AGAIN;
+ while(1) {
+
+ n = Curl_bufq_sipn(q, max_len, reader, reader_ctx, err);
+ if(n < 0) {
+ if(!nread || *err != CURLE_AGAIN) {
+ /* blocked on first read or real error, fail */
+ nread = -1;
+ }
+ else
+ *err = CURLE_OK;
+ break;
+ }
+ else if(n == 0) {
+ /* eof */
+ *err = CURLE_OK;
+ break;
+ }
+ nread += (size_t)n;
+ if(max_len) {
+ DEBUGASSERT((size_t)n <= max_len);
+ max_len -= (size_t)n;
+ if(!max_len)
+ break;
+ }
+ /* give up slurping when we get less bytes than we asked for */
+ if(q->tail && !chunk_is_full(q->tail))
+ break;
+ }
+ return nread;
+}
+
+ssize_t Curl_bufq_slurp(struct bufq *q, Curl_bufq_reader *reader,
+ void *reader_ctx, CURLcode *err)
+{
+ return bufq_slurpn(q, 0, reader, reader_ctx, err);
+}
diff --git a/iotdb-client/odbc/deps/curl-src/lib/bufq.h b/iotdb-client/odbc/deps/curl-src/lib/bufq.h
new file mode 100644
index 0000000000000..089d61bfe4241
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/bufq.h
@@ -0,0 +1,265 @@
+#ifndef HEADER_CURL_BUFQ_H
+#define HEADER_CURL_BUFQ_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#include
+
+/**
+ * A chunk of bytes for reading and writing.
+ * The size is fixed a creation with read and write offset
+ * for where unread content is.
+ */
+struct buf_chunk {
+ struct buf_chunk *next; /* to keep it in a list */
+ size_t dlen; /* the amount of allocated x.data[] */
+ size_t r_offset; /* first unread bytes */
+ size_t w_offset; /* one after last written byte */
+ union {
+ unsigned char data[1]; /* the buffer for `dlen` bytes */
+ void *dummy; /* alignment */
+ } x;
+};
+
+/**
+ * A pool for providing/keeping a number of chunks of the same size
+ *
+ * The same pool can be shared by many `bufq` instances. However, a pool
+ * is not thread safe. All bufqs using it are supposed to operate in the
+ * same thread.
+ */
+struct bufc_pool {
+ struct buf_chunk *spare; /* list of available spare chunks */
+ size_t chunk_size; /* the size of chunks in this pool */
+ size_t spare_count; /* current number of spare chunks in list */
+ size_t spare_max; /* max number of spares to keep */
+};
+
+void Curl_bufcp_init(struct bufc_pool *pool,
+ size_t chunk_size, size_t spare_max);
+
+void Curl_bufcp_free(struct bufc_pool *pool);
+
+/**
+ * A queue of byte chunks for reading and writing.
+ * Reading is done from `head`, writing is done to `tail`.
+ *
+ * `bufq`s can be empty or full or neither. Its `len` is the number
+ * of bytes that can be read. For an empty bufq, `len` will be 0.
+ *
+ * By default, a bufq can hold up to `max_chunks * chunk_size` number
+ * of bytes. When `max_chunks` are used (in the `head` list) and the
+ * `tail` chunk is full, the bufq will report that it is full.
+ *
+ * On a full bufq, `len` may be less than the maximum number of bytes,
+ * e.g. when the head chunk is partially read. `len` may also become
+ * larger than the max when option `BUFQ_OPT_SOFT_LIMIT` is used.
+ *
+ * By default, writing to a full bufq will return (-1, CURLE_AGAIN). Same
+ * as reading from an empty bufq.
+ * With `BUFQ_OPT_SOFT_LIMIT` set, a bufq will allow writing becond this
+ * limit and use more than `max_chunks`. However it will report that it
+ * is full nevertheless. This is provided for situation where writes
+ * preferably never fail (except for memory exhaustion).
+ *
+ * By default and without a pool, a bufq will keep chunks that read
+ * read empty in its `spare` list. Option `BUFQ_OPT_NO_SPARES` will
+ * disable that and free chunks once they become empty.
+ *
+ * When providing a pool to a bufq, all chunk creation and spare handling
+ * will be delegated to that pool.
+ */
+struct bufq {
+ struct buf_chunk *head; /* chunk with bytes to read from */
+ struct buf_chunk *tail; /* chunk to write to */
+ struct buf_chunk *spare; /* list of free chunks, unless `pool` */
+ struct bufc_pool *pool; /* optional pool for free chunks */
+ size_t chunk_count; /* current number of chunks in `head+spare` */
+ size_t max_chunks; /* max `head` chunks to use */
+ size_t chunk_size; /* size of chunks to manage */
+ int opts; /* options for handling queue, see below */
+};
+
+/**
+ * Default behaviour: chunk limit is "hard", meaning attempts to write
+ * more bytes than can be hold in `max_chunks` is refused and will return
+ * -1, CURLE_AGAIN. */
+#define BUFQ_OPT_NONE (0)
+/**
+ * Make `max_chunks` a "soft" limit. A bufq will report that it is "full"
+ * when `max_chunks` are used, but allows writing beyond this limit.
+ */
+#define BUFQ_OPT_SOFT_LIMIT (1 << 0)
+/**
+ * Do not keep spare chunks.
+ */
+#define BUFQ_OPT_NO_SPARES (1 << 1)
+
+/**
+ * Initialize a buffer queue that can hold up to `max_chunks` buffers
+ * each of size `chunk_size`. The bufq will not allow writing of
+ * more bytes than can be held in `max_chunks`.
+ */
+void Curl_bufq_init(struct bufq *q, size_t chunk_size, size_t max_chunks);
+
+/**
+ * Initialize a buffer queue that can hold up to `max_chunks` buffers
+ * each of size `chunk_size` with the given options. See `BUFQ_OPT_*`.
+ */
+void Curl_bufq_init2(struct bufq *q, size_t chunk_size,
+ size_t max_chunks, int opts);
+
+void Curl_bufq_initp(struct bufq *q, struct bufc_pool *pool,
+ size_t max_chunks, int opts);
+
+/**
+ * Reset the buffer queue to be empty. Will keep any allocated buffer
+ * chunks around.
+ */
+void Curl_bufq_reset(struct bufq *q);
+
+/**
+ * Free all resources held by the buffer queue.
+ */
+void Curl_bufq_free(struct bufq *q);
+
+/**
+ * Return the total amount of data in the queue.
+ */
+size_t Curl_bufq_len(const struct bufq *q);
+
+/**
+ * Return the total amount of free space in the queue.
+ * The returned length is the number of bytes that can
+ * be expected to be written successfully to the bufq,
+ * providing no memory allocations fail.
+ */
+size_t Curl_bufq_space(const struct bufq *q);
+
+/**
+ * Returns TRUE iff there is no data in the buffer queue.
+ */
+bool Curl_bufq_is_empty(const struct bufq *q);
+
+/**
+ * Returns TRUE iff there is no space left in the buffer queue.
+ */
+bool Curl_bufq_is_full(const struct bufq *q);
+
+/**
+ * Write buf to the end of the buffer queue. The buf is copied
+ * and the amount of copied bytes is returned.
+ * A return code of -1 indicates an error, setting `err` to the
+ * cause. An err of CURLE_AGAIN is returned if the buffer queue is full.
+ */
+ssize_t Curl_bufq_write(struct bufq *q,
+ const unsigned char *buf, size_t len,
+ CURLcode *err);
+
+/**
+ * Read buf from the start of the buffer queue. The buf is copied
+ * and the amount of copied bytes is returned.
+ * A return code of -1 indicates an error, setting `err` to the
+ * cause. An err of CURLE_AGAIN is returned if the buffer queue is empty.
+ */
+ssize_t Curl_bufq_read(struct bufq *q, unsigned char *buf, size_t len,
+ CURLcode *err);
+
+/**
+ * Peek at the head chunk in the buffer queue. Returns a pointer to
+ * the chunk buf (at the current offset) and its length. Does not
+ * modify the buffer queue.
+ * Returns TRUE iff bytes are available. Sets `pbuf` to NULL and `plen`
+ * to 0 when no bytes are available.
+ * Repeated calls return the same information until the buffer queue
+ * is modified, see `Curl_bufq_skip()``
+ */
+bool Curl_bufq_peek(struct bufq *q,
+ const unsigned char **pbuf, size_t *plen);
+
+bool Curl_bufq_peek_at(struct bufq *q, size_t offset,
+ const unsigned char **pbuf, size_t *plen);
+
+/**
+ * Tell the buffer queue to discard `amount` buf bytes at the head
+ * of the queue. Skipping more buf than is currently buffered will
+ * just empty the queue.
+ */
+void Curl_bufq_skip(struct bufq *q, size_t amount);
+
+typedef ssize_t Curl_bufq_writer(void *writer_ctx,
+ const unsigned char *buf, size_t len,
+ CURLcode *err);
+/**
+ * Passes the chunks in the buffer queue to the writer and returns
+ * the amount of buf written. A writer may return -1 and CURLE_AGAIN
+ * to indicate blocking at which point the queue will stop and return
+ * the amount of buf passed so far.
+ * -1 is returned on any other errors reported by the writer.
+ * Note that in case of a -1 chunks may have been written and
+ * the buffer queue will have different length than before.
+ */
+ssize_t Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer,
+ void *writer_ctx, CURLcode *err);
+
+typedef ssize_t Curl_bufq_reader(void *reader_ctx,
+ unsigned char *buf, size_t len,
+ CURLcode *err);
+
+/**
+ * Read date and append it to the end of the buffer queue until the
+ * reader returns blocking or the queue is full. A reader returns
+ * -1 and CURLE_AGAIN to indicate blocking.
+ * Returns the total amount of buf read (may be 0) or -1 on other
+ * reader errors.
+ * Note that in case of a -1 chunks may have been read and
+ * the buffer queue will have different length than before.
+ */
+ssize_t Curl_bufq_slurp(struct bufq *q, Curl_bufq_reader *reader,
+ void *reader_ctx, CURLcode *err);
+
+/**
+ * Read *once* up to `max_len` bytes and append it to the buffer.
+ * if `max_len` is 0, no limit is imposed besides the chunk space.
+ * Returns the total amount of buf read (may be 0) or -1 on other
+ * reader errors.
+ */
+ssize_t Curl_bufq_sipn(struct bufq *q, size_t max_len,
+ Curl_bufq_reader *reader, void *reader_ctx,
+ CURLcode *err);
+
+/**
+ * Write buf to the end of the buffer queue.
+ * Will write bufq content or passed `buf` directly using the `writer`
+ * callback when it sees fit. 'buf' might get passed directly
+ * on or is placed into the buffer, depending on `len` and current
+ * amount buffered, chunk size, etc.
+ */
+ssize_t Curl_bufq_write_pass(struct bufq *q,
+ const unsigned char *buf, size_t len,
+ Curl_bufq_writer *writer, void *writer_ctx,
+ CURLcode *err);
+
+#endif /* HEADER_CURL_BUFQ_H */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/bufref.c b/iotdb-client/odbc/deps/curl-src/lib/bufref.c
new file mode 100644
index 0000000000000..ce686b6f37722
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/bufref.c
@@ -0,0 +1,129 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "urldata.h"
+#include "bufref.h"
+
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define SIGNATURE 0x5c48e9b2 /* Random pattern. */
+
+/*
+ * Init a bufref struct.
+ */
+void Curl_bufref_init(struct bufref *br)
+{
+ DEBUGASSERT(br);
+ br->dtor = NULL;
+ br->ptr = NULL;
+ br->len = 0;
+
+#ifdef DEBUGBUILD
+ br->signature = SIGNATURE;
+#endif
+}
+
+/*
+ * Free the buffer and re-init the necessary fields. It doesn't touch the
+ * 'signature' field and thus this buffer reference can be reused.
+ */
+
+void Curl_bufref_free(struct bufref *br)
+{
+ DEBUGASSERT(br);
+ DEBUGASSERT(br->signature == SIGNATURE);
+ DEBUGASSERT(br->ptr || !br->len);
+
+ if(br->ptr && br->dtor)
+ br->dtor((void *) br->ptr);
+
+ br->dtor = NULL;
+ br->ptr = NULL;
+ br->len = 0;
+}
+
+/*
+ * Set the buffer reference to new values. The previously referenced buffer
+ * is released before assignment.
+ */
+void Curl_bufref_set(struct bufref *br, const void *ptr, size_t len,
+ void (*dtor)(void *))
+{
+ DEBUGASSERT(ptr || !len);
+ DEBUGASSERT(len <= CURL_MAX_INPUT_LENGTH);
+
+ Curl_bufref_free(br);
+ br->ptr = (const unsigned char *) ptr;
+ br->len = len;
+ br->dtor = dtor;
+}
+
+/*
+ * Get a pointer to the referenced buffer.
+ */
+const unsigned char *Curl_bufref_ptr(const struct bufref *br)
+{
+ DEBUGASSERT(br);
+ DEBUGASSERT(br->signature == SIGNATURE);
+ DEBUGASSERT(br->ptr || !br->len);
+
+ return br->ptr;
+}
+
+/*
+ * Get the length of the referenced buffer data.
+ */
+size_t Curl_bufref_len(const struct bufref *br)
+{
+ DEBUGASSERT(br);
+ DEBUGASSERT(br->signature == SIGNATURE);
+ DEBUGASSERT(br->ptr || !br->len);
+
+ return br->len;
+}
+
+CURLcode Curl_bufref_memdup(struct bufref *br, const void *ptr, size_t len)
+{
+ unsigned char *cpy = NULL;
+
+ DEBUGASSERT(br);
+ DEBUGASSERT(br->signature == SIGNATURE);
+ DEBUGASSERT(br->ptr || !br->len);
+ DEBUGASSERT(ptr || !len);
+ DEBUGASSERT(len <= CURL_MAX_INPUT_LENGTH);
+
+ if(ptr) {
+ cpy = malloc(len + 1);
+ if(!cpy)
+ return CURLE_OUT_OF_MEMORY;
+ if(len)
+ memcpy(cpy, ptr, len);
+ cpy[len] = '\0';
+ }
+
+ Curl_bufref_set(br, cpy, len, curl_free);
+ return CURLE_OK;
+}
diff --git a/iotdb-client/odbc/deps/curl-src/lib/bufref.h b/iotdb-client/odbc/deps/curl-src/lib/bufref.h
new file mode 100644
index 0000000000000..dd424f18f5568
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/bufref.h
@@ -0,0 +1,48 @@
+#ifndef HEADER_CURL_BUFREF_H
+#define HEADER_CURL_BUFREF_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+/*
+ * Generic buffer reference.
+ */
+struct bufref {
+ void (*dtor)(void *); /* Associated destructor. */
+ const unsigned char *ptr; /* Referenced data buffer. */
+ size_t len; /* The data size in bytes. */
+#ifdef DEBUGBUILD
+ int signature; /* Detect API use mistakes. */
+#endif
+};
+
+
+void Curl_bufref_init(struct bufref *br);
+void Curl_bufref_set(struct bufref *br, const void *ptr, size_t len,
+ void (*dtor)(void *));
+const unsigned char *Curl_bufref_ptr(const struct bufref *br);
+size_t Curl_bufref_len(const struct bufref *br);
+CURLcode Curl_bufref_memdup(struct bufref *br, const void *ptr, size_t len);
+void Curl_bufref_free(struct bufref *br);
+
+#endif
diff --git a/iotdb-client/odbc/deps/curl-src/lib/c-hyper.c b/iotdb-client/odbc/deps/curl-src/lib/c-hyper.c
new file mode 100644
index 0000000000000..5726ff1cc3a0b
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/c-hyper.c
@@ -0,0 +1,1277 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_HYPER)
+
+#ifdef HAVE_NETINET_IN_H
+#include
+#endif
+
+#ifdef HAVE_NETDB_H
+#include
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include
+#endif
+#ifdef HAVE_NET_IF_H
+#include
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include
+#endif
+
+#include
+#include "urldata.h"
+#include "sendf.h"
+#include "transfer.h"
+#include "multiif.h"
+#include "progress.h"
+#include "content_encoding.h"
+#include "ws.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+typedef enum {
+ USERDATA_NOT_SET = 0, /* for tasks with no userdata set; must be zero */
+ USERDATA_RESP_BODY
+} userdata_t;
+
+size_t Curl_hyper_recv(void *userp, hyper_context *ctx,
+ uint8_t *buf, size_t buflen)
+{
+ struct Curl_easy *data = userp;
+ struct connectdata *conn = data->conn;
+ CURLcode result;
+ ssize_t nread;
+ DEBUGASSERT(conn);
+ (void)ctx;
+
+ DEBUGF(infof(data, "Curl_hyper_recv(%zu)", buflen));
+ result = Curl_read(data, conn->sockfd, (char *)buf, buflen, &nread);
+ if(result == CURLE_AGAIN) {
+ /* would block, register interest */
+ DEBUGF(infof(data, "Curl_hyper_recv(%zu) -> EAGAIN", buflen));
+ if(data->hyp.read_waker)
+ hyper_waker_free(data->hyp.read_waker);
+ data->hyp.read_waker = hyper_context_waker(ctx);
+ if(!data->hyp.read_waker) {
+ failf(data, "Couldn't make the read hyper_context_waker");
+ return HYPER_IO_ERROR;
+ }
+ return HYPER_IO_PENDING;
+ }
+ else if(result) {
+ failf(data, "Curl_read failed");
+ return HYPER_IO_ERROR;
+ }
+ DEBUGF(infof(data, "Curl_hyper_recv(%zu) -> %zd", buflen, nread));
+ return (size_t)nread;
+}
+
+size_t Curl_hyper_send(void *userp, hyper_context *ctx,
+ const uint8_t *buf, size_t buflen)
+{
+ struct Curl_easy *data = userp;
+ struct connectdata *conn = data->conn;
+ CURLcode result;
+ ssize_t nwrote;
+
+ DEBUGF(infof(data, "Curl_hyper_send(%zu)", buflen));
+ result = Curl_write(data, conn->sockfd, (void *)buf, buflen, &nwrote);
+ if(!result && !nwrote)
+ result = CURLE_AGAIN;
+ if(result == CURLE_AGAIN) {
+ DEBUGF(infof(data, "Curl_hyper_send(%zu) -> EAGAIN", buflen));
+ /* would block, register interest */
+ if(data->hyp.write_waker)
+ hyper_waker_free(data->hyp.write_waker);
+ data->hyp.write_waker = hyper_context_waker(ctx);
+ if(!data->hyp.write_waker) {
+ failf(data, "Couldn't make the write hyper_context_waker");
+ return HYPER_IO_ERROR;
+ }
+ return HYPER_IO_PENDING;
+ }
+ else if(result) {
+ failf(data, "Curl_write failed");
+ return HYPER_IO_ERROR;
+ }
+ DEBUGF(infof(data, "Curl_hyper_send(%zu) -> %zd", buflen, nwrote));
+ return (size_t)nwrote;
+}
+
+static int hyper_each_header(void *userdata,
+ const uint8_t *name,
+ size_t name_len,
+ const uint8_t *value,
+ size_t value_len)
+{
+ struct Curl_easy *data = (struct Curl_easy *)userdata;
+ size_t len;
+ char *headp;
+ CURLcode result;
+ int writetype;
+
+ if(name_len + value_len + 2 > CURL_MAX_HTTP_HEADER) {
+ failf(data, "Too long response header");
+ data->state.hresult = CURLE_OUT_OF_MEMORY;
+ return HYPER_ITER_BREAK;
+ }
+
+ if(!data->req.bytecount)
+ Curl_pgrsTime(data, TIMER_STARTTRANSFER);
+
+ Curl_dyn_reset(&data->state.headerb);
+ if(name_len) {
+ if(Curl_dyn_addf(&data->state.headerb, "%.*s: %.*s\r\n",
+ (int) name_len, name, (int) value_len, value))
+ return HYPER_ITER_BREAK;
+ }
+ else {
+ if(Curl_dyn_addn(&data->state.headerb, STRCONST("\r\n")))
+ return HYPER_ITER_BREAK;
+ }
+ len = Curl_dyn_len(&data->state.headerb);
+ headp = Curl_dyn_ptr(&data->state.headerb);
+
+ result = Curl_http_header(data, data->conn, headp);
+ if(result) {
+ data->state.hresult = result;
+ return HYPER_ITER_BREAK;
+ }
+
+ Curl_debug(data, CURLINFO_HEADER_IN, headp, len);
+
+ if(!data->state.hconnect || !data->set.suppress_connect_headers) {
+ writetype = CLIENTWRITE_HEADER;
+ if(data->state.hconnect)
+ writetype |= CLIENTWRITE_CONNECT;
+ if(data->req.httpcode/100 == 1)
+ writetype |= CLIENTWRITE_1XX;
+ result = Curl_client_write(data, writetype, headp, len);
+ if(result) {
+ data->state.hresult = CURLE_ABORTED_BY_CALLBACK;
+ return HYPER_ITER_BREAK;
+ }
+ }
+
+ result = Curl_bump_headersize(data, len, FALSE);
+ if(result) {
+ data->state.hresult = result;
+ return HYPER_ITER_BREAK;
+ }
+ return HYPER_ITER_CONTINUE;
+}
+
+static int hyper_body_chunk(void *userdata, const hyper_buf *chunk)
+{
+ char *buf = (char *)hyper_buf_bytes(chunk);
+ size_t len = hyper_buf_len(chunk);
+ struct Curl_easy *data = (struct Curl_easy *)userdata;
+ struct SingleRequest *k = &data->req;
+ CURLcode result = CURLE_OK;
+
+ if(0 == k->bodywrites++) {
+ bool done = FALSE;
+#if defined(USE_NTLM)
+ struct connectdata *conn = data->conn;
+ if(conn->bits.close &&
+ (((data->req.httpcode == 401) &&
+ (conn->http_ntlm_state == NTLMSTATE_TYPE2)) ||
+ ((data->req.httpcode == 407) &&
+ (conn->proxy_ntlm_state == NTLMSTATE_TYPE2)))) {
+ infof(data, "Connection closed while negotiating NTLM");
+ data->state.authproblem = TRUE;
+ Curl_safefree(data->req.newurl);
+ }
+#endif
+ if(data->state.expect100header) {
+ Curl_expire_done(data, EXPIRE_100_TIMEOUT);
+ if(data->req.httpcode < 400) {
+ k->exp100 = EXP100_SEND_DATA;
+ if(data->hyp.exp100_waker) {
+ hyper_waker_wake(data->hyp.exp100_waker);
+ data->hyp.exp100_waker = NULL;
+ }
+ }
+ else { /* >= 4xx */
+ k->exp100 = EXP100_FAILED;
+ }
+ }
+ if(data->state.hconnect && (data->req.httpcode/100 != 2) &&
+ data->state.authproxy.done) {
+ done = TRUE;
+ result = CURLE_OK;
+ }
+ else
+ result = Curl_http_firstwrite(data, data->conn, &done);
+ if(result || done) {
+ infof(data, "Return early from hyper_body_chunk");
+ data->state.hresult = result;
+ return HYPER_ITER_BREAK;
+ }
+ }
+ if(k->ignorebody)
+ return HYPER_ITER_CONTINUE;
+ if(0 == len)
+ return HYPER_ITER_CONTINUE;
+ Curl_debug(data, CURLINFO_DATA_IN, buf, len);
+ result = Curl_client_write(data, CLIENTWRITE_BODY, buf, len);
+
+ if(result) {
+ data->state.hresult = result;
+ return HYPER_ITER_BREAK;
+ }
+
+ data->req.bytecount += len;
+ result = Curl_pgrsSetDownloadCounter(data, data->req.bytecount);
+ if(result) {
+ data->state.hresult = result;
+ return HYPER_ITER_BREAK;
+ }
+ return HYPER_ITER_CONTINUE;
+}
+
+/*
+ * Hyper does not consider the status line, the first line in an HTTP/1
+ * response, to be a header. The libcurl API does. This function sends the
+ * status line in the header callback. */
+static CURLcode status_line(struct Curl_easy *data,
+ struct connectdata *conn,
+ uint16_t http_status,
+ int http_version,
+ const uint8_t *reason, size_t rlen)
+{
+ CURLcode result;
+ size_t len;
+ const char *vstr;
+ int writetype;
+ vstr = http_version == HYPER_HTTP_VERSION_1_1 ? "1.1" :
+ (http_version == HYPER_HTTP_VERSION_2 ? "2" : "1.0");
+
+ /* We need to set 'httpcodeq' for functions that check the response code in
+ a single place. */
+ data->req.httpcode = http_status;
+
+ if(data->state.hconnect)
+ /* CONNECT */
+ data->info.httpproxycode = http_status;
+ else {
+ conn->httpversion =
+ http_version == HYPER_HTTP_VERSION_1_1 ? 11 :
+ (http_version == HYPER_HTTP_VERSION_2 ? 20 : 10);
+ if(http_version == HYPER_HTTP_VERSION_1_0)
+ data->state.httpwant = CURL_HTTP_VERSION_1_0;
+
+ result = Curl_http_statusline(data, conn);
+ if(result)
+ return result;
+ }
+
+ Curl_dyn_reset(&data->state.headerb);
+
+ result = Curl_dyn_addf(&data->state.headerb, "HTTP/%s %03d %.*s\r\n",
+ vstr,
+ (int)http_status,
+ (int)rlen, reason);
+ if(result)
+ return result;
+ len = Curl_dyn_len(&data->state.headerb);
+ Curl_debug(data, CURLINFO_HEADER_IN, Curl_dyn_ptr(&data->state.headerb),
+ len);
+
+ if(!data->state.hconnect || !data->set.suppress_connect_headers) {
+ writetype = CLIENTWRITE_HEADER|CLIENTWRITE_STATUS;
+ result = Curl_client_write(data, writetype,
+ Curl_dyn_ptr(&data->state.headerb), len);
+ if(result)
+ return result;
+ }
+ result = Curl_bump_headersize(data, len, FALSE);
+ return result;
+}
+
+/*
+ * Hyper does not pass on the last empty response header. The libcurl API
+ * does. This function sends an empty header in the header callback.
+ */
+static CURLcode empty_header(struct Curl_easy *data)
+{
+ CURLcode result = Curl_http_size(data);
+ if(!result) {
+ result = hyper_each_header(data, NULL, 0, NULL, 0) ?
+ CURLE_WRITE_ERROR : CURLE_OK;
+ if(result)
+ failf(data, "hyperstream: couldn't pass blank header");
+ }
+ return result;
+}
+
+CURLcode Curl_hyper_stream(struct Curl_easy *data,
+ struct connectdata *conn,
+ int *didwhat,
+ bool *done,
+ int select_res)
+{
+ hyper_response *resp = NULL;
+ uint16_t http_status;
+ int http_version;
+ hyper_headers *headers = NULL;
+ hyper_body *resp_body = NULL;
+ struct hyptransfer *h = &data->hyp;
+ hyper_task *task;
+ hyper_task *foreach;
+ const uint8_t *reasonp;
+ size_t reason_len;
+ CURLcode result = CURLE_OK;
+ struct SingleRequest *k = &data->req;
+ (void)conn;
+
+ if(k->exp100 > EXP100_SEND_DATA) {
+ struct curltime now = Curl_now();
+ timediff_t ms = Curl_timediff(now, k->start100);
+ if(ms >= data->set.expect_100_timeout) {
+ /* we've waited long enough, continue anyway */
+ k->exp100 = EXP100_SEND_DATA;
+ k->keepon |= KEEP_SEND;
+ Curl_expire_done(data, EXPIRE_100_TIMEOUT);
+ infof(data, "Done waiting for 100-continue");
+ if(data->hyp.exp100_waker) {
+ hyper_waker_wake(data->hyp.exp100_waker);
+ data->hyp.exp100_waker = NULL;
+ }
+ }
+ }
+
+ if(select_res & CURL_CSELECT_IN) {
+ if(h->read_waker)
+ hyper_waker_wake(h->read_waker);
+ h->read_waker = NULL;
+ }
+ if(select_res & CURL_CSELECT_OUT) {
+ if(h->write_waker)
+ hyper_waker_wake(h->write_waker);
+ h->write_waker = NULL;
+ }
+
+ *done = FALSE;
+ do {
+ hyper_task_return_type t;
+ task = hyper_executor_poll(h->exec);
+ if(!task) {
+ *didwhat = KEEP_RECV;
+ break;
+ }
+ t = hyper_task_type(task);
+ if(t == HYPER_TASK_ERROR) {
+ hyper_error *hypererr = hyper_task_value(task);
+ hyper_task_free(task);
+ if(data->state.hresult) {
+ /* override Hyper's view, might not even be an error */
+ result = data->state.hresult;
+ infof(data, "hyperstream is done (by early callback)");
+ }
+ else {
+ uint8_t errbuf[256];
+ size_t errlen = hyper_error_print(hypererr, errbuf, sizeof(errbuf));
+ hyper_code code = hyper_error_code(hypererr);
+ failf(data, "Hyper: [%d] %.*s", (int)code, (int)errlen, errbuf);
+ switch(code) {
+ case HYPERE_ABORTED_BY_CALLBACK:
+ result = CURLE_OK;
+ break;
+ case HYPERE_UNEXPECTED_EOF:
+ if(!data->req.bytecount)
+ result = CURLE_GOT_NOTHING;
+ else
+ result = CURLE_RECV_ERROR;
+ break;
+ case HYPERE_INVALID_PEER_MESSAGE:
+ /* bump headerbytecount to avoid the count remaining at zero and
+ appearing to not having read anything from the peer at all */
+ data->req.headerbytecount++;
+ result = CURLE_UNSUPPORTED_PROTOCOL; /* maybe */
+ break;
+ default:
+ result = CURLE_RECV_ERROR;
+ break;
+ }
+ }
+ *done = TRUE;
+ hyper_error_free(hypererr);
+ break;
+ }
+ else if(t == HYPER_TASK_EMPTY) {
+ void *userdata = hyper_task_userdata(task);
+ hyper_task_free(task);
+ if((userdata_t)userdata == USERDATA_RESP_BODY) {
+ /* end of transfer */
+ *done = TRUE;
+ infof(data, "hyperstream is done");
+ if(!k->bodywrites) {
+ /* hyper doesn't always call the body write callback */
+ bool stilldone;
+ result = Curl_http_firstwrite(data, data->conn, &stilldone);
+ }
+ break;
+ }
+ else {
+ /* A background task for hyper; ignore */
+ continue;
+ }
+ }
+
+ DEBUGASSERT(HYPER_TASK_RESPONSE);
+
+ resp = hyper_task_value(task);
+ hyper_task_free(task);
+
+ *didwhat = KEEP_RECV;
+ if(!resp) {
+ failf(data, "hyperstream: couldn't get response");
+ return CURLE_RECV_ERROR;
+ }
+
+ http_status = hyper_response_status(resp);
+ http_version = hyper_response_version(resp);
+ reasonp = hyper_response_reason_phrase(resp);
+ reason_len = hyper_response_reason_phrase_len(resp);
+
+ if(http_status == 417 && data->state.expect100header) {
+ infof(data, "Got 417 while waiting for a 100");
+ data->state.disableexpect = TRUE;
+ data->req.newurl = strdup(data->state.url);
+ Curl_done_sending(data, k);
+ }
+
+ result = status_line(data, conn,
+ http_status, http_version, reasonp, reason_len);
+ if(result)
+ break;
+
+ headers = hyper_response_headers(resp);
+ if(!headers) {
+ failf(data, "hyperstream: couldn't get response headers");
+ result = CURLE_RECV_ERROR;
+ break;
+ }
+
+ /* the headers are already received */
+ hyper_headers_foreach(headers, hyper_each_header, data);
+ if(data->state.hresult) {
+ result = data->state.hresult;
+ break;
+ }
+
+ result = empty_header(data);
+ if(result)
+ break;
+
+ k->deductheadercount =
+ (100 <= http_status && 199 >= http_status)?k->headerbytecount:0;
+#ifdef USE_WEBSOCKETS
+ if(k->upgr101 == UPGR101_WS) {
+ if(http_status == 101) {
+ /* verify the response */
+ result = Curl_ws_accept(data, NULL, 0);
+ if(result)
+ return result;
+ }
+ else {
+ failf(data, "Expected 101, got %u", k->httpcode);
+ result = CURLE_HTTP_RETURNED_ERROR;
+ break;
+ }
+ }
+#endif
+
+ /* Curl_http_auth_act() checks what authentication methods that are
+ * available and decides which one (if any) to use. It will set 'newurl'
+ * if an auth method was picked. */
+ result = Curl_http_auth_act(data);
+ if(result)
+ break;
+
+ resp_body = hyper_response_body(resp);
+ if(!resp_body) {
+ failf(data, "hyperstream: couldn't get response body");
+ result = CURLE_RECV_ERROR;
+ break;
+ }
+ foreach = hyper_body_foreach(resp_body, hyper_body_chunk, data);
+ if(!foreach) {
+ failf(data, "hyperstream: body foreach failed");
+ result = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+ hyper_task_set_userdata(foreach, (void *)USERDATA_RESP_BODY);
+ if(HYPERE_OK != hyper_executor_push(h->exec, foreach)) {
+ failf(data, "Couldn't hyper_executor_push the body-foreach");
+ result = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+
+ hyper_response_free(resp);
+ resp = NULL;
+ } while(1);
+ if(resp)
+ hyper_response_free(resp);
+ return result;
+}
+
+static CURLcode debug_request(struct Curl_easy *data,
+ const char *method,
+ const char *path,
+ bool h2)
+{
+ char *req = aprintf("%s %s HTTP/%s\r\n", method, path,
+ h2?"2":"1.1");
+ if(!req)
+ return CURLE_OUT_OF_MEMORY;
+ Curl_debug(data, CURLINFO_HEADER_OUT, req, strlen(req));
+ free(req);
+ return CURLE_OK;
+}
+
+/*
+ * Given a full header line "name: value" (optional CRLF in the input, should
+ * be in the output), add to Hyper and send to the debug callback.
+ *
+ * Supports multiple headers.
+ */
+
+CURLcode Curl_hyper_header(struct Curl_easy *data, hyper_headers *headers,
+ const char *line)
+{
+ const char *p;
+ const char *n;
+ size_t nlen;
+ const char *v;
+ size_t vlen;
+ bool newline = TRUE;
+ int numh = 0;
+
+ if(!line)
+ return CURLE_OK;
+ n = line;
+ do {
+ size_t linelen = 0;
+
+ p = strchr(n, ':');
+ if(!p)
+ /* this is fine if we already added at least one header */
+ return numh ? CURLE_OK : CURLE_BAD_FUNCTION_ARGUMENT;
+ nlen = p - n;
+ p++; /* move past the colon */
+ while(*p == ' ')
+ p++;
+ v = p;
+ p = strchr(v, '\r');
+ if(!p) {
+ p = strchr(v, '\n');
+ if(p)
+ linelen = 1; /* LF only */
+ else {
+ p = strchr(v, '\0');
+ newline = FALSE; /* no newline */
+ }
+ }
+ else
+ linelen = 2; /* CRLF ending */
+ linelen += (p - n);
+ vlen = p - v;
+
+ if(HYPERE_OK != hyper_headers_add(headers, (uint8_t *)n, nlen,
+ (uint8_t *)v, vlen)) {
+ failf(data, "hyper refused to add header '%s'", line);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ if(data->set.verbose) {
+ char *ptr = NULL;
+ if(!newline) {
+ ptr = aprintf("%.*s\r\n", (int)linelen, line);
+ if(!ptr)
+ return CURLE_OUT_OF_MEMORY;
+ Curl_debug(data, CURLINFO_HEADER_OUT, ptr, linelen + 2);
+ free(ptr);
+ }
+ else
+ Curl_debug(data, CURLINFO_HEADER_OUT, (char *)n, linelen);
+ }
+ numh++;
+ n += linelen;
+ } while(newline);
+ return CURLE_OK;
+}
+
+static CURLcode request_target(struct Curl_easy *data,
+ struct connectdata *conn,
+ const char *method,
+ bool h2,
+ hyper_request *req)
+{
+ CURLcode result;
+ struct dynbuf r;
+
+ Curl_dyn_init(&r, DYN_HTTP_REQUEST);
+
+ result = Curl_http_target(data, conn, &r);
+ if(result)
+ return result;
+
+ if(h2 && hyper_request_set_uri_parts(req,
+ /* scheme */
+ (uint8_t *)data->state.up.scheme,
+ strlen(data->state.up.scheme),
+ /* authority */
+ (uint8_t *)conn->host.name,
+ strlen(conn->host.name),
+ /* path_and_query */
+ (uint8_t *)Curl_dyn_uptr(&r),
+ Curl_dyn_len(&r))) {
+ failf(data, "error setting uri parts to hyper");
+ result = CURLE_OUT_OF_MEMORY;
+ }
+ else if(!h2 && hyper_request_set_uri(req, (uint8_t *)Curl_dyn_uptr(&r),
+ Curl_dyn_len(&r))) {
+ failf(data, "error setting uri to hyper");
+ result = CURLE_OUT_OF_MEMORY;
+ }
+ else
+ result = debug_request(data, method, Curl_dyn_ptr(&r), h2);
+
+ Curl_dyn_free(&r);
+
+ return result;
+}
+
+static int uploadpostfields(void *userdata, hyper_context *ctx,
+ hyper_buf **chunk)
+{
+ struct Curl_easy *data = (struct Curl_easy *)userdata;
+ (void)ctx;
+ if(data->req.exp100 > EXP100_SEND_DATA) {
+ if(data->req.exp100 == EXP100_FAILED)
+ return HYPER_POLL_ERROR;
+
+ /* still waiting confirmation */
+ if(data->hyp.exp100_waker)
+ hyper_waker_free(data->hyp.exp100_waker);
+ data->hyp.exp100_waker = hyper_context_waker(ctx);
+ return HYPER_POLL_PENDING;
+ }
+ if(data->req.upload_done)
+ *chunk = NULL; /* nothing more to deliver */
+ else {
+ /* send everything off in a single go */
+ hyper_buf *copy = hyper_buf_copy(data->set.postfields,
+ (size_t)data->req.p.http->postsize);
+ if(copy)
+ *chunk = copy;
+ else {
+ data->state.hresult = CURLE_OUT_OF_MEMORY;
+ return HYPER_POLL_ERROR;
+ }
+ /* increasing the writebytecount here is a little premature but we
+ don't know exactly when the body is sent */
+ data->req.writebytecount += (size_t)data->req.p.http->postsize;
+ Curl_pgrsSetUploadCounter(data, data->req.writebytecount);
+ data->req.upload_done = TRUE;
+ }
+ return HYPER_POLL_READY;
+}
+
+static int uploadstreamed(void *userdata, hyper_context *ctx,
+ hyper_buf **chunk)
+{
+ size_t fillcount;
+ struct Curl_easy *data = (struct Curl_easy *)userdata;
+ struct connectdata *conn = (struct connectdata *)data->conn;
+ CURLcode result;
+ (void)ctx;
+
+ if(data->req.exp100 > EXP100_SEND_DATA) {
+ if(data->req.exp100 == EXP100_FAILED)
+ return HYPER_POLL_ERROR;
+
+ /* still waiting confirmation */
+ if(data->hyp.exp100_waker)
+ hyper_waker_free(data->hyp.exp100_waker);
+ data->hyp.exp100_waker = hyper_context_waker(ctx);
+ return HYPER_POLL_PENDING;
+ }
+
+ if(data->req.upload_chunky && conn->bits.authneg) {
+ fillcount = 0;
+ data->req.upload_chunky = FALSE;
+ result = CURLE_OK;
+ }
+ else {
+ result = Curl_fillreadbuffer(data, data->set.upload_buffer_size,
+ &fillcount);
+ }
+ if(result) {
+ data->state.hresult = result;
+ return HYPER_POLL_ERROR;
+ }
+ if(!fillcount) {
+ if((data->req.keepon & KEEP_SEND_PAUSE) != KEEP_SEND_PAUSE)
+ /* done! */
+ *chunk = NULL;
+ else {
+ /* paused, save a waker */
+ if(data->hyp.send_body_waker)
+ hyper_waker_free(data->hyp.send_body_waker);
+ data->hyp.send_body_waker = hyper_context_waker(ctx);
+ return HYPER_POLL_PENDING;
+ }
+ }
+ else {
+ hyper_buf *copy = hyper_buf_copy((uint8_t *)data->state.ulbuf, fillcount);
+ if(copy)
+ *chunk = copy;
+ else {
+ data->state.hresult = CURLE_OUT_OF_MEMORY;
+ return HYPER_POLL_ERROR;
+ }
+ /* increasing the writebytecount here is a little premature but we
+ don't know exactly when the body is sent */
+ data->req.writebytecount += fillcount;
+ Curl_pgrsSetUploadCounter(data, data->req.writebytecount);
+ }
+ return HYPER_POLL_READY;
+}
+
+/*
+ * bodysend() sets up headers in the outgoing request for an HTTP transfer that
+ * sends a body
+ */
+
+static CURLcode bodysend(struct Curl_easy *data,
+ struct connectdata *conn,
+ hyper_headers *headers,
+ hyper_request *hyperreq,
+ Curl_HttpReq httpreq)
+{
+ struct HTTP *http = data->req.p.http;
+ CURLcode result = CURLE_OK;
+ struct dynbuf req;
+ if((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD))
+ Curl_pgrsSetUploadSize(data, 0); /* no request body */
+ else {
+ hyper_body *body;
+ Curl_dyn_init(&req, DYN_HTTP_REQUEST);
+ result = Curl_http_bodysend(data, conn, &req, httpreq);
+
+ if(!result)
+ result = Curl_hyper_header(data, headers, Curl_dyn_ptr(&req));
+
+ Curl_dyn_free(&req);
+
+ body = hyper_body_new();
+ hyper_body_set_userdata(body, data);
+ if(data->set.postfields)
+ hyper_body_set_data_func(body, uploadpostfields);
+ else {
+ result = Curl_get_upload_buffer(data);
+ if(result) {
+ hyper_body_free(body);
+ return result;
+ }
+ /* init the "upload from here" pointer */
+ data->req.upload_fromhere = data->state.ulbuf;
+ hyper_body_set_data_func(body, uploadstreamed);
+ }
+ if(HYPERE_OK != hyper_request_set_body(hyperreq, body)) {
+ /* fail */
+ result = CURLE_OUT_OF_MEMORY;
+ }
+ }
+ http->sending = HTTPSEND_BODY;
+ return result;
+}
+
+static CURLcode cookies(struct Curl_easy *data,
+ struct connectdata *conn,
+ hyper_headers *headers)
+{
+ struct dynbuf req;
+ CURLcode result;
+ Curl_dyn_init(&req, DYN_HTTP_REQUEST);
+
+ result = Curl_http_cookies(data, conn, &req);
+ if(!result)
+ result = Curl_hyper_header(data, headers, Curl_dyn_ptr(&req));
+ Curl_dyn_free(&req);
+ return result;
+}
+
+/* called on 1xx responses */
+static void http1xx_cb(void *arg, struct hyper_response *resp)
+{
+ struct Curl_easy *data = (struct Curl_easy *)arg;
+ hyper_headers *headers = NULL;
+ CURLcode result = CURLE_OK;
+ uint16_t http_status;
+ int http_version;
+ const uint8_t *reasonp;
+ size_t reason_len;
+
+ infof(data, "Got HTTP 1xx informational");
+
+ http_status = hyper_response_status(resp);
+ http_version = hyper_response_version(resp);
+ reasonp = hyper_response_reason_phrase(resp);
+ reason_len = hyper_response_reason_phrase_len(resp);
+
+ result = status_line(data, data->conn,
+ http_status, http_version, reasonp, reason_len);
+ if(!result) {
+ headers = hyper_response_headers(resp);
+ if(!headers) {
+ failf(data, "hyperstream: couldn't get 1xx response headers");
+ result = CURLE_RECV_ERROR;
+ }
+ }
+ data->state.hresult = result;
+
+ if(!result) {
+ /* the headers are already received */
+ hyper_headers_foreach(headers, hyper_each_header, data);
+ /* this callback also sets data->state.hresult on error */
+
+ if(empty_header(data))
+ result = CURLE_OUT_OF_MEMORY;
+ }
+
+ if(data->state.hresult)
+ infof(data, "ERROR in 1xx, bail out");
+}
+
+/*
+ * Curl_http() gets called from the generic multi_do() function when an HTTP
+ * request is to be performed. This creates and sends a properly constructed
+ * HTTP request.
+ */
+CURLcode Curl_http(struct Curl_easy *data, bool *done)
+{
+ struct connectdata *conn = data->conn;
+ struct hyptransfer *h = &data->hyp;
+ hyper_io *io = NULL;
+ hyper_clientconn_options *options = NULL;
+ hyper_task *task = NULL; /* for the handshake */
+ hyper_task *sendtask = NULL; /* for the send */
+ hyper_clientconn *client = NULL;
+ hyper_request *req = NULL;
+ hyper_headers *headers = NULL;
+ hyper_task *handshake = NULL;
+ CURLcode result;
+ const char *p_accept; /* Accept: string */
+ const char *method;
+ Curl_HttpReq httpreq;
+ bool h2 = FALSE;
+ const char *te = NULL; /* transfer-encoding */
+ hyper_code rc;
+
+ /* Always consider the DO phase done after this function call, even if there
+ may be parts of the request that is not yet sent, since we can deal with
+ the rest of the request in the PERFORM phase. */
+ *done = TRUE;
+
+ infof(data, "Time for the Hyper dance");
+ memset(h, 0, sizeof(struct hyptransfer));
+
+ result = Curl_http_host(data, conn);
+ if(result)
+ return result;
+
+ Curl_http_method(data, conn, &method, &httpreq);
+
+ /* setup the authentication headers */
+ {
+ char *pq = NULL;
+ if(data->state.up.query) {
+ pq = aprintf("%s?%s", data->state.up.path, data->state.up.query);
+ if(!pq)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ result = Curl_http_output_auth(data, conn, method, httpreq,
+ (pq ? pq : data->state.up.path), FALSE);
+ free(pq);
+ if(result)
+ return result;
+ }
+
+ result = Curl_http_resume(data, conn, httpreq);
+ if(result)
+ return result;
+
+ result = Curl_http_range(data, httpreq);
+ if(result)
+ return result;
+
+ result = Curl_http_useragent(data);
+ if(result)
+ return result;
+
+ io = hyper_io_new();
+ if(!io) {
+ failf(data, "Couldn't create hyper IO");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ /* tell Hyper how to read/write network data */
+ hyper_io_set_userdata(io, data);
+ hyper_io_set_read(io, Curl_hyper_recv);
+ hyper_io_set_write(io, Curl_hyper_send);
+
+ /* create an executor to poll futures */
+ if(!h->exec) {
+ h->exec = hyper_executor_new();
+ if(!h->exec) {
+ failf(data, "Couldn't create hyper executor");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ }
+
+ options = hyper_clientconn_options_new();
+ if(!options) {
+ failf(data, "Couldn't create hyper client options");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ if(conn->alpn == CURL_HTTP_VERSION_2) {
+ hyper_clientconn_options_http2(options, 1);
+ h2 = TRUE;
+ }
+ hyper_clientconn_options_set_preserve_header_case(options, 1);
+ hyper_clientconn_options_set_preserve_header_order(options, 1);
+ hyper_clientconn_options_http1_allow_multiline_headers(options, 1);
+
+ hyper_clientconn_options_exec(options, h->exec);
+
+ /* "Both the `io` and the `options` are consumed in this function call" */
+ handshake = hyper_clientconn_handshake(io, options);
+ if(!handshake) {
+ failf(data, "Couldn't create hyper client handshake");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ io = NULL;
+ options = NULL;
+
+ if(HYPERE_OK != hyper_executor_push(h->exec, handshake)) {
+ failf(data, "Couldn't hyper_executor_push the handshake");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ handshake = NULL; /* ownership passed on */
+
+ task = hyper_executor_poll(h->exec);
+ if(!task) {
+ failf(data, "Couldn't hyper_executor_poll the handshake");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+
+ client = hyper_task_value(task);
+ hyper_task_free(task);
+
+ req = hyper_request_new();
+ if(!req) {
+ failf(data, "Couldn't hyper_request_new");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+
+ if(!Curl_use_http_1_1plus(data, conn)) {
+ if(HYPERE_OK != hyper_request_set_version(req,
+ HYPER_HTTP_VERSION_1_0)) {
+ failf(data, "error setting HTTP version");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ }
+ else {
+ if(!h2 && !data->state.disableexpect) {
+ data->state.expect100header = TRUE;
+ }
+ }
+
+ if(hyper_request_set_method(req, (uint8_t *)method, strlen(method))) {
+ failf(data, "error setting method");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+
+ result = request_target(data, conn, method, h2, req);
+ if(result)
+ goto error;
+
+ headers = hyper_request_headers(req);
+ if(!headers) {
+ failf(data, "hyper_request_headers");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+
+ rc = hyper_request_on_informational(req, http1xx_cb, data);
+ if(rc) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+
+ result = Curl_http_body(data, conn, httpreq, &te);
+ if(result)
+ goto error;
+
+ if(!h2) {
+ if(data->state.aptr.host) {
+ result = Curl_hyper_header(data, headers, data->state.aptr.host);
+ if(result)
+ goto error;
+ }
+ }
+ else {
+ /* For HTTP/2, we show the Host: header as if we sent it, to make it look
+ like for HTTP/1 but it isn't actually sent since :authority is then
+ used. */
+ Curl_debug(data, CURLINFO_HEADER_OUT, data->state.aptr.host,
+ strlen(data->state.aptr.host));
+ }
+
+ if(data->state.aptr.proxyuserpwd) {
+ result = Curl_hyper_header(data, headers, data->state.aptr.proxyuserpwd);
+ if(result)
+ goto error;
+ }
+
+ if(data->state.aptr.userpwd) {
+ result = Curl_hyper_header(data, headers, data->state.aptr.userpwd);
+ if(result)
+ goto error;
+ }
+
+ if((data->state.use_range && data->state.aptr.rangeline)) {
+ result = Curl_hyper_header(data, headers, data->state.aptr.rangeline);
+ if(result)
+ goto error;
+ }
+
+ if(data->set.str[STRING_USERAGENT] &&
+ *data->set.str[STRING_USERAGENT] &&
+ data->state.aptr.uagent) {
+ result = Curl_hyper_header(data, headers, data->state.aptr.uagent);
+ if(result)
+ goto error;
+ }
+
+ p_accept = Curl_checkheaders(data,
+ STRCONST("Accept"))?NULL:"Accept: */*\r\n";
+ if(p_accept) {
+ result = Curl_hyper_header(data, headers, p_accept);
+ if(result)
+ goto error;
+ }
+ if(te) {
+ result = Curl_hyper_header(data, headers, te);
+ if(result)
+ goto error;
+ }
+
+#ifndef CURL_DISABLE_ALTSVC
+ if(conn->bits.altused && !Curl_checkheaders(data, STRCONST("Alt-Used"))) {
+ char *altused = aprintf("Alt-Used: %s:%d\r\n",
+ conn->conn_to_host.name, conn->conn_to_port);
+ if(!altused) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ result = Curl_hyper_header(data, headers, altused);
+ if(result)
+ goto error;
+ free(altused);
+ }
+#endif
+
+#ifndef CURL_DISABLE_PROXY
+ if(conn->bits.httpproxy && !conn->bits.tunnel_proxy &&
+ !Curl_checkheaders(data, STRCONST("Proxy-Connection")) &&
+ !Curl_checkProxyheaders(data, conn, STRCONST("Proxy-Connection"))) {
+ result = Curl_hyper_header(data, headers, "Proxy-Connection: Keep-Alive");
+ if(result)
+ goto error;
+ }
+#endif
+
+ Curl_safefree(data->state.aptr.ref);
+ if(data->state.referer && !Curl_checkheaders(data, STRCONST("Referer"))) {
+ data->state.aptr.ref = aprintf("Referer: %s\r\n", data->state.referer);
+ if(!data->state.aptr.ref)
+ result = CURLE_OUT_OF_MEMORY;
+ else
+ result = Curl_hyper_header(data, headers, data->state.aptr.ref);
+ if(result)
+ goto error;
+ }
+
+#ifdef HAVE_LIBZ
+ /* we only consider transfer-encoding magic if libz support is built-in */
+ result = Curl_transferencode(data);
+ if(result)
+ goto error;
+ result = Curl_hyper_header(data, headers, data->state.aptr.te);
+ if(result)
+ goto error;
+#endif
+
+ if(!Curl_checkheaders(data, STRCONST("Accept-Encoding")) &&
+ data->set.str[STRING_ENCODING]) {
+ Curl_safefree(data->state.aptr.accept_encoding);
+ data->state.aptr.accept_encoding =
+ aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
+ if(!data->state.aptr.accept_encoding)
+ result = CURLE_OUT_OF_MEMORY;
+ else
+ result = Curl_hyper_header(data, headers,
+ data->state.aptr.accept_encoding);
+ if(result)
+ goto error;
+ }
+ else
+ Curl_safefree(data->state.aptr.accept_encoding);
+
+ result = cookies(data, conn, headers);
+ if(result)
+ goto error;
+
+ if(!result && conn->handler->protocol&(CURLPROTO_WS|CURLPROTO_WSS))
+ result = Curl_ws_request(data, headers);
+
+ result = Curl_add_timecondition(data, headers);
+ if(result)
+ goto error;
+
+ result = Curl_add_custom_headers(data, FALSE, headers);
+ if(result)
+ goto error;
+
+ result = bodysend(data, conn, headers, req, httpreq);
+ if(result)
+ goto error;
+
+ Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"\r\n", 2);
+
+ if(data->req.upload_chunky && conn->bits.authneg) {
+ data->req.upload_chunky = TRUE;
+ }
+ else {
+ data->req.upload_chunky = FALSE;
+ }
+ sendtask = hyper_clientconn_send(client, req);
+ if(!sendtask) {
+ failf(data, "hyper_clientconn_send");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ req = NULL;
+
+ if(HYPERE_OK != hyper_executor_push(h->exec, sendtask)) {
+ failf(data, "Couldn't hyper_executor_push the send");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ sendtask = NULL; /* ownership passed on */
+
+ hyper_clientconn_free(client);
+ client = NULL;
+
+ if((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) {
+ /* HTTP GET/HEAD download */
+ Curl_pgrsSetUploadSize(data, 0); /* nothing */
+ Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1);
+ }
+ conn->datastream = Curl_hyper_stream;
+ if(data->state.expect100header)
+ /* Timeout count starts now since with Hyper we don't know exactly when
+ the full request has been sent. */
+ data->req.start100 = Curl_now();
+
+ /* clear userpwd and proxyuserpwd to avoid reusing old credentials
+ * from reused connections */
+ Curl_safefree(data->state.aptr.userpwd);
+ Curl_safefree(data->state.aptr.proxyuserpwd);
+ return CURLE_OK;
+error:
+ DEBUGASSERT(result);
+ if(io)
+ hyper_io_free(io);
+
+ if(options)
+ hyper_clientconn_options_free(options);
+
+ if(handshake)
+ hyper_task_free(handshake);
+
+ if(client)
+ hyper_clientconn_free(client);
+
+ if(req)
+ hyper_request_free(req);
+
+ return result;
+}
+
+void Curl_hyper_done(struct Curl_easy *data)
+{
+ struct hyptransfer *h = &data->hyp;
+ if(h->exec) {
+ hyper_executor_free(h->exec);
+ h->exec = NULL;
+ }
+ if(h->read_waker) {
+ hyper_waker_free(h->read_waker);
+ h->read_waker = NULL;
+ }
+ if(h->write_waker) {
+ hyper_waker_free(h->write_waker);
+ h->write_waker = NULL;
+ }
+ if(h->exp100_waker) {
+ hyper_waker_free(h->exp100_waker);
+ h->exp100_waker = NULL;
+ }
+}
+
+#endif /* !defined(CURL_DISABLE_HTTP) && defined(USE_HYPER) */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/c-hyper.h b/iotdb-client/odbc/deps/curl-src/lib/c-hyper.h
new file mode 100644
index 0000000000000..0c7de90b70b72
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/c-hyper.h
@@ -0,0 +1,59 @@
+#ifndef HEADER_CURL_HYPER_H
+#define HEADER_CURL_HYPER_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_HYPER)
+
+#include
+
+/* per-transfer data for the Hyper backend */
+struct hyptransfer {
+ hyper_waker *write_waker;
+ hyper_waker *read_waker;
+ const hyper_executor *exec;
+ hyper_waker *exp100_waker;
+ hyper_waker *send_body_waker;
+};
+
+size_t Curl_hyper_recv(void *userp, hyper_context *ctx,
+ uint8_t *buf, size_t buflen);
+size_t Curl_hyper_send(void *userp, hyper_context *ctx,
+ const uint8_t *buf, size_t buflen);
+CURLcode Curl_hyper_stream(struct Curl_easy *data,
+ struct connectdata *conn,
+ int *didwhat,
+ bool *done,
+ int select_res);
+
+CURLcode Curl_hyper_header(struct Curl_easy *data, hyper_headers *headers,
+ const char *line);
+void Curl_hyper_done(struct Curl_easy *);
+
+#else
+#define Curl_hyper_done(x)
+
+#endif /* !defined(CURL_DISABLE_HTTP) && defined(USE_HYPER) */
+#endif /* HEADER_CURL_HYPER_H */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/cf-h1-proxy.c b/iotdb-client/odbc/deps/curl-src/lib/cf-h1-proxy.c
new file mode 100644
index 0000000000000..674802114cee1
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/cf-h1-proxy.c
@@ -0,0 +1,1119 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)
+
+#include
+#ifdef USE_HYPER
+#include
+#endif
+#include "urldata.h"
+#include "dynbuf.h"
+#include "sendf.h"
+#include "http.h"
+#include "http1.h"
+#include "http_proxy.h"
+#include "url.h"
+#include "select.h"
+#include "progress.h"
+#include "cfilters.h"
+#include "cf-h1-proxy.h"
+#include "connect.h"
+#include "curl_trc.h"
+#include "curlx.h"
+#include "vtls/vtls.h"
+#include "transfer.h"
+#include "multiif.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+
+typedef enum {
+ H1_TUNNEL_INIT, /* init/default/no tunnel state */
+ H1_TUNNEL_CONNECT, /* CONNECT request is being send */
+ H1_TUNNEL_RECEIVE, /* CONNECT answer is being received */
+ H1_TUNNEL_RESPONSE, /* CONNECT response received completely */
+ H1_TUNNEL_ESTABLISHED,
+ H1_TUNNEL_FAILED
+} h1_tunnel_state;
+
+/* struct for HTTP CONNECT tunneling */
+struct h1_tunnel_state {
+ struct HTTP CONNECT;
+ struct dynbuf rcvbuf;
+ struct dynbuf request_data;
+ size_t nsent;
+ size_t headerlines;
+ enum keeponval {
+ KEEPON_DONE,
+ KEEPON_CONNECT,
+ KEEPON_IGNORE
+ } keepon;
+ curl_off_t cl; /* size of content to read and ignore */
+ h1_tunnel_state tunnel_state;
+ BIT(chunked_encoding);
+ BIT(close_connection);
+};
+
+
+static bool tunnel_is_established(struct h1_tunnel_state *ts)
+{
+ return ts && (ts->tunnel_state == H1_TUNNEL_ESTABLISHED);
+}
+
+static bool tunnel_is_failed(struct h1_tunnel_state *ts)
+{
+ return ts && (ts->tunnel_state == H1_TUNNEL_FAILED);
+}
+
+static CURLcode tunnel_reinit(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct h1_tunnel_state *ts)
+{
+ (void)data;
+ (void)cf;
+ DEBUGASSERT(ts);
+ Curl_dyn_reset(&ts->rcvbuf);
+ Curl_dyn_reset(&ts->request_data);
+ ts->tunnel_state = H1_TUNNEL_INIT;
+ ts->keepon = KEEPON_CONNECT;
+ ts->cl = 0;
+ ts->close_connection = FALSE;
+ return CURLE_OK;
+}
+
+static CURLcode tunnel_init(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct h1_tunnel_state **pts)
+{
+ struct h1_tunnel_state *ts;
+ CURLcode result;
+
+ if(cf->conn->handler->flags & PROTOPT_NOTCPPROXY) {
+ failf(data, "%s cannot be done over CONNECT", cf->conn->handler->scheme);
+ return CURLE_UNSUPPORTED_PROTOCOL;
+ }
+
+ /* we might need the upload buffer for streaming a partial request */
+ result = Curl_get_upload_buffer(data);
+ if(result)
+ return result;
+
+ ts = calloc(1, sizeof(*ts));
+ if(!ts)
+ return CURLE_OUT_OF_MEMORY;
+
+ infof(data, "allocate connect buffer");
+
+ Curl_dyn_init(&ts->rcvbuf, DYN_PROXY_CONNECT_HEADERS);
+ Curl_dyn_init(&ts->request_data, DYN_HTTP_REQUEST);
+
+ *pts = ts;
+ connkeep(cf->conn, "HTTP proxy CONNECT");
+ return tunnel_reinit(cf, data, ts);
+}
+
+static void h1_tunnel_go_state(struct Curl_cfilter *cf,
+ struct h1_tunnel_state *ts,
+ h1_tunnel_state new_state,
+ struct Curl_easy *data)
+{
+ if(ts->tunnel_state == new_state)
+ return;
+ /* leaving this one */
+ switch(ts->tunnel_state) {
+ case H1_TUNNEL_CONNECT:
+ data->req.ignorebody = FALSE;
+ break;
+ default:
+ break;
+ }
+ /* entering this one */
+ switch(new_state) {
+ case H1_TUNNEL_INIT:
+ CURL_TRC_CF(data, cf, "new tunnel state 'init'");
+ tunnel_reinit(cf, data, ts);
+ break;
+
+ case H1_TUNNEL_CONNECT:
+ CURL_TRC_CF(data, cf, "new tunnel state 'connect'");
+ ts->tunnel_state = H1_TUNNEL_CONNECT;
+ ts->keepon = KEEPON_CONNECT;
+ Curl_dyn_reset(&ts->rcvbuf);
+ break;
+
+ case H1_TUNNEL_RECEIVE:
+ CURL_TRC_CF(data, cf, "new tunnel state 'receive'");
+ ts->tunnel_state = H1_TUNNEL_RECEIVE;
+ break;
+
+ case H1_TUNNEL_RESPONSE:
+ CURL_TRC_CF(data, cf, "new tunnel state 'response'");
+ ts->tunnel_state = H1_TUNNEL_RESPONSE;
+ break;
+
+ case H1_TUNNEL_ESTABLISHED:
+ CURL_TRC_CF(data, cf, "new tunnel state 'established'");
+ infof(data, "CONNECT phase completed");
+ data->state.authproxy.done = TRUE;
+ data->state.authproxy.multipass = FALSE;
+ /* FALLTHROUGH */
+ case H1_TUNNEL_FAILED:
+ if(new_state == H1_TUNNEL_FAILED)
+ CURL_TRC_CF(data, cf, "new tunnel state 'failed'");
+ ts->tunnel_state = new_state;
+ Curl_dyn_reset(&ts->rcvbuf);
+ Curl_dyn_reset(&ts->request_data);
+ /* restore the protocol pointer */
+ data->info.httpcode = 0; /* clear it as it might've been used for the
+ proxy */
+ /* If a proxy-authorization header was used for the proxy, then we should
+ make sure that it isn't accidentally used for the document request
+ after we've connected. So let's free and clear it here. */
+ Curl_safefree(data->state.aptr.proxyuserpwd);
+#ifdef USE_HYPER
+ data->state.hconnect = FALSE;
+#endif
+ break;
+ }
+}
+
+static void tunnel_free(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ struct h1_tunnel_state *ts = cf->ctx;
+ if(ts) {
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data);
+ Curl_dyn_free(&ts->rcvbuf);
+ Curl_dyn_free(&ts->request_data);
+ free(ts);
+ cf->ctx = NULL;
+ }
+}
+
+#ifndef USE_HYPER
+static CURLcode start_CONNECT(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct h1_tunnel_state *ts)
+{
+ struct httpreq *req = NULL;
+ int http_minor;
+ CURLcode result;
+
+ /* This only happens if we've looped here due to authentication
+ reasons, and we don't really use the newly cloned URL here
+ then. Just free() it. */
+ Curl_safefree(data->req.newurl);
+
+ result = Curl_http_proxy_create_CONNECT(&req, cf, data, 1);
+ if(result)
+ goto out;
+
+ infof(data, "Establish HTTP proxy tunnel to %s", req->authority);
+
+ Curl_dyn_reset(&ts->request_data);
+ ts->nsent = 0;
+ ts->headerlines = 0;
+ http_minor = (cf->conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ? 0 : 1;
+
+ result = Curl_h1_req_write_head(req, http_minor, &ts->request_data);
+
+out:
+ if(result)
+ failf(data, "Failed sending CONNECT to proxy");
+ if(req)
+ Curl_http_req_free(req);
+ return result;
+}
+
+static CURLcode send_CONNECT(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct h1_tunnel_state *ts,
+ bool *done)
+{
+ char *buf = Curl_dyn_ptr(&ts->request_data);
+ size_t request_len = Curl_dyn_len(&ts->request_data);
+ size_t blen = request_len;
+ CURLcode result = CURLE_OK;
+ ssize_t nwritten;
+
+ if(blen <= ts->nsent)
+ goto out; /* we are done */
+
+ blen -= ts->nsent;
+ buf += ts->nsent;
+
+ nwritten = cf->next->cft->do_send(cf->next, data, buf, blen, &result);
+ if(nwritten < 0) {
+ if(result == CURLE_AGAIN) {
+ result = CURLE_OK;
+ }
+ goto out;
+ }
+
+ DEBUGASSERT(blen >= (size_t)nwritten);
+ ts->nsent += (size_t)nwritten;
+ Curl_debug(data, CURLINFO_HEADER_OUT, buf, (size_t)nwritten);
+
+out:
+ if(result)
+ failf(data, "Failed sending CONNECT to proxy");
+ *done = (!result && (ts->nsent >= request_len));
+ return result;
+}
+
+static CURLcode on_resp_header(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct h1_tunnel_state *ts,
+ const char *header)
+{
+ CURLcode result = CURLE_OK;
+ struct SingleRequest *k = &data->req;
+ (void)cf;
+
+ if((checkprefix("WWW-Authenticate:", header) &&
+ (401 == k->httpcode)) ||
+ (checkprefix("Proxy-authenticate:", header) &&
+ (407 == k->httpcode))) {
+
+ bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
+ char *auth = Curl_copy_header_value(header);
+ if(!auth)
+ return CURLE_OUT_OF_MEMORY;
+
+ CURL_TRC_CF(data, cf, "CONNECT: fwd auth header '%s'", header);
+ result = Curl_http_input_auth(data, proxy, auth);
+
+ free(auth);
+
+ if(result)
+ return result;
+ }
+ else if(checkprefix("Content-Length:", header)) {
+ if(k->httpcode/100 == 2) {
+ /* A client MUST ignore any Content-Length or Transfer-Encoding
+ header fields received in a successful response to CONNECT.
+ "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */
+ infof(data, "Ignoring Content-Length in CONNECT %03d response",
+ k->httpcode);
+ }
+ else {
+ (void)curlx_strtoofft(header + strlen("Content-Length:"),
+ NULL, 10, &ts->cl);
+ }
+ }
+ else if(Curl_compareheader(header,
+ STRCONST("Connection:"), STRCONST("close")))
+ ts->close_connection = TRUE;
+ else if(checkprefix("Transfer-Encoding:", header)) {
+ if(k->httpcode/100 == 2) {
+ /* A client MUST ignore any Content-Length or Transfer-Encoding
+ header fields received in a successful response to CONNECT.
+ "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */
+ infof(data, "Ignoring Transfer-Encoding in "
+ "CONNECT %03d response", k->httpcode);
+ }
+ else if(Curl_compareheader(header,
+ STRCONST("Transfer-Encoding:"),
+ STRCONST("chunked"))) {
+ infof(data, "CONNECT responded chunked");
+ ts->chunked_encoding = TRUE;
+ /* init our chunky engine */
+ Curl_httpchunk_init(data);
+ }
+ }
+ else if(Curl_compareheader(header,
+ STRCONST("Proxy-Connection:"),
+ STRCONST("close")))
+ ts->close_connection = TRUE;
+ else if(!strncmp(header, "HTTP/1.", 7) &&
+ ((header[7] == '0') || (header[7] == '1')) &&
+ (header[8] == ' ') &&
+ ISDIGIT(header[9]) && ISDIGIT(header[10]) && ISDIGIT(header[11]) &&
+ !ISDIGIT(header[12])) {
+ /* store the HTTP code from the proxy */
+ data->info.httpproxycode = k->httpcode = (header[9] - '0') * 100 +
+ (header[10] - '0') * 10 + (header[11] - '0');
+ }
+ return result;
+}
+
+static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct h1_tunnel_state *ts,
+ bool *done)
+{
+ CURLcode result = CURLE_OK;
+ struct SingleRequest *k = &data->req;
+ curl_socket_t tunnelsocket = Curl_conn_cf_get_socket(cf, data);
+ char *linep;
+ size_t perline;
+ int error;
+
+#define SELECT_OK 0
+#define SELECT_ERROR 1
+
+ error = SELECT_OK;
+ *done = FALSE;
+
+ if(!Curl_conn_data_pending(data, cf->sockindex))
+ return CURLE_OK;
+
+ while(ts->keepon) {
+ ssize_t gotbytes;
+ char byte;
+
+ /* Read one byte at a time to avoid a race condition. Wait at most one
+ second before looping to ensure continuous pgrsUpdates. */
+ result = Curl_read(data, tunnelsocket, &byte, 1, &gotbytes);
+ if(result == CURLE_AGAIN)
+ /* socket buffer drained, return */
+ return CURLE_OK;
+
+ if(Curl_pgrsUpdate(data))
+ return CURLE_ABORTED_BY_CALLBACK;
+
+ if(result) {
+ ts->keepon = KEEPON_DONE;
+ break;
+ }
+
+ if(gotbytes <= 0) {
+ if(data->set.proxyauth && data->state.authproxy.avail &&
+ data->state.aptr.proxyuserpwd) {
+ /* proxy auth was requested and there was proxy auth available,
+ then deem this as "mere" proxy disconnect */
+ ts->close_connection = TRUE;
+ infof(data, "Proxy CONNECT connection closed");
+ }
+ else {
+ error = SELECT_ERROR;
+ failf(data, "Proxy CONNECT aborted");
+ }
+ ts->keepon = KEEPON_DONE;
+ break;
+ }
+
+ if(ts->keepon == KEEPON_IGNORE) {
+ /* This means we are currently ignoring a response-body */
+
+ if(ts->cl) {
+ /* A Content-Length based body: simply count down the counter
+ and make sure to break out of the loop when we're done! */
+ ts->cl--;
+ if(ts->cl <= 0) {
+ ts->keepon = KEEPON_DONE;
+ break;
+ }
+ }
+ else {
+ /* chunked-encoded body, so we need to do the chunked dance
+ properly to know when the end of the body is reached */
+ CHUNKcode r;
+ CURLcode extra;
+ ssize_t tookcareof = 0;
+
+ /* now parse the chunked piece of data so that we can
+ properly tell when the stream ends */
+ r = Curl_httpchunk_read(data, &byte, 1, &tookcareof, &extra);
+ if(r == CHUNKE_STOP) {
+ /* we're done reading chunks! */
+ infof(data, "chunk reading DONE");
+ ts->keepon = KEEPON_DONE;
+ }
+ }
+ continue;
+ }
+
+ if(Curl_dyn_addn(&ts->rcvbuf, &byte, 1)) {
+ failf(data, "CONNECT response too large");
+ return CURLE_RECV_ERROR;
+ }
+
+ /* if this is not the end of a header line then continue */
+ if(byte != 0x0a)
+ continue;
+
+ ts->headerlines++;
+ linep = Curl_dyn_ptr(&ts->rcvbuf);
+ perline = Curl_dyn_len(&ts->rcvbuf); /* amount of bytes in this line */
+
+ /* output debug if that is requested */
+ Curl_debug(data, CURLINFO_HEADER_IN, linep, perline);
+
+ if(!data->set.suppress_connect_headers) {
+ /* send the header to the callback */
+ int writetype = CLIENTWRITE_HEADER | CLIENTWRITE_CONNECT |
+ (ts->headerlines == 1 ? CLIENTWRITE_STATUS : 0);
+
+ result = Curl_client_write(data, writetype, linep, perline);
+ if(result)
+ return result;
+ }
+
+ result = Curl_bump_headersize(data, perline, TRUE);
+ if(result)
+ return result;
+
+ /* Newlines are CRLF, so the CR is ignored as the line isn't
+ really terminated until the LF comes. Treat a following CR
+ as end-of-headers as well.*/
+
+ if(('\r' == linep[0]) ||
+ ('\n' == linep[0])) {
+ /* end of response-headers from the proxy */
+
+ if((407 == k->httpcode) && !data->state.authproblem) {
+ /* If we get a 407 response code with content length
+ when we have no auth problem, we must ignore the
+ whole response-body */
+ ts->keepon = KEEPON_IGNORE;
+
+ if(ts->cl) {
+ infof(data, "Ignore %" CURL_FORMAT_CURL_OFF_T
+ " bytes of response-body", ts->cl);
+ }
+ else if(ts->chunked_encoding) {
+ CHUNKcode r;
+ CURLcode extra;
+
+ infof(data, "Ignore chunked response-body");
+
+ /* We set ignorebody true here since the chunked decoder
+ function will acknowledge that. Pay attention so that this is
+ cleared again when this function returns! */
+ k->ignorebody = TRUE;
+
+ if(linep[1] == '\n')
+ /* this can only be a LF if the letter at index 0 was a CR */
+ linep++;
+
+ /* now parse the chunked piece of data so that we can properly
+ tell when the stream ends */
+ r = Curl_httpchunk_read(data, linep + 1, 1, &gotbytes,
+ &extra);
+ if(r == CHUNKE_STOP) {
+ /* we're done reading chunks! */
+ infof(data, "chunk reading DONE");
+ ts->keepon = KEEPON_DONE;
+ }
+ }
+ else {
+ /* without content-length or chunked encoding, we
+ can't keep the connection alive since the close is
+ the end signal so we bail out at once instead */
+ CURL_TRC_CF(data, cf, "CONNECT: no content-length or chunked");
+ ts->keepon = KEEPON_DONE;
+ }
+ }
+ else {
+ ts->keepon = KEEPON_DONE;
+ }
+
+ DEBUGASSERT(ts->keepon == KEEPON_IGNORE
+ || ts->keepon == KEEPON_DONE);
+ continue;
+ }
+
+ result = on_resp_header(cf, data, ts, linep);
+ if(result)
+ return result;
+
+ Curl_dyn_reset(&ts->rcvbuf);
+ } /* while there's buffer left and loop is requested */
+
+ if(error)
+ result = CURLE_RECV_ERROR;
+ *done = (ts->keepon == KEEPON_DONE);
+ if(!result && *done && data->info.httpproxycode/100 != 2) {
+ /* Deal with the possibly already received authenticate
+ headers. 'newurl' is set to a new URL if we must loop. */
+ result = Curl_http_auth_act(data);
+ }
+ return result;
+}
+
+#else /* USE_HYPER */
+
+static CURLcode CONNECT_host(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ char **pauthority,
+ char **phost_header)
+{
+ const char *hostname;
+ int port;
+ bool ipv6_ip;
+ CURLcode result;
+ char *authority; /* for CONNECT, the destination host + port */
+ char *host_header = NULL; /* Host: authority */
+
+ result = Curl_http_proxy_get_destination(cf, &hostname, &port, &ipv6_ip);
+ if(result)
+ return result;
+
+ authority = aprintf("%s%s%s:%d", ipv6_ip?"[":"", hostname, ipv6_ip?"]":"",
+ port);
+ if(!authority)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* If user is not overriding the Host header later */
+ if(!Curl_checkProxyheaders(data, cf->conn, STRCONST("Host"))) {
+ host_header = aprintf("Host: %s\r\n", authority);
+ if(!host_header) {
+ free(authority);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+ *pauthority = authority;
+ *phost_header = host_header;
+ return CURLE_OK;
+}
+
+/* The Hyper version of CONNECT */
+static CURLcode start_CONNECT(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct h1_tunnel_state *ts)
+{
+ struct connectdata *conn = cf->conn;
+ struct hyptransfer *h = &data->hyp;
+ curl_socket_t tunnelsocket = Curl_conn_cf_get_socket(cf, data);
+ hyper_io *io = NULL;
+ hyper_request *req = NULL;
+ hyper_headers *headers = NULL;
+ hyper_clientconn_options *options = NULL;
+ hyper_task *handshake = NULL;
+ hyper_task *task = NULL; /* for the handshake */
+ hyper_clientconn *client = NULL;
+ hyper_task *sendtask = NULL; /* for the send */
+ char *authority = NULL; /* for CONNECT */
+ char *host_header = NULL; /* Host: */
+ CURLcode result = CURLE_OUT_OF_MEMORY;
+ (void)ts;
+
+ io = hyper_io_new();
+ if(!io) {
+ failf(data, "Couldn't create hyper IO");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ /* tell Hyper how to read/write network data */
+ hyper_io_set_userdata(io, data);
+ hyper_io_set_read(io, Curl_hyper_recv);
+ hyper_io_set_write(io, Curl_hyper_send);
+ conn->sockfd = tunnelsocket;
+
+ data->state.hconnect = TRUE;
+
+ /* create an executor to poll futures */
+ if(!h->exec) {
+ h->exec = hyper_executor_new();
+ if(!h->exec) {
+ failf(data, "Couldn't create hyper executor");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ }
+
+ options = hyper_clientconn_options_new();
+ if(!options) {
+ failf(data, "Couldn't create hyper client options");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ hyper_clientconn_options_set_preserve_header_case(options, 1);
+ hyper_clientconn_options_set_preserve_header_order(options, 1);
+
+ hyper_clientconn_options_exec(options, h->exec);
+
+ /* "Both the `io` and the `options` are consumed in this function
+ call" */
+ handshake = hyper_clientconn_handshake(io, options);
+ if(!handshake) {
+ failf(data, "Couldn't create hyper client handshake");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ io = NULL;
+ options = NULL;
+
+ if(HYPERE_OK != hyper_executor_push(h->exec, handshake)) {
+ failf(data, "Couldn't hyper_executor_push the handshake");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ handshake = NULL; /* ownership passed on */
+
+ task = hyper_executor_poll(h->exec);
+ if(!task) {
+ failf(data, "Couldn't hyper_executor_poll the handshake");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+
+ client = hyper_task_value(task);
+ hyper_task_free(task);
+
+ req = hyper_request_new();
+ if(!req) {
+ failf(data, "Couldn't hyper_request_new");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ if(hyper_request_set_method(req, (uint8_t *)"CONNECT",
+ strlen("CONNECT"))) {
+ failf(data, "error setting method");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+
+ /* This only happens if we've looped here due to authentication
+ reasons, and we don't really use the newly cloned URL here
+ then. Just free() it. */
+ Curl_safefree(data->req.newurl);
+
+ result = CONNECT_host(cf, data, &authority, &host_header);
+ if(result)
+ goto error;
+
+ infof(data, "Establish HTTP proxy tunnel to %s", authority);
+
+ if(hyper_request_set_uri(req, (uint8_t *)authority,
+ strlen(authority))) {
+ failf(data, "error setting path");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ if(data->set.verbose) {
+ char *se = aprintf("CONNECT %s HTTP/1.1\r\n", authority);
+ if(!se) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ Curl_debug(data, CURLINFO_HEADER_OUT, se, strlen(se));
+ free(se);
+ }
+ /* Setup the proxy-authorization header, if any */
+ result = Curl_http_output_auth(data, conn, "CONNECT", HTTPREQ_GET,
+ authority, TRUE);
+ if(result)
+ goto error;
+ Curl_safefree(authority);
+
+ /* default is 1.1 */
+ if((conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) &&
+ (HYPERE_OK != hyper_request_set_version(req,
+ HYPER_HTTP_VERSION_1_0))) {
+ failf(data, "error setting HTTP version");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+
+ headers = hyper_request_headers(req);
+ if(!headers) {
+ failf(data, "hyper_request_headers");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ if(host_header) {
+ result = Curl_hyper_header(data, headers, host_header);
+ if(result)
+ goto error;
+ Curl_safefree(host_header);
+ }
+
+ if(data->state.aptr.proxyuserpwd) {
+ result = Curl_hyper_header(data, headers,
+ data->state.aptr.proxyuserpwd);
+ if(result)
+ goto error;
+ }
+
+ if(!Curl_checkProxyheaders(data, conn, STRCONST("User-Agent")) &&
+ data->set.str[STRING_USERAGENT]) {
+ struct dynbuf ua;
+ Curl_dyn_init(&ua, DYN_HTTP_REQUEST);
+ result = Curl_dyn_addf(&ua, "User-Agent: %s\r\n",
+ data->set.str[STRING_USERAGENT]);
+ if(result)
+ goto error;
+ result = Curl_hyper_header(data, headers, Curl_dyn_ptr(&ua));
+ if(result)
+ goto error;
+ Curl_dyn_free(&ua);
+ }
+
+ if(!Curl_checkProxyheaders(data, conn, STRCONST("Proxy-Connection"))) {
+ result = Curl_hyper_header(data, headers,
+ "Proxy-Connection: Keep-Alive");
+ if(result)
+ goto error;
+ }
+
+ result = Curl_add_custom_headers(data, TRUE, headers);
+ if(result)
+ goto error;
+
+ sendtask = hyper_clientconn_send(client, req);
+ if(!sendtask) {
+ failf(data, "hyper_clientconn_send");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ req = NULL;
+
+ if(HYPERE_OK != hyper_executor_push(h->exec, sendtask)) {
+ failf(data, "Couldn't hyper_executor_push the send");
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ sendtask = NULL; /* ownership passed on */
+
+ hyper_clientconn_free(client);
+ client = NULL;
+
+error:
+ free(host_header);
+ free(authority);
+ if(io)
+ hyper_io_free(io);
+ if(options)
+ hyper_clientconn_options_free(options);
+ if(handshake)
+ hyper_task_free(handshake);
+ if(client)
+ hyper_clientconn_free(client);
+ if(req)
+ hyper_request_free(req);
+
+ return result;
+}
+
+static CURLcode send_CONNECT(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct h1_tunnel_state *ts,
+ bool *done)
+{
+ struct hyptransfer *h = &data->hyp;
+ struct connectdata *conn = cf->conn;
+ hyper_task *task = NULL;
+ hyper_error *hypererr = NULL;
+ CURLcode result = CURLE_OK;
+
+ (void)ts;
+ (void)conn;
+ do {
+ task = hyper_executor_poll(h->exec);
+ if(task) {
+ bool error = hyper_task_type(task) == HYPER_TASK_ERROR;
+ if(error)
+ hypererr = hyper_task_value(task);
+ hyper_task_free(task);
+ if(error) {
+ /* this could probably use a better error code? */
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ }
+ } while(task);
+error:
+ *done = (result == CURLE_OK);
+ if(hypererr) {
+ uint8_t errbuf[256];
+ size_t errlen = hyper_error_print(hypererr, errbuf, sizeof(errbuf));
+ failf(data, "Hyper: %.*s", (int)errlen, errbuf);
+ hyper_error_free(hypererr);
+ }
+ return result;
+}
+
+static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct h1_tunnel_state *ts,
+ bool *done)
+{
+ struct hyptransfer *h = &data->hyp;
+ CURLcode result;
+ int didwhat;
+
+ (void)ts;
+ *done = FALSE;
+ result = Curl_hyper_stream(data, cf->conn, &didwhat, done,
+ CURL_CSELECT_IN | CURL_CSELECT_OUT);
+ if(result || !*done)
+ return result;
+ if(h->exec) {
+ hyper_executor_free(h->exec);
+ h->exec = NULL;
+ }
+ if(h->read_waker) {
+ hyper_waker_free(h->read_waker);
+ h->read_waker = NULL;
+ }
+ if(h->write_waker) {
+ hyper_waker_free(h->write_waker);
+ h->write_waker = NULL;
+ }
+ return result;
+}
+
+#endif /* USE_HYPER */
+
+static CURLcode H1_CONNECT(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct h1_tunnel_state *ts)
+{
+ struct connectdata *conn = cf->conn;
+ CURLcode result;
+ bool done;
+
+ if(tunnel_is_established(ts))
+ return CURLE_OK;
+ if(tunnel_is_failed(ts))
+ return CURLE_RECV_ERROR; /* Need a cfilter close and new bootstrap */
+
+ do {
+ timediff_t check;
+
+ check = Curl_timeleft(data, NULL, TRUE);
+ if(check <= 0) {
+ failf(data, "Proxy CONNECT aborted due to timeout");
+ result = CURLE_OPERATION_TIMEDOUT;
+ goto out;
+ }
+
+ switch(ts->tunnel_state) {
+ case H1_TUNNEL_INIT:
+ /* Prepare the CONNECT request and make a first attempt to send. */
+ CURL_TRC_CF(data, cf, "CONNECT start");
+ result = start_CONNECT(cf, data, ts);
+ if(result)
+ goto out;
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_CONNECT, data);
+ /* FALLTHROUGH */
+
+ case H1_TUNNEL_CONNECT:
+ /* see that the request is completely sent */
+ CURL_TRC_CF(data, cf, "CONNECT send");
+ result = send_CONNECT(cf, data, ts, &done);
+ if(result || !done)
+ goto out;
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_RECEIVE, data);
+ /* FALLTHROUGH */
+
+ case H1_TUNNEL_RECEIVE:
+ /* read what is there */
+ CURL_TRC_CF(data, cf, "CONNECT receive");
+ result = recv_CONNECT_resp(cf, data, ts, &done);
+ if(Curl_pgrsUpdate(data)) {
+ result = CURLE_ABORTED_BY_CALLBACK;
+ goto out;
+ }
+ /* error or not complete yet. return for more multi-multi */
+ if(result || !done)
+ goto out;
+ /* got it */
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_RESPONSE, data);
+ /* FALLTHROUGH */
+
+ case H1_TUNNEL_RESPONSE:
+ CURL_TRC_CF(data, cf, "CONNECT response");
+ if(data->req.newurl) {
+ /* not the "final" response, we need to do a follow up request.
+ * If the other side indicated a connection close, or if someone
+ * else told us to close this connection, do so now.
+ */
+ if(ts->close_connection || conn->bits.close) {
+ /* Close this filter and the sub-chain, re-connect the
+ * sub-chain and continue. Closing this filter will
+ * reset our tunnel state. To avoid recursion, we return
+ * and expect to be called again.
+ */
+ CURL_TRC_CF(data, cf, "CONNECT need to close+open");
+ infof(data, "Connect me again please");
+ Curl_conn_cf_close(cf, data);
+ connkeep(conn, "HTTP proxy CONNECT");
+ result = Curl_conn_cf_connect(cf->next, data, FALSE, &done);
+ goto out;
+ }
+ else {
+ /* staying on this connection, reset state */
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_INIT, data);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ } while(data->req.newurl);
+
+ DEBUGASSERT(ts->tunnel_state == H1_TUNNEL_RESPONSE);
+ if(data->info.httpproxycode/100 != 2) {
+ /* a non-2xx response and we have no next url to try. */
+ Curl_safefree(data->req.newurl);
+ /* failure, close this connection to avoid reuse */
+ streamclose(conn, "proxy CONNECT failure");
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data);
+ failf(data, "CONNECT tunnel failed, response %d", data->req.httpcode);
+ return CURLE_RECV_ERROR;
+ }
+ /* 2xx response, SUCCESS! */
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_ESTABLISHED, data);
+ infof(data, "CONNECT tunnel established, response %d",
+ data->info.httpproxycode);
+ result = CURLE_OK;
+
+out:
+ if(result)
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data);
+ return result;
+}
+
+static CURLcode cf_h1_proxy_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool blocking, bool *done)
+{
+ CURLcode result;
+ struct h1_tunnel_state *ts = cf->ctx;
+
+ if(cf->connected) {
+ *done = TRUE;
+ return CURLE_OK;
+ }
+
+ CURL_TRC_CF(data, cf, "connect");
+ result = cf->next->cft->do_connect(cf->next, data, blocking, done);
+ if(result || !*done)
+ return result;
+
+ *done = FALSE;
+ if(!ts) {
+ result = tunnel_init(cf, data, &ts);
+ if(result)
+ return result;
+ cf->ctx = ts;
+ }
+
+ /* TODO: can we do blocking? */
+ /* We want "seamless" operations through HTTP proxy tunnel */
+
+ result = H1_CONNECT(cf, data, ts);
+ if(result)
+ goto out;
+ Curl_safefree(data->state.aptr.proxyuserpwd);
+
+out:
+ *done = (result == CURLE_OK) && tunnel_is_established(cf->ctx);
+ if(*done) {
+ cf->connected = TRUE;
+ tunnel_free(cf, data);
+ }
+ return result;
+}
+
+static int cf_h1_proxy_get_select_socks(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ curl_socket_t *socks)
+{
+ struct h1_tunnel_state *ts = cf->ctx;
+ int fds;
+
+ fds = cf->next->cft->get_select_socks(cf->next, data, socks);
+ if(!fds && cf->next->connected && !cf->connected) {
+ /* If we are not connected, but the filter "below" is
+ * and not waiting on something, we are tunneling. */
+ socks[0] = Curl_conn_cf_get_socket(cf, data);
+ if(ts) {
+ /* when we've sent a CONNECT to a proxy, we should rather either
+ wait for the socket to become readable to be able to get the
+ response headers or if we're still sending the request, wait
+ for write. */
+ if(ts->CONNECT.sending == HTTPSEND_REQUEST) {
+ return GETSOCK_WRITESOCK(0);
+ }
+ return GETSOCK_READSOCK(0);
+ }
+ return GETSOCK_WRITESOCK(0);
+ }
+ return fds;
+}
+
+static void cf_h1_proxy_destroy(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ CURL_TRC_CF(data, cf, "destroy");
+ tunnel_free(cf, data);
+}
+
+static void cf_h1_proxy_close(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ CURL_TRC_CF(data, cf, "close");
+ cf->connected = FALSE;
+ if(cf->ctx) {
+ h1_tunnel_go_state(cf, cf->ctx, H1_TUNNEL_INIT, data);
+ }
+ if(cf->next)
+ cf->next->cft->do_close(cf->next, data);
+}
+
+
+struct Curl_cftype Curl_cft_h1_proxy = {
+ "H1-PROXY",
+ CF_TYPE_IP_CONNECT,
+ 0,
+ cf_h1_proxy_destroy,
+ cf_h1_proxy_connect,
+ cf_h1_proxy_close,
+ Curl_cf_http_proxy_get_host,
+ cf_h1_proxy_get_select_socks,
+ Curl_cf_def_data_pending,
+ Curl_cf_def_send,
+ Curl_cf_def_recv,
+ Curl_cf_def_cntrl,
+ Curl_cf_def_conn_is_alive,
+ Curl_cf_def_conn_keep_alive,
+ Curl_cf_def_query,
+};
+
+CURLcode Curl_cf_h1_proxy_insert_after(struct Curl_cfilter *cf_at,
+ struct Curl_easy *data)
+{
+ struct Curl_cfilter *cf;
+ CURLcode result;
+
+ (void)data;
+ result = Curl_cf_create(&cf, &Curl_cft_h1_proxy, NULL);
+ if(!result)
+ Curl_conn_cf_insert_after(cf_at, cf);
+ return result;
+}
+
+#endif /* !CURL_DISABLE_PROXY && ! CURL_DISABLE_HTTP */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/cf-h1-proxy.h b/iotdb-client/odbc/deps/curl-src/lib/cf-h1-proxy.h
new file mode 100644
index 0000000000000..ac5bed0b2bc7a
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/cf-h1-proxy.h
@@ -0,0 +1,39 @@
+#ifndef HEADER_CURL_H1_PROXY_H
+#define HEADER_CURL_H1_PROXY_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)
+
+CURLcode Curl_cf_h1_proxy_insert_after(struct Curl_cfilter *cf,
+ struct Curl_easy *data);
+
+extern struct Curl_cftype Curl_cft_h1_proxy;
+
+
+#endif /* !CURL_DISABLE_PROXY && !CURL_DISABLE_HTTP */
+
+#endif /* HEADER_CURL_H1_PROXY_H */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/cf-h2-proxy.c b/iotdb-client/odbc/deps/curl-src/lib/cf-h2-proxy.c
new file mode 100644
index 0000000000000..dbc895d2634d9
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/cf-h2-proxy.c
@@ -0,0 +1,1580 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NGHTTP2) && !defined(CURL_DISABLE_PROXY)
+
+#include
+#include "urldata.h"
+#include "cfilters.h"
+#include "connect.h"
+#include "curl_trc.h"
+#include "bufq.h"
+#include "dynbuf.h"
+#include "dynhds.h"
+#include "http1.h"
+#include "http2.h"
+#include "http_proxy.h"
+#include "multiif.h"
+#include "cf-h2-proxy.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define PROXY_H2_CHUNK_SIZE (16*1024)
+
+#define PROXY_HTTP2_HUGE_WINDOW_SIZE (100 * 1024 * 1024)
+#define H2_TUNNEL_WINDOW_SIZE (10 * 1024 * 1024)
+
+#define PROXY_H2_NW_RECV_CHUNKS (H2_TUNNEL_WINDOW_SIZE / PROXY_H2_CHUNK_SIZE)
+#define PROXY_H2_NW_SEND_CHUNKS 1
+
+#define H2_TUNNEL_RECV_CHUNKS (H2_TUNNEL_WINDOW_SIZE / PROXY_H2_CHUNK_SIZE)
+#define H2_TUNNEL_SEND_CHUNKS ((128 * 1024) / PROXY_H2_CHUNK_SIZE)
+
+
+typedef enum {
+ H2_TUNNEL_INIT, /* init/default/no tunnel state */
+ H2_TUNNEL_CONNECT, /* CONNECT request is being send */
+ H2_TUNNEL_RESPONSE, /* CONNECT response received completely */
+ H2_TUNNEL_ESTABLISHED,
+ H2_TUNNEL_FAILED
+} h2_tunnel_state;
+
+struct tunnel_stream {
+ struct http_resp *resp;
+ struct bufq recvbuf;
+ struct bufq sendbuf;
+ char *authority;
+ int32_t stream_id;
+ uint32_t error;
+ size_t upload_blocked_len;
+ h2_tunnel_state state;
+ BIT(has_final_response);
+ BIT(closed);
+ BIT(reset);
+};
+
+static CURLcode tunnel_stream_init(struct Curl_cfilter *cf,
+ struct tunnel_stream *ts)
+{
+ const char *hostname;
+ int port;
+ bool ipv6_ip;
+ CURLcode result;
+
+ ts->state = H2_TUNNEL_INIT;
+ ts->stream_id = -1;
+ Curl_bufq_init2(&ts->recvbuf, PROXY_H2_CHUNK_SIZE, H2_TUNNEL_RECV_CHUNKS,
+ BUFQ_OPT_SOFT_LIMIT);
+ Curl_bufq_init(&ts->sendbuf, PROXY_H2_CHUNK_SIZE, H2_TUNNEL_SEND_CHUNKS);
+
+ result = Curl_http_proxy_get_destination(cf, &hostname, &port, &ipv6_ip);
+ if(result)
+ return result;
+
+ ts->authority = /* host:port with IPv6 support */
+ aprintf("%s%s%s:%d", ipv6_ip?"[":"", hostname, ipv6_ip?"]":"", port);
+ if(!ts->authority)
+ return CURLE_OUT_OF_MEMORY;
+
+ return CURLE_OK;
+}
+
+static void tunnel_stream_clear(struct tunnel_stream *ts)
+{
+ Curl_http_resp_free(ts->resp);
+ Curl_bufq_free(&ts->recvbuf);
+ Curl_bufq_free(&ts->sendbuf);
+ Curl_safefree(ts->authority);
+ memset(ts, 0, sizeof(*ts));
+ ts->state = H2_TUNNEL_INIT;
+}
+
+static void h2_tunnel_go_state(struct Curl_cfilter *cf,
+ struct tunnel_stream *ts,
+ h2_tunnel_state new_state,
+ struct Curl_easy *data)
+{
+ (void)cf;
+
+ if(ts->state == new_state)
+ return;
+ /* leaving this one */
+ switch(ts->state) {
+ case H2_TUNNEL_CONNECT:
+ data->req.ignorebody = FALSE;
+ break;
+ default:
+ break;
+ }
+ /* entering this one */
+ switch(new_state) {
+ case H2_TUNNEL_INIT:
+ CURL_TRC_CF(data, cf, "[%d] new tunnel state 'init'", ts->stream_id);
+ tunnel_stream_clear(ts);
+ break;
+
+ case H2_TUNNEL_CONNECT:
+ CURL_TRC_CF(data, cf, "[%d] new tunnel state 'connect'", ts->stream_id);
+ ts->state = H2_TUNNEL_CONNECT;
+ break;
+
+ case H2_TUNNEL_RESPONSE:
+ CURL_TRC_CF(data, cf, "[%d] new tunnel state 'response'", ts->stream_id);
+ ts->state = H2_TUNNEL_RESPONSE;
+ break;
+
+ case H2_TUNNEL_ESTABLISHED:
+ CURL_TRC_CF(data, cf, "[%d] new tunnel state 'established'",
+ ts->stream_id);
+ infof(data, "CONNECT phase completed");
+ data->state.authproxy.done = TRUE;
+ data->state.authproxy.multipass = FALSE;
+ /* FALLTHROUGH */
+ case H2_TUNNEL_FAILED:
+ if(new_state == H2_TUNNEL_FAILED)
+ CURL_TRC_CF(data, cf, "[%d] new tunnel state 'failed'", ts->stream_id);
+ ts->state = new_state;
+ /* If a proxy-authorization header was used for the proxy, then we should
+ make sure that it isn't accidentally used for the document request
+ after we've connected. So let's free and clear it here. */
+ Curl_safefree(data->state.aptr.proxyuserpwd);
+ break;
+ }
+}
+
+struct cf_h2_proxy_ctx {
+ nghttp2_session *h2;
+ /* The easy handle used in the current filter call, cleared at return */
+ struct cf_call_data call_data;
+
+ struct bufq inbufq; /* network receive buffer */
+ struct bufq outbufq; /* network send buffer */
+
+ struct tunnel_stream tunnel; /* our tunnel CONNECT stream */
+ int32_t goaway_error;
+ int32_t last_stream_id;
+ BIT(conn_closed);
+ BIT(goaway);
+ BIT(nw_out_blocked);
+};
+
+/* How to access `call_data` from a cf_h2 filter */
+#undef CF_CTX_CALL_DATA
+#define CF_CTX_CALL_DATA(cf) \
+ ((struct cf_h2_proxy_ctx *)(cf)->ctx)->call_data
+
+static void cf_h2_proxy_ctx_clear(struct cf_h2_proxy_ctx *ctx)
+{
+ struct cf_call_data save = ctx->call_data;
+
+ if(ctx->h2) {
+ nghttp2_session_del(ctx->h2);
+ }
+ Curl_bufq_free(&ctx->inbufq);
+ Curl_bufq_free(&ctx->outbufq);
+ tunnel_stream_clear(&ctx->tunnel);
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->call_data = save;
+}
+
+static void cf_h2_proxy_ctx_free(struct cf_h2_proxy_ctx *ctx)
+{
+ if(ctx) {
+ cf_h2_proxy_ctx_clear(ctx);
+ free(ctx);
+ }
+}
+
+static void drain_tunnel(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct tunnel_stream *tunnel)
+{
+ unsigned char bits;
+
+ (void)cf;
+ bits = CURL_CSELECT_IN;
+ if(!tunnel->closed && !tunnel->reset && tunnel->upload_blocked_len)
+ bits |= CURL_CSELECT_OUT;
+ if(data->state.dselect_bits != bits) {
+ CURL_TRC_CF(data, cf, "[%d] DRAIN dselect_bits=%x",
+ tunnel->stream_id, bits);
+ data->state.dselect_bits = bits;
+ Curl_expire(data, 0, EXPIRE_RUN_NOW);
+ }
+}
+
+static ssize_t proxy_nw_in_reader(void *reader_ctx,
+ unsigned char *buf, size_t buflen,
+ CURLcode *err)
+{
+ struct Curl_cfilter *cf = reader_ctx;
+ ssize_t nread;
+
+ if(cf) {
+ struct Curl_easy *data = CF_DATA_CURRENT(cf);
+ nread = Curl_conn_cf_recv(cf->next, data, (char *)buf, buflen, err);
+ CURL_TRC_CF(data, cf, "[0] nw_in_reader(len=%zu) -> %zd, %d",
+ buflen, nread, *err);
+ }
+ else {
+ nread = 0;
+ }
+ return nread;
+}
+
+static ssize_t proxy_h2_nw_out_writer(void *writer_ctx,
+ const unsigned char *buf, size_t buflen,
+ CURLcode *err)
+{
+ struct Curl_cfilter *cf = writer_ctx;
+ ssize_t nwritten;
+
+ if(cf) {
+ struct Curl_easy *data = CF_DATA_CURRENT(cf);
+ nwritten = Curl_conn_cf_send(cf->next, data, (const char *)buf, buflen,
+ err);
+ CURL_TRC_CF(data, cf, "[0] nw_out_writer(len=%zu) -> %zd, %d",
+ buflen, nwritten, *err);
+ }
+ else {
+ nwritten = 0;
+ }
+ return nwritten;
+}
+
+static int proxy_h2_client_new(struct Curl_cfilter *cf,
+ nghttp2_session_callbacks *cbs)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ nghttp2_option *o;
+
+ int rc = nghttp2_option_new(&o);
+ if(rc)
+ return rc;
+ /* We handle window updates ourself to enforce buffer limits */
+ nghttp2_option_set_no_auto_window_update(o, 1);
+#if NGHTTP2_VERSION_NUM >= 0x013200
+ /* with 1.50.0 */
+ /* turn off RFC 9113 leading and trailing white spaces validation against
+ HTTP field value. */
+ nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(o, 1);
+#endif
+ rc = nghttp2_session_client_new2(&ctx->h2, cbs, cf, o);
+ nghttp2_option_del(o);
+ return rc;
+}
+
+static ssize_t on_session_send(nghttp2_session *h2,
+ const uint8_t *buf, size_t blen,
+ int flags, void *userp);
+static int proxy_h2_on_frame_recv(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ void *userp);
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+static int proxy_h2_on_frame_send(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ void *userp);
+#endif
+static int proxy_h2_on_stream_close(nghttp2_session *session,
+ int32_t stream_id,
+ uint32_t error_code, void *userp);
+static int proxy_h2_on_header(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ const uint8_t *name, size_t namelen,
+ const uint8_t *value, size_t valuelen,
+ uint8_t flags,
+ void *userp);
+static int tunnel_recv_callback(nghttp2_session *session, uint8_t flags,
+ int32_t stream_id,
+ const uint8_t *mem, size_t len, void *userp);
+
+/*
+ * Initialize the cfilter context
+ */
+static CURLcode cf_h2_proxy_ctx_init(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ CURLcode result = CURLE_OUT_OF_MEMORY;
+ nghttp2_session_callbacks *cbs = NULL;
+ int rc;
+
+ DEBUGASSERT(!ctx->h2);
+ memset(&ctx->tunnel, 0, sizeof(ctx->tunnel));
+
+ Curl_bufq_init(&ctx->inbufq, PROXY_H2_CHUNK_SIZE, PROXY_H2_NW_RECV_CHUNKS);
+ Curl_bufq_init(&ctx->outbufq, PROXY_H2_CHUNK_SIZE, PROXY_H2_NW_SEND_CHUNKS);
+
+ if(tunnel_stream_init(cf, &ctx->tunnel))
+ goto out;
+
+ rc = nghttp2_session_callbacks_new(&cbs);
+ if(rc) {
+ failf(data, "Couldn't initialize nghttp2 callbacks");
+ goto out;
+ }
+
+ nghttp2_session_callbacks_set_send_callback(cbs, on_session_send);
+ nghttp2_session_callbacks_set_on_frame_recv_callback(
+ cbs, proxy_h2_on_frame_recv);
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+ nghttp2_session_callbacks_set_on_frame_send_callback(cbs,
+ proxy_h2_on_frame_send);
+#endif
+ nghttp2_session_callbacks_set_on_data_chunk_recv_callback(
+ cbs, tunnel_recv_callback);
+ nghttp2_session_callbacks_set_on_stream_close_callback(
+ cbs, proxy_h2_on_stream_close);
+ nghttp2_session_callbacks_set_on_header_callback(cbs, proxy_h2_on_header);
+
+ /* The nghttp2 session is not yet setup, do it */
+ rc = proxy_h2_client_new(cf, cbs);
+ if(rc) {
+ failf(data, "Couldn't initialize nghttp2");
+ goto out;
+ }
+
+ {
+ nghttp2_settings_entry iv[3];
+
+ iv[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
+ iv[0].value = Curl_multi_max_concurrent_streams(data->multi);
+ iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
+ iv[1].value = H2_TUNNEL_WINDOW_SIZE;
+ iv[2].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH;
+ iv[2].value = 0;
+ rc = nghttp2_submit_settings(ctx->h2, NGHTTP2_FLAG_NONE, iv, 3);
+ if(rc) {
+ failf(data, "nghttp2_submit_settings() failed: %s(%d)",
+ nghttp2_strerror(rc), rc);
+ result = CURLE_HTTP2;
+ goto out;
+ }
+ }
+
+ rc = nghttp2_session_set_local_window_size(ctx->h2, NGHTTP2_FLAG_NONE, 0,
+ PROXY_HTTP2_HUGE_WINDOW_SIZE);
+ if(rc) {
+ failf(data, "nghttp2_session_set_local_window_size() failed: %s(%d)",
+ nghttp2_strerror(rc), rc);
+ result = CURLE_HTTP2;
+ goto out;
+ }
+
+
+ /* all set, traffic will be send on connect */
+ result = CURLE_OK;
+
+out:
+ if(cbs)
+ nghttp2_session_callbacks_del(cbs);
+ CURL_TRC_CF(data, cf, "[0] init proxy ctx -> %d", result);
+ return result;
+}
+
+static int proxy_h2_should_close_session(struct cf_h2_proxy_ctx *ctx)
+{
+ return !nghttp2_session_want_read(ctx->h2) &&
+ !nghttp2_session_want_write(ctx->h2);
+}
+
+static CURLcode proxy_h2_nw_out_flush(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ ssize_t nwritten;
+ CURLcode result;
+
+ (void)data;
+ if(Curl_bufq_is_empty(&ctx->outbufq))
+ return CURLE_OK;
+
+ nwritten = Curl_bufq_pass(&ctx->outbufq, proxy_h2_nw_out_writer, cf,
+ &result);
+ if(nwritten < 0) {
+ if(result == CURLE_AGAIN) {
+ CURL_TRC_CF(data, cf, "[0] flush nw send buffer(%zu) -> EAGAIN",
+ Curl_bufq_len(&ctx->outbufq));
+ ctx->nw_out_blocked = 1;
+ }
+ return result;
+ }
+ CURL_TRC_CF(data, cf, "[0] nw send buffer flushed");
+ return Curl_bufq_is_empty(&ctx->outbufq)? CURLE_OK: CURLE_AGAIN;
+}
+
+/*
+ * Processes pending input left in network input buffer.
+ * This function returns 0 if it succeeds, or -1 and error code will
+ * be assigned to *err.
+ */
+static int proxy_h2_process_pending_input(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ CURLcode *err)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ const unsigned char *buf;
+ size_t blen;
+ ssize_t rv;
+
+ while(Curl_bufq_peek(&ctx->inbufq, &buf, &blen)) {
+
+ rv = nghttp2_session_mem_recv(ctx->h2, (const uint8_t *)buf, blen);
+ CURL_TRC_CF(data, cf, "[0] %zu bytes to nghttp2 -> %zd", blen, rv);
+ if(rv < 0) {
+ failf(data,
+ "process_pending_input: nghttp2_session_mem_recv() returned "
+ "%zd:%s", rv, nghttp2_strerror((int)rv));
+ *err = CURLE_RECV_ERROR;
+ return -1;
+ }
+ Curl_bufq_skip(&ctx->inbufq, (size_t)rv);
+ if(Curl_bufq_is_empty(&ctx->inbufq)) {
+ CURL_TRC_CF(data, cf, "[0] all data in connection buffer processed");
+ break;
+ }
+ else {
+ CURL_TRC_CF(data, cf, "[0] process_pending_input: %zu bytes left "
+ "in connection buffer", Curl_bufq_len(&ctx->inbufq));
+ }
+ }
+
+ return 0;
+}
+
+static CURLcode proxy_h2_progress_ingress(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ CURLcode result = CURLE_OK;
+ ssize_t nread;
+
+ /* Process network input buffer fist */
+ if(!Curl_bufq_is_empty(&ctx->inbufq)) {
+ CURL_TRC_CF(data, cf, "[0] process %zu bytes in connection buffer",
+ Curl_bufq_len(&ctx->inbufq));
+ if(proxy_h2_process_pending_input(cf, data, &result) < 0)
+ return result;
+ }
+
+ /* Receive data from the "lower" filters, e.g. network until
+ * it is time to stop or we have enough data for this stream */
+ while(!ctx->conn_closed && /* not closed the connection */
+ !ctx->tunnel.closed && /* nor the tunnel */
+ Curl_bufq_is_empty(&ctx->inbufq) && /* and we consumed our input */
+ !Curl_bufq_is_full(&ctx->tunnel.recvbuf)) {
+
+ nread = Curl_bufq_slurp(&ctx->inbufq, proxy_nw_in_reader, cf, &result);
+ CURL_TRC_CF(data, cf, "[0] read %zu bytes nw data -> %zd, %d",
+ Curl_bufq_len(&ctx->inbufq), nread, result);
+ if(nread < 0) {
+ if(result != CURLE_AGAIN) {
+ failf(data, "Failed receiving HTTP2 data");
+ return result;
+ }
+ break;
+ }
+ else if(nread == 0) {
+ ctx->conn_closed = TRUE;
+ break;
+ }
+
+ if(proxy_h2_process_pending_input(cf, data, &result))
+ return result;
+ }
+
+ if(ctx->conn_closed && Curl_bufq_is_empty(&ctx->inbufq)) {
+ connclose(cf->conn, "GOAWAY received");
+ }
+
+ return CURLE_OK;
+}
+
+static CURLcode proxy_h2_progress_egress(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ int rv = 0;
+
+ ctx->nw_out_blocked = 0;
+ while(!rv && !ctx->nw_out_blocked && nghttp2_session_want_write(ctx->h2))
+ rv = nghttp2_session_send(ctx->h2);
+
+ if(nghttp2_is_fatal(rv)) {
+ CURL_TRC_CF(data, cf, "[0] nghttp2_session_send error (%s)%d",
+ nghttp2_strerror(rv), rv);
+ return CURLE_SEND_ERROR;
+ }
+ return proxy_h2_nw_out_flush(cf, data);
+}
+
+static ssize_t on_session_send(nghttp2_session *h2,
+ const uint8_t *buf, size_t blen, int flags,
+ void *userp)
+{
+ struct Curl_cfilter *cf = userp;
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ struct Curl_easy *data = CF_DATA_CURRENT(cf);
+ ssize_t nwritten;
+ CURLcode result = CURLE_OK;
+
+ (void)h2;
+ (void)flags;
+ DEBUGASSERT(data);
+
+ nwritten = Curl_bufq_write_pass(&ctx->outbufq, buf, blen,
+ proxy_h2_nw_out_writer, cf, &result);
+ if(nwritten < 0) {
+ if(result == CURLE_AGAIN) {
+ return NGHTTP2_ERR_WOULDBLOCK;
+ }
+ failf(data, "Failed sending HTTP2 data");
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ }
+
+ if(!nwritten)
+ return NGHTTP2_ERR_WOULDBLOCK;
+
+ return nwritten;
+}
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+static int proxy_h2_fr_print(const nghttp2_frame *frame,
+ char *buffer, size_t blen)
+{
+ switch(frame->hd.type) {
+ case NGHTTP2_DATA: {
+ return msnprintf(buffer, blen,
+ "FRAME[DATA, len=%d, eos=%d, padlen=%d]",
+ (int)frame->hd.length,
+ !!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM),
+ (int)frame->data.padlen);
+ }
+ case NGHTTP2_HEADERS: {
+ return msnprintf(buffer, blen,
+ "FRAME[HEADERS, len=%d, hend=%d, eos=%d]",
+ (int)frame->hd.length,
+ !!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS),
+ !!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM));
+ }
+ case NGHTTP2_PRIORITY: {
+ return msnprintf(buffer, blen,
+ "FRAME[PRIORITY, len=%d, flags=%d]",
+ (int)frame->hd.length, frame->hd.flags);
+ }
+ case NGHTTP2_RST_STREAM: {
+ return msnprintf(buffer, blen,
+ "FRAME[RST_STREAM, len=%d, flags=%d, error=%u]",
+ (int)frame->hd.length, frame->hd.flags,
+ frame->rst_stream.error_code);
+ }
+ case NGHTTP2_SETTINGS: {
+ if(frame->hd.flags & NGHTTP2_FLAG_ACK) {
+ return msnprintf(buffer, blen, "FRAME[SETTINGS, ack=1]");
+ }
+ return msnprintf(buffer, blen,
+ "FRAME[SETTINGS, len=%d]", (int)frame->hd.length);
+ }
+ case NGHTTP2_PUSH_PROMISE: {
+ return msnprintf(buffer, blen,
+ "FRAME[PUSH_PROMISE, len=%d, hend=%d]",
+ (int)frame->hd.length,
+ !!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS));
+ }
+ case NGHTTP2_PING: {
+ return msnprintf(buffer, blen,
+ "FRAME[PING, len=%d, ack=%d]",
+ (int)frame->hd.length,
+ frame->hd.flags&NGHTTP2_FLAG_ACK);
+ }
+ case NGHTTP2_GOAWAY: {
+ char scratch[128];
+ size_t s_len = sizeof(scratch)/sizeof(scratch[0]);
+ size_t len = (frame->goaway.opaque_data_len < s_len)?
+ frame->goaway.opaque_data_len : s_len-1;
+ if(len)
+ memcpy(scratch, frame->goaway.opaque_data, len);
+ scratch[len] = '\0';
+ return msnprintf(buffer, blen, "FRAME[GOAWAY, error=%d, reason='%s', "
+ "last_stream=%d]", frame->goaway.error_code,
+ scratch, frame->goaway.last_stream_id);
+ }
+ case NGHTTP2_WINDOW_UPDATE: {
+ return msnprintf(buffer, blen,
+ "FRAME[WINDOW_UPDATE, incr=%d]",
+ frame->window_update.window_size_increment);
+ }
+ default:
+ return msnprintf(buffer, blen, "FRAME[%d, len=%d, flags=%d]",
+ frame->hd.type, (int)frame->hd.length,
+ frame->hd.flags);
+ }
+}
+
+static int proxy_h2_on_frame_send(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ void *userp)
+{
+ struct Curl_cfilter *cf = userp;
+ struct Curl_easy *data = CF_DATA_CURRENT(cf);
+
+ (void)session;
+ DEBUGASSERT(data);
+ if(data && Curl_trc_cf_is_verbose(cf, data)) {
+ char buffer[256];
+ int len;
+ len = proxy_h2_fr_print(frame, buffer, sizeof(buffer)-1);
+ buffer[len] = 0;
+ CURL_TRC_CF(data, cf, "[%d] -> %s", frame->hd.stream_id, buffer);
+ }
+ return 0;
+}
+#endif /* !CURL_DISABLE_VERBOSE_STRINGS */
+
+static int proxy_h2_on_frame_recv(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ void *userp)
+{
+ struct Curl_cfilter *cf = userp;
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ struct Curl_easy *data = CF_DATA_CURRENT(cf);
+ int32_t stream_id = frame->hd.stream_id;
+
+ (void)session;
+ DEBUGASSERT(data);
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+ if(Curl_trc_cf_is_verbose(cf, data)) {
+ char buffer[256];
+ int len;
+ len = proxy_h2_fr_print(frame, buffer, sizeof(buffer)-1);
+ buffer[len] = 0;
+ CURL_TRC_CF(data, cf, "[%d] <- %s",frame->hd.stream_id, buffer);
+ }
+#endif /* !CURL_DISABLE_VERBOSE_STRINGS */
+
+ if(!stream_id) {
+ /* stream ID zero is for connection-oriented stuff */
+ DEBUGASSERT(data);
+ switch(frame->hd.type) {
+ case NGHTTP2_SETTINGS:
+ /* Since the initial stream window is 64K, a request might be on HOLD,
+ * due to exhaustion. The (initial) SETTINGS may announce a much larger
+ * window and *assume* that we treat this like a WINDOW_UPDATE. Some
+ * servers send an explicit WINDOW_UPDATE, but not all seem to do that.
+ * To be safe, we UNHOLD a stream in order not to stall. */
+ if((data->req.keepon & KEEP_SEND_HOLD) &&
+ (data->req.keepon & KEEP_SEND)) {
+ data->req.keepon &= ~KEEP_SEND_HOLD;
+ drain_tunnel(cf, data, &ctx->tunnel);
+ CURL_TRC_CF(data, cf, "[%d] un-holding after SETTINGS",
+ stream_id);
+ }
+ break;
+ case NGHTTP2_GOAWAY:
+ ctx->goaway = TRUE;
+ break;
+ default:
+ break;
+ }
+ return 0;
+ }
+
+ if(stream_id != ctx->tunnel.stream_id) {
+ CURL_TRC_CF(data, cf, "[%d] rcvd FRAME not for tunnel", stream_id);
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ }
+
+ switch(frame->hd.type) {
+ case NGHTTP2_HEADERS:
+ /* nghttp2 guarantees that :status is received, and we store it to
+ stream->status_code. Fuzzing has proven this can still be reached
+ without status code having been set. */
+ if(!ctx->tunnel.resp)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ /* Only final status code signals the end of header */
+ CURL_TRC_CF(data, cf, "[%d] got http status: %d",
+ stream_id, ctx->tunnel.resp->status);
+ if(!ctx->tunnel.has_final_response) {
+ if(ctx->tunnel.resp->status / 100 != 1) {
+ ctx->tunnel.has_final_response = TRUE;
+ }
+ }
+ break;
+ case NGHTTP2_WINDOW_UPDATE:
+ if((data->req.keepon & KEEP_SEND_HOLD) &&
+ (data->req.keepon & KEEP_SEND)) {
+ data->req.keepon &= ~KEEP_SEND_HOLD;
+ Curl_expire(data, 0, EXPIRE_RUN_NOW);
+ CURL_TRC_CF(data, cf, "[%d] unpausing after win update",
+ stream_id);
+ }
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int proxy_h2_on_header(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ const uint8_t *name, size_t namelen,
+ const uint8_t *value, size_t valuelen,
+ uint8_t flags,
+ void *userp)
+{
+ struct Curl_cfilter *cf = userp;
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ struct Curl_easy *data = CF_DATA_CURRENT(cf);
+ int32_t stream_id = frame->hd.stream_id;
+ CURLcode result;
+
+ (void)flags;
+ (void)data;
+ (void)session;
+ DEBUGASSERT(stream_id); /* should never be a zero stream ID here */
+ if(stream_id != ctx->tunnel.stream_id) {
+ CURL_TRC_CF(data, cf, "[%d] header for non-tunnel stream: "
+ "%.*s: %.*s", stream_id,
+ (int)namelen, name, (int)valuelen, value);
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ }
+
+ if(frame->hd.type == NGHTTP2_PUSH_PROMISE)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+ if(ctx->tunnel.has_final_response) {
+ /* we do not do anything with trailers for tunnel streams */
+ return 0;
+ }
+
+ if(namelen == sizeof(HTTP_PSEUDO_STATUS) - 1 &&
+ memcmp(HTTP_PSEUDO_STATUS, name, namelen) == 0) {
+ int http_status;
+ struct http_resp *resp;
+
+ /* status: always comes first, we might get more than one response,
+ * link the previous ones for keepers */
+ result = Curl_http_decode_status(&http_status,
+ (const char *)value, valuelen);
+ if(result)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ result = Curl_http_resp_make(&resp, http_status, NULL);
+ if(result)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ resp->prev = ctx->tunnel.resp;
+ ctx->tunnel.resp = resp;
+ CURL_TRC_CF(data, cf, "[%d] status: HTTP/2 %03d",
+ stream_id, ctx->tunnel.resp->status);
+ return 0;
+ }
+
+ if(!ctx->tunnel.resp)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+ result = Curl_dynhds_add(&ctx->tunnel.resp->headers,
+ (const char *)name, namelen,
+ (const char *)value, valuelen);
+ if(result)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+ CURL_TRC_CF(data, cf, "[%d] header: %.*s: %.*s",
+ stream_id, (int)namelen, name, (int)valuelen, value);
+
+ return 0; /* 0 is successful */
+}
+
+static ssize_t tunnel_send_callback(nghttp2_session *session,
+ int32_t stream_id,
+ uint8_t *buf, size_t length,
+ uint32_t *data_flags,
+ nghttp2_data_source *source,
+ void *userp)
+{
+ struct Curl_cfilter *cf = userp;
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ struct Curl_easy *data = CF_DATA_CURRENT(cf);
+ struct tunnel_stream *ts;
+ CURLcode result;
+ ssize_t nread;
+
+ (void)source;
+ (void)data;
+ (void)ctx;
+
+ if(!stream_id)
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
+
+ ts = nghttp2_session_get_stream_user_data(session, stream_id);
+ if(!ts)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ DEBUGASSERT(ts == &ctx->tunnel);
+
+ nread = Curl_bufq_read(&ts->sendbuf, buf, length, &result);
+ if(nread < 0) {
+ if(result != CURLE_AGAIN)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ return NGHTTP2_ERR_DEFERRED;
+ }
+ if(ts->closed && Curl_bufq_is_empty(&ts->sendbuf))
+ *data_flags = NGHTTP2_DATA_FLAG_EOF;
+
+ CURL_TRC_CF(data, cf, "[%d] tunnel_send_callback -> %zd",
+ ts->stream_id, nread);
+ return nread;
+}
+
+static int tunnel_recv_callback(nghttp2_session *session, uint8_t flags,
+ int32_t stream_id,
+ const uint8_t *mem, size_t len, void *userp)
+{
+ struct Curl_cfilter *cf = userp;
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ ssize_t nwritten;
+ CURLcode result;
+
+ (void)flags;
+ (void)session;
+ DEBUGASSERT(stream_id); /* should never be a zero stream ID here */
+
+ if(stream_id != ctx->tunnel.stream_id)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+ nwritten = Curl_bufq_write(&ctx->tunnel.recvbuf, mem, len, &result);
+ if(nwritten < 0) {
+ if(result != CURLE_AGAIN)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ nwritten = 0;
+ }
+ DEBUGASSERT((size_t)nwritten == len);
+ return 0;
+}
+
+static int proxy_h2_on_stream_close(nghttp2_session *session,
+ int32_t stream_id,
+ uint32_t error_code, void *userp)
+{
+ struct Curl_cfilter *cf = userp;
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ struct Curl_easy *data = CF_DATA_CURRENT(cf);
+
+ (void)session;
+ (void)data;
+
+ if(stream_id != ctx->tunnel.stream_id)
+ return 0;
+
+ CURL_TRC_CF(data, cf, "[%d] proxy_h2_on_stream_close, %s (err %d)",
+ stream_id, nghttp2_http2_strerror(error_code), error_code);
+ ctx->tunnel.closed = TRUE;
+ ctx->tunnel.error = error_code;
+
+ return 0;
+}
+
+static CURLcode proxy_h2_submit(int32_t *pstream_id,
+ struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ nghttp2_session *h2,
+ struct httpreq *req,
+ const nghttp2_priority_spec *pri_spec,
+ void *stream_user_data,
+ nghttp2_data_source_read_callback read_callback,
+ void *read_ctx)
+{
+ struct dynhds h2_headers;
+ nghttp2_nv *nva = NULL;
+ unsigned int i;
+ int32_t stream_id = -1;
+ size_t nheader;
+ CURLcode result;
+
+ (void)cf;
+ Curl_dynhds_init(&h2_headers, 0, DYN_HTTP_REQUEST);
+ result = Curl_http_req_to_h2(&h2_headers, req, data);
+ if(result)
+ goto out;
+
+ nheader = Curl_dynhds_count(&h2_headers);
+ nva = malloc(sizeof(nghttp2_nv) * nheader);
+ if(!nva) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ for(i = 0; i < nheader; ++i) {
+ struct dynhds_entry *e = Curl_dynhds_getn(&h2_headers, i);
+ nva[i].name = (unsigned char *)e->name;
+ nva[i].namelen = e->namelen;
+ nva[i].value = (unsigned char *)e->value;
+ nva[i].valuelen = e->valuelen;
+ nva[i].flags = NGHTTP2_NV_FLAG_NONE;
+ }
+
+ if(read_callback) {
+ nghttp2_data_provider data_prd;
+
+ data_prd.read_callback = read_callback;
+ data_prd.source.ptr = read_ctx;
+ stream_id = nghttp2_submit_request(h2, pri_spec, nva, nheader,
+ &data_prd, stream_user_data);
+ }
+ else {
+ stream_id = nghttp2_submit_request(h2, pri_spec, nva, nheader,
+ NULL, stream_user_data);
+ }
+
+ if(stream_id < 0) {
+ failf(data, "nghttp2_session_upgrade2() failed: %s(%d)",
+ nghttp2_strerror(stream_id), stream_id);
+ result = CURLE_SEND_ERROR;
+ goto out;
+ }
+ result = CURLE_OK;
+
+out:
+ free(nva);
+ Curl_dynhds_free(&h2_headers);
+ *pstream_id = stream_id;
+ return result;
+}
+
+static CURLcode submit_CONNECT(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct tunnel_stream *ts)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ CURLcode result;
+ struct httpreq *req = NULL;
+
+ result = Curl_http_proxy_create_CONNECT(&req, cf, data, 2);
+ if(result)
+ goto out;
+
+ infof(data, "Establish HTTP/2 proxy tunnel to %s", req->authority);
+
+ result = proxy_h2_submit(&ts->stream_id, cf, data, ctx->h2, req,
+ NULL, ts, tunnel_send_callback, cf);
+ if(result) {
+ CURL_TRC_CF(data, cf, "[%d] send, nghttp2_submit_request error: %s",
+ ts->stream_id, nghttp2_strerror(ts->stream_id));
+ }
+
+out:
+ if(req)
+ Curl_http_req_free(req);
+ if(result)
+ failf(data, "Failed sending CONNECT to proxy");
+ return result;
+}
+
+static CURLcode inspect_response(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct tunnel_stream *ts)
+{
+ CURLcode result = CURLE_OK;
+ struct dynhds_entry *auth_reply = NULL;
+ (void)cf;
+
+ DEBUGASSERT(ts->resp);
+ if(ts->resp->status/100 == 2) {
+ infof(data, "CONNECT tunnel established, response %d", ts->resp->status);
+ h2_tunnel_go_state(cf, ts, H2_TUNNEL_ESTABLISHED, data);
+ return CURLE_OK;
+ }
+
+ if(ts->resp->status == 401) {
+ auth_reply = Curl_dynhds_cget(&ts->resp->headers, "WWW-Authenticate");
+ }
+ else if(ts->resp->status == 407) {
+ auth_reply = Curl_dynhds_cget(&ts->resp->headers, "Proxy-Authenticate");
+ }
+
+ if(auth_reply) {
+ CURL_TRC_CF(data, cf, "[0] CONNECT: fwd auth header '%s'",
+ auth_reply->value);
+ result = Curl_http_input_auth(data, ts->resp->status == 407,
+ auth_reply->value);
+ if(result)
+ return result;
+ if(data->req.newurl) {
+ /* Indicator that we should try again */
+ Curl_safefree(data->req.newurl);
+ h2_tunnel_go_state(cf, ts, H2_TUNNEL_INIT, data);
+ return CURLE_OK;
+ }
+ }
+
+ /* Seems to have failed */
+ return CURLE_RECV_ERROR;
+}
+
+static CURLcode H2_CONNECT(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct tunnel_stream *ts)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ CURLcode result = CURLE_OK;
+
+ DEBUGASSERT(ts);
+ DEBUGASSERT(ts->authority);
+ do {
+ switch(ts->state) {
+ case H2_TUNNEL_INIT:
+ /* Prepare the CONNECT request and make a first attempt to send. */
+ CURL_TRC_CF(data, cf, "[0] CONNECT start for %s", ts->authority);
+ result = submit_CONNECT(cf, data, ts);
+ if(result)
+ goto out;
+ h2_tunnel_go_state(cf, ts, H2_TUNNEL_CONNECT, data);
+ /* FALLTHROUGH */
+
+ case H2_TUNNEL_CONNECT:
+ /* see that the request is completely sent */
+ result = proxy_h2_progress_ingress(cf, data);
+ if(!result)
+ result = proxy_h2_progress_egress(cf, data);
+ if(result && result != CURLE_AGAIN) {
+ h2_tunnel_go_state(cf, ts, H2_TUNNEL_FAILED, data);
+ break;
+ }
+
+ if(ts->has_final_response) {
+ h2_tunnel_go_state(cf, ts, H2_TUNNEL_RESPONSE, data);
+ }
+ else {
+ result = CURLE_OK;
+ goto out;
+ }
+ /* FALLTHROUGH */
+
+ case H2_TUNNEL_RESPONSE:
+ DEBUGASSERT(ts->has_final_response);
+ result = inspect_response(cf, data, ts);
+ if(result)
+ goto out;
+ break;
+
+ case H2_TUNNEL_ESTABLISHED:
+ return CURLE_OK;
+
+ case H2_TUNNEL_FAILED:
+ return CURLE_RECV_ERROR;
+
+ default:
+ break;
+ }
+
+ } while(ts->state == H2_TUNNEL_INIT);
+
+out:
+ if(result || ctx->tunnel.closed)
+ h2_tunnel_go_state(cf, ts, H2_TUNNEL_FAILED, data);
+ return result;
+}
+
+static CURLcode cf_h2_proxy_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool blocking, bool *done)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ CURLcode result = CURLE_OK;
+ struct cf_call_data save;
+ timediff_t check;
+ struct tunnel_stream *ts = &ctx->tunnel;
+
+ if(cf->connected) {
+ *done = TRUE;
+ return CURLE_OK;
+ }
+
+ /* Connect the lower filters first */
+ if(!cf->next->connected) {
+ result = Curl_conn_cf_connect(cf->next, data, blocking, done);
+ if(result || !*done)
+ return result;
+ }
+
+ *done = FALSE;
+
+ CF_DATA_SAVE(save, cf, data);
+ if(!ctx->h2) {
+ result = cf_h2_proxy_ctx_init(cf, data);
+ if(result)
+ goto out;
+ }
+ DEBUGASSERT(ts->authority);
+
+ check = Curl_timeleft(data, NULL, TRUE);
+ if(check <= 0) {
+ failf(data, "Proxy CONNECT aborted due to timeout");
+ result = CURLE_OPERATION_TIMEDOUT;
+ goto out;
+ }
+
+ /* for the secondary socket (FTP), use the "connect to host"
+ * but ignore the "connect to port" (use the secondary port)
+ */
+ result = H2_CONNECT(cf, data, ts);
+
+out:
+ *done = (result == CURLE_OK) && (ts->state == H2_TUNNEL_ESTABLISHED);
+ cf->connected = *done;
+ CF_DATA_RESTORE(cf, save);
+ return result;
+}
+
+static void cf_h2_proxy_close(struct Curl_cfilter *cf, struct Curl_easy *data)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+
+ if(ctx) {
+ struct cf_call_data save;
+
+ CF_DATA_SAVE(save, cf, data);
+ cf_h2_proxy_ctx_clear(ctx);
+ CF_DATA_RESTORE(cf, save);
+ }
+ if(cf->next)
+ cf->next->cft->do_close(cf->next, data);
+}
+
+static void cf_h2_proxy_destroy(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+
+ (void)data;
+ if(ctx) {
+ cf_h2_proxy_ctx_free(ctx);
+ cf->ctx = NULL;
+ }
+}
+
+static bool cf_h2_proxy_data_pending(struct Curl_cfilter *cf,
+ const struct Curl_easy *data)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ if((ctx && !Curl_bufq_is_empty(&ctx->inbufq)) ||
+ (ctx && ctx->tunnel.state == H2_TUNNEL_ESTABLISHED &&
+ !Curl_bufq_is_empty(&ctx->tunnel.recvbuf)))
+ return TRUE;
+ return cf->next? cf->next->cft->has_data_pending(cf->next, data) : FALSE;
+}
+
+static int cf_h2_proxy_get_select_socks(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ curl_socket_t *sock)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ int bitmap = GETSOCK_BLANK;
+ struct cf_call_data save;
+
+ CF_DATA_SAVE(save, cf, data);
+ sock[0] = Curl_conn_cf_get_socket(cf, data);
+ bitmap |= GETSOCK_READSOCK(0);
+
+ /* HTTP/2 layer wants to send data) AND there's a window to send data in */
+ if(nghttp2_session_want_write(ctx->h2) &&
+ nghttp2_session_get_remote_window_size(ctx->h2))
+ bitmap |= GETSOCK_WRITESOCK(0);
+
+ CF_DATA_RESTORE(cf, save);
+ return bitmap;
+}
+
+static ssize_t h2_handle_tunnel_close(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ CURLcode *err)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ ssize_t rv = 0;
+
+ if(ctx->tunnel.error == NGHTTP2_REFUSED_STREAM) {
+ CURL_TRC_CF(data, cf, "[%d] REFUSED_STREAM, try again on a new "
+ "connection", ctx->tunnel.stream_id);
+ connclose(cf->conn, "REFUSED_STREAM"); /* don't use this anymore */
+ *err = CURLE_RECV_ERROR; /* trigger Curl_retry_request() later */
+ return -1;
+ }
+ else if(ctx->tunnel.error != NGHTTP2_NO_ERROR) {
+ failf(data, "HTTP/2 stream %u was not closed cleanly: %s (err %u)",
+ ctx->tunnel.stream_id, nghttp2_http2_strerror(ctx->tunnel.error),
+ ctx->tunnel.error);
+ *err = CURLE_HTTP2_STREAM;
+ return -1;
+ }
+ else if(ctx->tunnel.reset) {
+ failf(data, "HTTP/2 stream %u was reset", ctx->tunnel.stream_id);
+ *err = CURLE_RECV_ERROR;
+ return -1;
+ }
+
+ *err = CURLE_OK;
+ rv = 0;
+ CURL_TRC_CF(data, cf, "[%d] handle_tunnel_close -> %zd, %d",
+ ctx->tunnel.stream_id, rv, *err);
+ return rv;
+}
+
+static ssize_t tunnel_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
+ char *buf, size_t len, CURLcode *err)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ ssize_t nread = -1;
+
+ *err = CURLE_AGAIN;
+ if(!Curl_bufq_is_empty(&ctx->tunnel.recvbuf)) {
+ nread = Curl_bufq_read(&ctx->tunnel.recvbuf,
+ (unsigned char *)buf, len, err);
+ if(nread < 0)
+ goto out;
+ DEBUGASSERT(nread > 0);
+ }
+
+ if(nread < 0) {
+ if(ctx->tunnel.closed) {
+ nread = h2_handle_tunnel_close(cf, data, err);
+ }
+ else if(ctx->tunnel.reset ||
+ (ctx->conn_closed && Curl_bufq_is_empty(&ctx->inbufq)) ||
+ (ctx->goaway && ctx->last_stream_id < ctx->tunnel.stream_id)) {
+ *err = CURLE_RECV_ERROR;
+ nread = -1;
+ }
+ }
+ else if(nread == 0) {
+ *err = CURLE_AGAIN;
+ nread = -1;
+ }
+
+out:
+ CURL_TRC_CF(data, cf, "[%d] tunnel_recv(len=%zu) -> %zd, %d",
+ ctx->tunnel.stream_id, len, nread, *err);
+ return nread;
+}
+
+static ssize_t cf_h2_proxy_recv(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ char *buf, size_t len, CURLcode *err)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ ssize_t nread = -1;
+ struct cf_call_data save;
+ CURLcode result;
+
+ if(ctx->tunnel.state != H2_TUNNEL_ESTABLISHED) {
+ *err = CURLE_RECV_ERROR;
+ return -1;
+ }
+ CF_DATA_SAVE(save, cf, data);
+
+ if(Curl_bufq_is_empty(&ctx->tunnel.recvbuf)) {
+ *err = proxy_h2_progress_ingress(cf, data);
+ if(*err)
+ goto out;
+ }
+
+ nread = tunnel_recv(cf, data, buf, len, err);
+
+ if(nread > 0) {
+ CURL_TRC_CF(data, cf, "[%d] increase window by %zd",
+ ctx->tunnel.stream_id, nread);
+ nghttp2_session_consume(ctx->h2, ctx->tunnel.stream_id, (size_t)nread);
+ }
+
+ result = proxy_h2_progress_egress(cf, data);
+ if(result == CURLE_AGAIN) {
+ /* pending data to send, need to be called again. Ideally, we'd
+ * monitor the socket for POLLOUT, but we might not be in SENDING
+ * transfer state any longer and are unable to make this happen.
+ */
+ CURL_TRC_CF(data, cf, "[%d] egress blocked, DRAIN",
+ ctx->tunnel.stream_id);
+ drain_tunnel(cf, data, &ctx->tunnel);
+ }
+ else if(result) {
+ *err = result;
+ nread = -1;
+ }
+
+out:
+ if(!Curl_bufq_is_empty(&ctx->tunnel.recvbuf) &&
+ (nread >= 0 || *err == CURLE_AGAIN)) {
+ /* data pending and no fatal error to report. Need to trigger
+ * draining to avoid stalling when no socket events happen. */
+ drain_tunnel(cf, data, &ctx->tunnel);
+ }
+ CURL_TRC_CF(data, cf, "[%d] cf_recv(len=%zu) -> %zd %d",
+ ctx->tunnel.stream_id, len, nread, *err);
+ CF_DATA_RESTORE(cf, save);
+ return nread;
+}
+
+static ssize_t cf_h2_proxy_send(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ const void *buf, size_t len, CURLcode *err)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ struct cf_call_data save;
+ int rv;
+ ssize_t nwritten;
+ CURLcode result;
+ int blocked = 0;
+
+ if(ctx->tunnel.state != H2_TUNNEL_ESTABLISHED) {
+ *err = CURLE_SEND_ERROR;
+ return -1;
+ }
+ CF_DATA_SAVE(save, cf, data);
+
+ if(ctx->tunnel.closed) {
+ nwritten = -1;
+ *err = CURLE_SEND_ERROR;
+ goto out;
+ }
+ else if(ctx->tunnel.upload_blocked_len) {
+ /* the data in `buf` has already been submitted or added to the
+ * buffers, but have been EAGAINed on the last invocation. */
+ DEBUGASSERT(len >= ctx->tunnel.upload_blocked_len);
+ if(len < ctx->tunnel.upload_blocked_len) {
+ /* Did we get called again with a smaller `len`? This should not
+ * happen. We are not prepared to handle that. */
+ failf(data, "HTTP/2 proxy, send again with decreased length");
+ *err = CURLE_HTTP2;
+ nwritten = -1;
+ goto out;
+ }
+ nwritten = (ssize_t)ctx->tunnel.upload_blocked_len;
+ ctx->tunnel.upload_blocked_len = 0;
+ *err = CURLE_OK;
+ }
+ else {
+ nwritten = Curl_bufq_write(&ctx->tunnel.sendbuf, buf, len, err);
+ if(nwritten < 0) {
+ if(*err != CURLE_AGAIN)
+ goto out;
+ nwritten = 0;
+ }
+ }
+
+ if(!Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) {
+ /* req body data is buffered, resume the potentially suspended stream */
+ rv = nghttp2_session_resume_data(ctx->h2, ctx->tunnel.stream_id);
+ if(nghttp2_is_fatal(rv)) {
+ *err = CURLE_SEND_ERROR;
+ nwritten = -1;
+ goto out;
+ }
+ }
+
+ result = proxy_h2_progress_ingress(cf, data);
+ if(result) {
+ *err = result;
+ nwritten = -1;
+ goto out;
+ }
+
+ /* Call the nghttp2 send loop and flush to write ALL buffered data,
+ * headers and/or request body completely out to the network */
+ result = proxy_h2_progress_egress(cf, data);
+ if(result == CURLE_AGAIN) {
+ blocked = 1;
+ }
+ else if(result) {
+ *err = result;
+ nwritten = -1;
+ goto out;
+ }
+ else if(!Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) {
+ /* although we wrote everything that nghttp2 wants to send now,
+ * there is data left in our stream send buffer unwritten. This may
+ * be due to the stream's HTTP/2 flow window being exhausted. */
+ blocked = 1;
+ }
+
+ if(blocked) {
+ /* Unable to send all data, due to connection blocked or H2 window
+ * exhaustion. Data is left in our stream buffer, or nghttp2's internal
+ * frame buffer or our network out buffer. */
+ size_t rwin = nghttp2_session_get_stream_remote_window_size(
+ ctx->h2, ctx->tunnel.stream_id);
+ if(rwin == 0) {
+ /* H2 flow window exhaustion.
+ * FIXME: there is no way to HOLD all transfers that use this
+ * proxy connection AND to UNHOLD all of them again when the
+ * window increases.
+ * We *could* iterate over all data on this conn maybe? */
+ CURL_TRC_CF(data, cf, "[%d] remote flow "
+ "window is exhausted", ctx->tunnel.stream_id);
+ }
+
+ /* Whatever the cause, we need to return CURL_EAGAIN for this call.
+ * We have unwritten state that needs us being invoked again and EAGAIN
+ * is the only way to ensure that. */
+ ctx->tunnel.upload_blocked_len = nwritten;
+ CURL_TRC_CF(data, cf, "[%d] cf_send(len=%zu) BLOCK: win %u/%zu "
+ "blocked_len=%zu",
+ ctx->tunnel.stream_id, len,
+ nghttp2_session_get_remote_window_size(ctx->h2), rwin,
+ nwritten);
+ drain_tunnel(cf, data, &ctx->tunnel);
+ *err = CURLE_AGAIN;
+ nwritten = -1;
+ goto out;
+ }
+ else if(proxy_h2_should_close_session(ctx)) {
+ /* nghttp2 thinks this session is done. If the stream has not been
+ * closed, this is an error state for out transfer */
+ if(ctx->tunnel.closed) {
+ *err = CURLE_SEND_ERROR;
+ nwritten = -1;
+ }
+ else {
+ CURL_TRC_CF(data, cf, "[0] send: nothing to do in this session");
+ *err = CURLE_HTTP2;
+ nwritten = -1;
+ }
+ }
+
+out:
+ if(!Curl_bufq_is_empty(&ctx->tunnel.recvbuf) &&
+ (nwritten >= 0 || *err == CURLE_AGAIN)) {
+ /* data pending and no fatal error to report. Need to trigger
+ * draining to avoid stalling when no socket events happen. */
+ drain_tunnel(cf, data, &ctx->tunnel);
+ }
+ CURL_TRC_CF(data, cf, "[%d] cf_send(len=%zu) -> %zd, %d, "
+ "h2 windows %d-%d (stream-conn), buffers %zu-%zu (stream-conn)",
+ ctx->tunnel.stream_id, len, nwritten, *err,
+ nghttp2_session_get_stream_remote_window_size(
+ ctx->h2, ctx->tunnel.stream_id),
+ nghttp2_session_get_remote_window_size(ctx->h2),
+ Curl_bufq_len(&ctx->tunnel.sendbuf),
+ Curl_bufq_len(&ctx->outbufq));
+ CF_DATA_RESTORE(cf, save);
+ return nwritten;
+}
+
+static bool proxy_h2_connisalive(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *input_pending)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ bool alive = TRUE;
+
+ *input_pending = FALSE;
+ if(!cf->next || !cf->next->cft->is_alive(cf->next, data, input_pending))
+ return FALSE;
+
+ if(*input_pending) {
+ /* This happens before we've sent off a request and the connection is
+ not in use by any other transfer, there shouldn't be any data here,
+ only "protocol frames" */
+ CURLcode result;
+ ssize_t nread = -1;
+
+ *input_pending = FALSE;
+ nread = Curl_bufq_slurp(&ctx->inbufq, proxy_nw_in_reader, cf, &result);
+ if(nread != -1) {
+ if(proxy_h2_process_pending_input(cf, data, &result) < 0)
+ /* immediate error, considered dead */
+ alive = FALSE;
+ else {
+ alive = !proxy_h2_should_close_session(ctx);
+ }
+ }
+ else if(result != CURLE_AGAIN) {
+ /* the read failed so let's say this is dead anyway */
+ alive = FALSE;
+ }
+ }
+
+ return alive;
+}
+
+static bool cf_h2_proxy_is_alive(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *input_pending)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ CURLcode result;
+ struct cf_call_data save;
+
+ CF_DATA_SAVE(save, cf, data);
+ result = (ctx && ctx->h2 && proxy_h2_connisalive(cf, data, input_pending));
+ CURL_TRC_CF(data, cf, "[0] conn alive -> %d, input_pending=%d",
+ result, *input_pending);
+ CF_DATA_RESTORE(cf, save);
+ return result;
+}
+
+struct Curl_cftype Curl_cft_h2_proxy = {
+ "H2-PROXY",
+ CF_TYPE_IP_CONNECT,
+ CURL_LOG_LVL_NONE,
+ cf_h2_proxy_destroy,
+ cf_h2_proxy_connect,
+ cf_h2_proxy_close,
+ Curl_cf_http_proxy_get_host,
+ cf_h2_proxy_get_select_socks,
+ cf_h2_proxy_data_pending,
+ cf_h2_proxy_send,
+ cf_h2_proxy_recv,
+ Curl_cf_def_cntrl,
+ cf_h2_proxy_is_alive,
+ Curl_cf_def_conn_keep_alive,
+ Curl_cf_def_query,
+};
+
+CURLcode Curl_cf_h2_proxy_insert_after(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ struct Curl_cfilter *cf_h2_proxy = NULL;
+ struct cf_h2_proxy_ctx *ctx;
+ CURLcode result = CURLE_OUT_OF_MEMORY;
+
+ (void)data;
+ ctx = calloc(sizeof(*ctx), 1);
+ if(!ctx)
+ goto out;
+
+ result = Curl_cf_create(&cf_h2_proxy, &Curl_cft_h2_proxy, ctx);
+ if(result)
+ goto out;
+
+ Curl_conn_cf_insert_after(cf, cf_h2_proxy);
+ result = CURLE_OK;
+
+out:
+ if(result)
+ cf_h2_proxy_ctx_free(ctx);
+ return result;
+}
+
+#endif /* defined(USE_NGHTTP2) && !defined(CURL_DISABLE_PROXY) */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/cf-h2-proxy.h b/iotdb-client/odbc/deps/curl-src/lib/cf-h2-proxy.h
new file mode 100644
index 0000000000000..c01bf62133b6a
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/cf-h2-proxy.h
@@ -0,0 +1,39 @@
+#ifndef HEADER_CURL_H2_PROXY_H
+#define HEADER_CURL_H2_PROXY_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NGHTTP2) && !defined(CURL_DISABLE_PROXY)
+
+CURLcode Curl_cf_h2_proxy_insert_after(struct Curl_cfilter *cf,
+ struct Curl_easy *data);
+
+extern struct Curl_cftype Curl_cft_h2_proxy;
+
+
+#endif /* defined(USE_NGHTTP2) && !defined(CURL_DISABLE_PROXY) */
+
+#endif /* HEADER_CURL_H2_PROXY_H */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/cf-haproxy.c b/iotdb-client/odbc/deps/curl-src/lib/cf-haproxy.c
new file mode 100644
index 0000000000000..39ac4157175c3
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/cf-haproxy.c
@@ -0,0 +1,251 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_PROXY)
+
+#include
+#include "urldata.h"
+#include "cfilters.h"
+#include "cf-haproxy.h"
+#include "curl_trc.h"
+#include "multiif.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+
+typedef enum {
+ HAPROXY_INIT, /* init/default/no tunnel state */
+ HAPROXY_SEND, /* data_out being sent */
+ HAPROXY_DONE /* all work done */
+} haproxy_state;
+
+struct cf_haproxy_ctx {
+ int state;
+ struct dynbuf data_out;
+};
+
+static void cf_haproxy_ctx_reset(struct cf_haproxy_ctx *ctx)
+{
+ DEBUGASSERT(ctx);
+ ctx->state = HAPROXY_INIT;
+ Curl_dyn_reset(&ctx->data_out);
+}
+
+static void cf_haproxy_ctx_free(struct cf_haproxy_ctx *ctx)
+{
+ if(ctx) {
+ Curl_dyn_free(&ctx->data_out);
+ free(ctx);
+ }
+}
+
+static CURLcode cf_haproxy_date_out_set(struct Curl_cfilter*cf,
+ struct Curl_easy *data)
+{
+ struct cf_haproxy_ctx *ctx = cf->ctx;
+ CURLcode result;
+ const char *tcp_version;
+ const char *client_ip;
+
+ DEBUGASSERT(ctx);
+ DEBUGASSERT(ctx->state == HAPROXY_INIT);
+#ifdef USE_UNIX_SOCKETS
+ if(cf->conn->unix_domain_socket)
+ /* the buffer is large enough to hold this! */
+ result = Curl_dyn_addn(&ctx->data_out, STRCONST("PROXY UNKNOWN\r\n"));
+ else {
+#endif /* USE_UNIX_SOCKETS */
+ /* Emit the correct prefix for IPv6 */
+ tcp_version = cf->conn->bits.ipv6 ? "TCP6" : "TCP4";
+ if(data->set.str[STRING_HAPROXY_CLIENT_IP])
+ client_ip = data->set.str[STRING_HAPROXY_CLIENT_IP];
+ else
+ client_ip = data->info.conn_local_ip;
+
+ result = Curl_dyn_addf(&ctx->data_out, "PROXY %s %s %s %i %i\r\n",
+ tcp_version,
+ client_ip,
+ data->info.conn_primary_ip,
+ data->info.conn_local_port,
+ data->info.conn_primary_port);
+
+#ifdef USE_UNIX_SOCKETS
+ }
+#endif /* USE_UNIX_SOCKETS */
+ return result;
+}
+
+static CURLcode cf_haproxy_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool blocking, bool *done)
+{
+ struct cf_haproxy_ctx *ctx = cf->ctx;
+ CURLcode result;
+ size_t len;
+
+ DEBUGASSERT(ctx);
+ if(cf->connected) {
+ *done = TRUE;
+ return CURLE_OK;
+ }
+
+ result = cf->next->cft->do_connect(cf->next, data, blocking, done);
+ if(result || !*done)
+ return result;
+
+ switch(ctx->state) {
+ case HAPROXY_INIT:
+ result = cf_haproxy_date_out_set(cf, data);
+ if(result)
+ goto out;
+ ctx->state = HAPROXY_SEND;
+ /* FALLTHROUGH */
+ case HAPROXY_SEND:
+ len = Curl_dyn_len(&ctx->data_out);
+ if(len > 0) {
+ ssize_t written = Curl_conn_send(data, cf->sockindex,
+ Curl_dyn_ptr(&ctx->data_out),
+ len, &result);
+ if(written < 0)
+ goto out;
+ Curl_dyn_tail(&ctx->data_out, len - (size_t)written);
+ if(Curl_dyn_len(&ctx->data_out) > 0) {
+ result = CURLE_OK;
+ goto out;
+ }
+ }
+ ctx->state = HAPROXY_DONE;
+ /* FALLTHROUGH */
+ default:
+ Curl_dyn_free(&ctx->data_out);
+ break;
+ }
+
+out:
+ *done = (!result) && (ctx->state == HAPROXY_DONE);
+ cf->connected = *done;
+ return result;
+}
+
+static void cf_haproxy_destroy(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ (void)data;
+ CURL_TRC_CF(data, cf, "destroy");
+ cf_haproxy_ctx_free(cf->ctx);
+}
+
+static void cf_haproxy_close(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ CURL_TRC_CF(data, cf, "close");
+ cf->connected = FALSE;
+ cf_haproxy_ctx_reset(cf->ctx);
+ if(cf->next)
+ cf->next->cft->do_close(cf->next, data);
+}
+
+static int cf_haproxy_get_select_socks(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ curl_socket_t *socks)
+{
+ int fds;
+
+ fds = cf->next->cft->get_select_socks(cf->next, data, socks);
+ if(!fds && cf->next->connected && !cf->connected) {
+ /* If we are not connected, but the filter "below" is
+ * and not waiting on something, we are sending. */
+ socks[0] = Curl_conn_cf_get_socket(cf, data);
+ return GETSOCK_WRITESOCK(0);
+ }
+ return fds;
+}
+
+
+struct Curl_cftype Curl_cft_haproxy = {
+ "HAPROXY",
+ 0,
+ 0,
+ cf_haproxy_destroy,
+ cf_haproxy_connect,
+ cf_haproxy_close,
+ Curl_cf_def_get_host,
+ cf_haproxy_get_select_socks,
+ Curl_cf_def_data_pending,
+ Curl_cf_def_send,
+ Curl_cf_def_recv,
+ Curl_cf_def_cntrl,
+ Curl_cf_def_conn_is_alive,
+ Curl_cf_def_conn_keep_alive,
+ Curl_cf_def_query,
+};
+
+static CURLcode cf_haproxy_create(struct Curl_cfilter **pcf,
+ struct Curl_easy *data)
+{
+ struct Curl_cfilter *cf = NULL;
+ struct cf_haproxy_ctx *ctx;
+ CURLcode result;
+
+ (void)data;
+ ctx = calloc(sizeof(*ctx), 1);
+ if(!ctx) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+ ctx->state = HAPROXY_INIT;
+ Curl_dyn_init(&ctx->data_out, DYN_HAXPROXY);
+
+ result = Curl_cf_create(&cf, &Curl_cft_haproxy, ctx);
+ if(result)
+ goto out;
+ ctx = NULL;
+
+out:
+ cf_haproxy_ctx_free(ctx);
+ *pcf = result? NULL : cf;
+ return result;
+}
+
+CURLcode Curl_cf_haproxy_insert_after(struct Curl_cfilter *cf_at,
+ struct Curl_easy *data)
+{
+ struct Curl_cfilter *cf;
+ CURLcode result;
+
+ result = cf_haproxy_create(&cf, data);
+ if(result)
+ goto out;
+ Curl_conn_cf_insert_after(cf_at, cf);
+
+out:
+ return result;
+}
+
+#endif /* !CURL_DISABLE_PROXY */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/cf-haproxy.h b/iotdb-client/odbc/deps/curl-src/lib/cf-haproxy.h
new file mode 100644
index 0000000000000..d02c323e7b708
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/cf-haproxy.h
@@ -0,0 +1,39 @@
+#ifndef HEADER_CURL_CF_HAPROXY_H
+#define HEADER_CURL_CF_HAPROXY_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "urldata.h"
+
+#if !defined(CURL_DISABLE_PROXY)
+
+CURLcode Curl_cf_haproxy_insert_after(struct Curl_cfilter *cf_at,
+ struct Curl_easy *data);
+
+extern struct Curl_cftype Curl_cft_haproxy;
+
+#endif /* !CURL_DISABLE_PROXY */
+
+#endif /* HEADER_CURL_CF_HAPROXY_H */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/cf-https-connect.c b/iotdb-client/odbc/deps/curl-src/lib/cf-https-connect.c
new file mode 100644
index 0000000000000..be54aec7402bd
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/cf-https-connect.c
@@ -0,0 +1,551 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER)
+
+#include "urldata.h"
+#include
+#include "curl_trc.h"
+#include "cfilters.h"
+#include "connect.h"
+#include "multiif.h"
+#include "cf-https-connect.h"
+#include "http2.h"
+#include "vquic/vquic.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+
+typedef enum {
+ CF_HC_INIT,
+ CF_HC_CONNECT,
+ CF_HC_SUCCESS,
+ CF_HC_FAILURE
+} cf_hc_state;
+
+struct cf_hc_baller {
+ const char *name;
+ struct Curl_cfilter *cf;
+ CURLcode result;
+ struct curltime started;
+ int reply_ms;
+ bool enabled;
+};
+
+static void cf_hc_baller_reset(struct cf_hc_baller *b,
+ struct Curl_easy *data)
+{
+ if(b->cf) {
+ Curl_conn_cf_close(b->cf, data);
+ Curl_conn_cf_discard_chain(&b->cf, data);
+ b->cf = NULL;
+ }
+ b->result = CURLE_OK;
+ b->reply_ms = -1;
+}
+
+static bool cf_hc_baller_is_active(struct cf_hc_baller *b)
+{
+ return b->enabled && b->cf && !b->result;
+}
+
+static bool cf_hc_baller_has_started(struct cf_hc_baller *b)
+{
+ return !!b->cf;
+}
+
+static int cf_hc_baller_reply_ms(struct cf_hc_baller *b,
+ struct Curl_easy *data)
+{
+ if(b->reply_ms < 0)
+ b->cf->cft->query(b->cf, data, CF_QUERY_CONNECT_REPLY_MS,
+ &b->reply_ms, NULL);
+ return b->reply_ms;
+}
+
+static bool cf_hc_baller_data_pending(struct cf_hc_baller *b,
+ const struct Curl_easy *data)
+{
+ return b->cf && !b->result && b->cf->cft->has_data_pending(b->cf, data);
+}
+
+struct cf_hc_ctx {
+ cf_hc_state state;
+ const struct Curl_dns_entry *remotehost;
+ struct curltime started; /* when connect started */
+ CURLcode result; /* overall result */
+ struct cf_hc_baller h3_baller;
+ struct cf_hc_baller h21_baller;
+ int soft_eyeballs_timeout_ms;
+ int hard_eyeballs_timeout_ms;
+};
+
+static void cf_hc_baller_init(struct cf_hc_baller *b,
+ struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ const char *name,
+ int transport)
+{
+ struct cf_hc_ctx *ctx = cf->ctx;
+ struct Curl_cfilter *save = cf->next;
+
+ b->name = name;
+ cf->next = NULL;
+ b->started = Curl_now();
+ b->result = Curl_cf_setup_insert_after(cf, data, ctx->remotehost,
+ transport, CURL_CF_SSL_ENABLE);
+ b->cf = cf->next;
+ cf->next = save;
+}
+
+static CURLcode cf_hc_baller_connect(struct cf_hc_baller *b,
+ struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *done)
+{
+ struct Curl_cfilter *save = cf->next;
+
+ cf->next = b->cf;
+ b->result = Curl_conn_cf_connect(cf->next, data, FALSE, done);
+ b->cf = cf->next; /* it might mutate */
+ cf->next = save;
+ return b->result;
+}
+
+static void cf_hc_reset(struct Curl_cfilter *cf, struct Curl_easy *data)
+{
+ struct cf_hc_ctx *ctx = cf->ctx;
+
+ if(ctx) {
+ cf_hc_baller_reset(&ctx->h3_baller, data);
+ cf_hc_baller_reset(&ctx->h21_baller, data);
+ ctx->state = CF_HC_INIT;
+ ctx->result = CURLE_OK;
+ ctx->hard_eyeballs_timeout_ms = data->set.happy_eyeballs_timeout;
+ ctx->soft_eyeballs_timeout_ms = data->set.happy_eyeballs_timeout / 2;
+ }
+}
+
+static CURLcode baller_connected(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct cf_hc_baller *winner)
+{
+ struct cf_hc_ctx *ctx = cf->ctx;
+ CURLcode result = CURLE_OK;
+
+ DEBUGASSERT(winner->cf);
+ if(winner != &ctx->h3_baller)
+ cf_hc_baller_reset(&ctx->h3_baller, data);
+ if(winner != &ctx->h21_baller)
+ cf_hc_baller_reset(&ctx->h21_baller, data);
+
+ CURL_TRC_CF(data, cf, "connect+handshake %s: %dms, 1st data: %dms",
+ winner->name, (int)Curl_timediff(Curl_now(), winner->started),
+ cf_hc_baller_reply_ms(winner, data));
+ cf->next = winner->cf;
+ winner->cf = NULL;
+
+ switch(cf->conn->alpn) {
+ case CURL_HTTP_VERSION_3:
+ infof(data, "using HTTP/3");
+ break;
+ case CURL_HTTP_VERSION_2:
+#ifdef USE_NGHTTP2
+ /* Using nghttp2, we add the filter "below" us, so when the conn
+ * closes, we tear it down for a fresh reconnect */
+ result = Curl_http2_switch_at(cf, data);
+ if(result) {
+ ctx->state = CF_HC_FAILURE;
+ ctx->result = result;
+ return result;
+ }
+#endif
+ infof(data, "using HTTP/2");
+ break;
+ case CURL_HTTP_VERSION_1_1:
+ infof(data, "using HTTP/1.1");
+ break;
+ default:
+ infof(data, "using HTTP/1.x");
+ break;
+ }
+ ctx->state = CF_HC_SUCCESS;
+ cf->connected = TRUE;
+ Curl_conn_cf_cntrl(cf->next, data, TRUE,
+ CF_CTRL_CONN_INFO_UPDATE, 0, NULL);
+ return result;
+}
+
+
+static bool time_to_start_h21(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct curltime now)
+{
+ struct cf_hc_ctx *ctx = cf->ctx;
+ timediff_t elapsed_ms;
+
+ if(!ctx->h21_baller.enabled || cf_hc_baller_has_started(&ctx->h21_baller))
+ return FALSE;
+
+ if(!ctx->h3_baller.enabled || !cf_hc_baller_is_active(&ctx->h3_baller))
+ return TRUE;
+
+ elapsed_ms = Curl_timediff(now, ctx->started);
+ if(elapsed_ms >= ctx->hard_eyeballs_timeout_ms) {
+ CURL_TRC_CF(data, cf, "hard timeout of %dms reached, starting h21",
+ ctx->hard_eyeballs_timeout_ms);
+ return TRUE;
+ }
+
+ if(elapsed_ms >= ctx->soft_eyeballs_timeout_ms) {
+ if(cf_hc_baller_reply_ms(&ctx->h3_baller, data) < 0) {
+ CURL_TRC_CF(data, cf, "soft timeout of %dms reached, h3 has not "
+ "seen any data, starting h21",
+ ctx->soft_eyeballs_timeout_ms);
+ return TRUE;
+ }
+ /* set the effective hard timeout again */
+ Curl_expire(data, ctx->hard_eyeballs_timeout_ms - elapsed_ms,
+ EXPIRE_ALPN_EYEBALLS);
+ }
+ return FALSE;
+}
+
+static CURLcode cf_hc_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool blocking, bool *done)
+{
+ struct cf_hc_ctx *ctx = cf->ctx;
+ struct curltime now;
+ CURLcode result = CURLE_OK;
+
+ (void)blocking;
+ if(cf->connected) {
+ *done = TRUE;
+ return CURLE_OK;
+ }
+
+ *done = FALSE;
+ now = Curl_now();
+ switch(ctx->state) {
+ case CF_HC_INIT:
+ DEBUGASSERT(!ctx->h3_baller.cf);
+ DEBUGASSERT(!ctx->h21_baller.cf);
+ DEBUGASSERT(!cf->next);
+ CURL_TRC_CF(data, cf, "connect, init");
+ ctx->started = now;
+ if(ctx->h3_baller.enabled) {
+ cf_hc_baller_init(&ctx->h3_baller, cf, data, "h3", TRNSPRT_QUIC);
+ if(ctx->h21_baller.enabled)
+ Curl_expire(data, ctx->soft_eyeballs_timeout_ms, EXPIRE_ALPN_EYEBALLS);
+ }
+ else if(ctx->h21_baller.enabled)
+ cf_hc_baller_init(&ctx->h21_baller, cf, data, "h21",
+ cf->conn->transport);
+ ctx->state = CF_HC_CONNECT;
+ /* FALLTHROUGH */
+
+ case CF_HC_CONNECT:
+ if(cf_hc_baller_is_active(&ctx->h3_baller)) {
+ result = cf_hc_baller_connect(&ctx->h3_baller, cf, data, done);
+ if(!result && *done) {
+ result = baller_connected(cf, data, &ctx->h3_baller);
+ goto out;
+ }
+ }
+
+ if(time_to_start_h21(cf, data, now)) {
+ cf_hc_baller_init(&ctx->h21_baller, cf, data, "h21",
+ cf->conn->transport);
+ }
+
+ if(cf_hc_baller_is_active(&ctx->h21_baller)) {
+ CURL_TRC_CF(data, cf, "connect, check h21");
+ result = cf_hc_baller_connect(&ctx->h21_baller, cf, data, done);
+ if(!result && *done) {
+ result = baller_connected(cf, data, &ctx->h21_baller);
+ goto out;
+ }
+ }
+
+ if((!ctx->h3_baller.enabled || ctx->h3_baller.result) &&
+ (!ctx->h21_baller.enabled || ctx->h21_baller.result)) {
+ /* both failed or disabled. we give up */
+ CURL_TRC_CF(data, cf, "connect, all failed");
+ result = ctx->result = ctx->h3_baller.enabled?
+ ctx->h3_baller.result : ctx->h21_baller.result;
+ ctx->state = CF_HC_FAILURE;
+ goto out;
+ }
+ result = CURLE_OK;
+ *done = FALSE;
+ break;
+
+ case CF_HC_FAILURE:
+ result = ctx->result;
+ cf->connected = FALSE;
+ *done = FALSE;
+ break;
+
+ case CF_HC_SUCCESS:
+ result = CURLE_OK;
+ cf->connected = TRUE;
+ *done = TRUE;
+ break;
+ }
+
+out:
+ CURL_TRC_CF(data, cf, "connect -> %d, done=%d", result, *done);
+ return result;
+}
+
+static int cf_hc_get_select_socks(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ curl_socket_t *socks)
+{
+ struct cf_hc_ctx *ctx = cf->ctx;
+ size_t i, j, s;
+ int brc, rc = GETSOCK_BLANK;
+ curl_socket_t bsocks[MAX_SOCKSPEREASYHANDLE];
+ struct cf_hc_baller *ballers[2];
+
+ if(cf->connected)
+ return cf->next->cft->get_select_socks(cf->next, data, socks);
+
+ ballers[0] = &ctx->h3_baller;
+ ballers[1] = &ctx->h21_baller;
+ for(i = s = 0; i < sizeof(ballers)/sizeof(ballers[0]); i++) {
+ struct cf_hc_baller *b = ballers[i];
+ if(!cf_hc_baller_is_active(b))
+ continue;
+ brc = Curl_conn_cf_get_select_socks(b->cf, data, bsocks);
+ CURL_TRC_CF(data, cf, "get_selected_socks(%s) -> %x", b->name, brc);
+ if(!brc)
+ continue;
+ for(j = 0; j < MAX_SOCKSPEREASYHANDLE && s < MAX_SOCKSPEREASYHANDLE; ++j) {
+ if((brc & GETSOCK_WRITESOCK(j)) || (brc & GETSOCK_READSOCK(j))) {
+ socks[s] = bsocks[j];
+ if(brc & GETSOCK_WRITESOCK(j))
+ rc |= GETSOCK_WRITESOCK(s);
+ if(brc & GETSOCK_READSOCK(j))
+ rc |= GETSOCK_READSOCK(s);
+ s++;
+ }
+ }
+ }
+ CURL_TRC_CF(data, cf, "get_selected_socks -> %x", rc);
+ return rc;
+}
+
+static bool cf_hc_data_pending(struct Curl_cfilter *cf,
+ const struct Curl_easy *data)
+{
+ struct cf_hc_ctx *ctx = cf->ctx;
+
+ if(cf->connected)
+ return cf->next->cft->has_data_pending(cf->next, data);
+
+ CURL_TRC_CF((struct Curl_easy *)data, cf, "data_pending");
+ return cf_hc_baller_data_pending(&ctx->h3_baller, data)
+ || cf_hc_baller_data_pending(&ctx->h21_baller, data);
+}
+
+static struct curltime cf_get_max_baller_time(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ int query)
+{
+ struct cf_hc_ctx *ctx = cf->ctx;
+ struct Curl_cfilter *cfb;
+ struct curltime t, tmax;
+
+ memset(&tmax, 0, sizeof(tmax));
+ memset(&t, 0, sizeof(t));
+ cfb = ctx->h21_baller.enabled? ctx->h21_baller.cf : NULL;
+ if(cfb && !cfb->cft->query(cfb, data, query, NULL, &t)) {
+ if((t.tv_sec || t.tv_usec) && Curl_timediff_us(t, tmax) > 0)
+ tmax = t;
+ }
+ memset(&t, 0, sizeof(t));
+ cfb = ctx->h3_baller.enabled? ctx->h3_baller.cf : NULL;
+ if(cfb && !cfb->cft->query(cfb, data, query, NULL, &t)) {
+ if((t.tv_sec || t.tv_usec) && Curl_timediff_us(t, tmax) > 0)
+ tmax = t;
+ }
+ return tmax;
+}
+
+static CURLcode cf_hc_query(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ int query, int *pres1, void *pres2)
+{
+ if(!cf->connected) {
+ switch(query) {
+ case CF_QUERY_TIMER_CONNECT: {
+ struct curltime *when = pres2;
+ *when = cf_get_max_baller_time(cf, data, CF_QUERY_TIMER_CONNECT);
+ return CURLE_OK;
+ }
+ case CF_QUERY_TIMER_APPCONNECT: {
+ struct curltime *when = pres2;
+ *when = cf_get_max_baller_time(cf, data, CF_QUERY_TIMER_APPCONNECT);
+ return CURLE_OK;
+ }
+ default:
+ break;
+ }
+ }
+ return cf->next?
+ cf->next->cft->query(cf->next, data, query, pres1, pres2) :
+ CURLE_UNKNOWN_OPTION;
+}
+
+static void cf_hc_close(struct Curl_cfilter *cf, struct Curl_easy *data)
+{
+ CURL_TRC_CF(data, cf, "close");
+ cf_hc_reset(cf, data);
+ cf->connected = FALSE;
+
+ if(cf->next) {
+ cf->next->cft->do_close(cf->next, data);
+ Curl_conn_cf_discard_chain(&cf->next, data);
+ }
+}
+
+static void cf_hc_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
+{
+ struct cf_hc_ctx *ctx = cf->ctx;
+
+ (void)data;
+ CURL_TRC_CF(data, cf, "destroy");
+ cf_hc_reset(cf, data);
+ Curl_safefree(ctx);
+}
+
+struct Curl_cftype Curl_cft_http_connect = {
+ "HTTPS-CONNECT",
+ 0,
+ CURL_LOG_LVL_NONE,
+ cf_hc_destroy,
+ cf_hc_connect,
+ cf_hc_close,
+ Curl_cf_def_get_host,
+ cf_hc_get_select_socks,
+ cf_hc_data_pending,
+ Curl_cf_def_send,
+ Curl_cf_def_recv,
+ Curl_cf_def_cntrl,
+ Curl_cf_def_conn_is_alive,
+ Curl_cf_def_conn_keep_alive,
+ cf_hc_query,
+};
+
+static CURLcode cf_hc_create(struct Curl_cfilter **pcf,
+ struct Curl_easy *data,
+ const struct Curl_dns_entry *remotehost,
+ bool try_h3, bool try_h21)
+{
+ struct Curl_cfilter *cf = NULL;
+ struct cf_hc_ctx *ctx;
+ CURLcode result = CURLE_OK;
+
+ (void)data;
+ ctx = calloc(sizeof(*ctx), 1);
+ if(!ctx) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+ ctx->remotehost = remotehost;
+ ctx->h3_baller.enabled = try_h3;
+ ctx->h21_baller.enabled = try_h21;
+
+ result = Curl_cf_create(&cf, &Curl_cft_http_connect, ctx);
+ if(result)
+ goto out;
+ ctx = NULL;
+ cf_hc_reset(cf, data);
+
+out:
+ *pcf = result? NULL : cf;
+ free(ctx);
+ return result;
+}
+
+static CURLcode cf_http_connect_add(struct Curl_easy *data,
+ struct connectdata *conn,
+ int sockindex,
+ const struct Curl_dns_entry *remotehost,
+ bool try_h3, bool try_h21)
+{
+ struct Curl_cfilter *cf;
+ CURLcode result = CURLE_OK;
+
+ DEBUGASSERT(data);
+ result = cf_hc_create(&cf, data, remotehost, try_h3, try_h21);
+ if(result)
+ goto out;
+ Curl_conn_cf_add(data, conn, sockindex, cf);
+out:
+ return result;
+}
+
+CURLcode Curl_cf_https_setup(struct Curl_easy *data,
+ struct connectdata *conn,
+ int sockindex,
+ const struct Curl_dns_entry *remotehost)
+{
+ bool try_h3 = FALSE, try_h21 = TRUE; /* defaults, for now */
+ CURLcode result = CURLE_OK;
+
+ (void)sockindex;
+ (void)remotehost;
+
+ if(!conn->bits.tls_enable_alpn)
+ goto out;
+
+ if(data->state.httpwant == CURL_HTTP_VERSION_3ONLY) {
+ result = Curl_conn_may_http3(data, conn);
+ if(result) /* can't do it */
+ goto out;
+ try_h3 = TRUE;
+ try_h21 = FALSE;
+ }
+ else if(data->state.httpwant >= CURL_HTTP_VERSION_3) {
+ /* We assume that silently not even trying H3 is ok here */
+ /* TODO: should we fail instead? */
+ try_h3 = (Curl_conn_may_http3(data, conn) == CURLE_OK);
+ try_h21 = TRUE;
+ }
+
+ result = cf_http_connect_add(data, conn, sockindex, remotehost,
+ try_h3, try_h21);
+out:
+ return result;
+}
+
+#endif /* !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER) */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/cf-https-connect.h b/iotdb-client/odbc/deps/curl-src/lib/cf-https-connect.h
new file mode 100644
index 0000000000000..6a39527317c1a
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/cf-https-connect.h
@@ -0,0 +1,58 @@
+#ifndef HEADER_CURL_CF_HTTP_H
+#define HEADER_CURL_CF_HTTP_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER)
+
+struct Curl_cfilter;
+struct Curl_easy;
+struct connectdata;
+struct Curl_cftype;
+struct Curl_dns_entry;
+
+extern struct Curl_cftype Curl_cft_http_connect;
+
+CURLcode Curl_cf_http_connect_add(struct Curl_easy *data,
+ struct connectdata *conn,
+ int sockindex,
+ const struct Curl_dns_entry *remotehost,
+ bool try_h3, bool try_h21);
+
+CURLcode
+Curl_cf_http_connect_insert_after(struct Curl_cfilter *cf_at,
+ struct Curl_easy *data,
+ const struct Curl_dns_entry *remotehost,
+ bool try_h3, bool try_h21);
+
+
+CURLcode Curl_cf_https_setup(struct Curl_easy *data,
+ struct connectdata *conn,
+ int sockindex,
+ const struct Curl_dns_entry *remotehost);
+
+
+#endif /* !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER) */
+#endif /* HEADER_CURL_CF_HTTP_H */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/cf-socket.c b/iotdb-client/odbc/deps/curl-src/lib/cf-socket.c
new file mode 100644
index 0000000000000..ce3f9e9437c32
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/cf-socket.c
@@ -0,0 +1,2011 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include /* may need it */
+#endif
+#ifdef HAVE_SYS_UN_H
+#include /* for sockaddr_un */
+#endif
+#ifdef HAVE_LINUX_TCP_H
+#include
+#elif defined(HAVE_NETINET_TCP_H)
+#include
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include
+#endif
+#ifdef HAVE_NETDB_H
+#include
+#endif
+#ifdef HAVE_FCNTL_H
+#include
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include
+#endif
+
+#ifdef __VMS
+#include
+#include
+#endif
+
+#include "urldata.h"
+#include "bufq.h"
+#include "sendf.h"
+#include "if2ip.h"
+#include "strerror.h"
+#include "cfilters.h"
+#include "cf-socket.h"
+#include "connect.h"
+#include "select.h"
+#include "url.h" /* for Curl_safefree() */
+#include "multiif.h"
+#include "sockaddr.h" /* required for Curl_sockaddr_storage */
+#include "inet_ntop.h"
+#include "inet_pton.h"
+#include "progress.h"
+#include "warnless.h"
+#include "conncache.h"
+#include "multihandle.h"
+#include "rand.h"
+#include "share.h"
+#include "version_win32.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+
+#if defined(ENABLE_IPV6) && defined(IPV6_V6ONLY) && defined(WIN32)
+/* It makes support for IPv4-mapped IPv6 addresses.
+ * Linux kernel, NetBSD, FreeBSD and Darwin: default is off;
+ * Windows Vista and later: default is on;
+ * DragonFly BSD: acts like off, and dummy setting;
+ * OpenBSD and earlier Windows: unsupported.
+ * Linux: controlled by /proc/sys/net/ipv6/bindv6only.
+ */
+static void set_ipv6_v6only(curl_socket_t sockfd, int on)
+{
+ (void)setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&on, sizeof(on));
+}
+#else
+#define set_ipv6_v6only(x,y)
+#endif
+
+static void tcpnodelay(struct Curl_easy *data, curl_socket_t sockfd)
+{
+#if defined(TCP_NODELAY)
+ curl_socklen_t onoff = (curl_socklen_t) 1;
+ int level = IPPROTO_TCP;
+#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ char buffer[STRERROR_LEN];
+#else
+ (void) data;
+#endif
+
+ if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff,
+ sizeof(onoff)) < 0)
+ infof(data, "Could not set TCP_NODELAY: %s",
+ Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
+#else
+ (void)data;
+ (void)sockfd;
+#endif
+}
+
+#ifdef SO_NOSIGPIPE
+/* The preferred method on Mac OS X (10.2 and later) to prevent SIGPIPEs when
+ sending data to a dead peer (instead of relying on the 4th argument to send
+ being MSG_NOSIGNAL). Possibly also existing and in use on other BSD
+ systems? */
+static void nosigpipe(struct Curl_easy *data,
+ curl_socket_t sockfd)
+{
+ int onoff = 1;
+ if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
+ sizeof(onoff)) < 0) {
+#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ char buffer[STRERROR_LEN];
+ infof(data, "Could not set SO_NOSIGPIPE: %s",
+ Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
+#endif
+ }
+}
+#else
+#define nosigpipe(x,y) Curl_nop_stmt
+#endif
+
+#if defined(__DragonFly__) || defined(HAVE_WINSOCK2_H)
+/* DragonFlyBSD and Windows use millisecond units */
+#define KEEPALIVE_FACTOR(x) (x *= 1000)
+#else
+#define KEEPALIVE_FACTOR(x)
+#endif
+
+#if defined(HAVE_WINSOCK2_H) && !defined(SIO_KEEPALIVE_VALS)
+#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)
+
+struct tcp_keepalive {
+ u_long onoff;
+ u_long keepalivetime;
+ u_long keepaliveinterval;
+};
+#endif
+
+static void
+tcpkeepalive(struct Curl_easy *data,
+ curl_socket_t sockfd)
+{
+ int optval = data->set.tcp_keepalive?1:0;
+
+ /* only set IDLE and INTVL if setting KEEPALIVE is successful */
+ if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,
+ (void *)&optval, sizeof(optval)) < 0) {
+ infof(data, "Failed to set SO_KEEPALIVE on fd %d", sockfd);
+ }
+ else {
+#if defined(SIO_KEEPALIVE_VALS)
+ struct tcp_keepalive vals;
+ DWORD dummy;
+ vals.onoff = 1;
+ optval = curlx_sltosi(data->set.tcp_keepidle);
+ KEEPALIVE_FACTOR(optval);
+ vals.keepalivetime = optval;
+ optval = curlx_sltosi(data->set.tcp_keepintvl);
+ KEEPALIVE_FACTOR(optval);
+ vals.keepaliveinterval = optval;
+ if(WSAIoctl(sockfd, SIO_KEEPALIVE_VALS, (LPVOID) &vals, sizeof(vals),
+ NULL, 0, &dummy, NULL, NULL) != 0) {
+ infof(data, "Failed to set SIO_KEEPALIVE_VALS on fd %d: %d",
+ (int)sockfd, WSAGetLastError());
+ }
+#else
+#ifdef TCP_KEEPIDLE
+ optval = curlx_sltosi(data->set.tcp_keepidle);
+ KEEPALIVE_FACTOR(optval);
+ if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE,
+ (void *)&optval, sizeof(optval)) < 0) {
+ infof(data, "Failed to set TCP_KEEPIDLE on fd %d", sockfd);
+ }
+#elif defined(TCP_KEEPALIVE)
+ /* Mac OS X style */
+ optval = curlx_sltosi(data->set.tcp_keepidle);
+ KEEPALIVE_FACTOR(optval);
+ if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE,
+ (void *)&optval, sizeof(optval)) < 0) {
+ infof(data, "Failed to set TCP_KEEPALIVE on fd %d", sockfd);
+ }
+#endif
+#ifdef TCP_KEEPINTVL
+ optval = curlx_sltosi(data->set.tcp_keepintvl);
+ KEEPALIVE_FACTOR(optval);
+ if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL,
+ (void *)&optval, sizeof(optval)) < 0) {
+ infof(data, "Failed to set TCP_KEEPINTVL on fd %d", sockfd);
+ }
+#endif
+#endif
+ }
+}
+
+/**
+ * Assign the address `ai` to the Curl_sockaddr_ex `dest` and
+ * set the transport used.
+ */
+void Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
+ const struct Curl_addrinfo *ai,
+ int transport)
+{
+ /*
+ * The Curl_sockaddr_ex structure is basically libcurl's external API
+ * curl_sockaddr structure with enough space available to directly hold
+ * any protocol-specific address structures. The variable declared here
+ * will be used to pass / receive data to/from the fopensocket callback
+ * if this has been set, before that, it is initialized from parameters.
+ */
+ dest->family = ai->ai_family;
+ switch(transport) {
+ case TRNSPRT_TCP:
+ dest->socktype = SOCK_STREAM;
+ dest->protocol = IPPROTO_TCP;
+ break;
+ case TRNSPRT_UNIX:
+ dest->socktype = SOCK_STREAM;
+ dest->protocol = IPPROTO_IP;
+ break;
+ default: /* UDP and QUIC */
+ dest->socktype = SOCK_DGRAM;
+ dest->protocol = IPPROTO_UDP;
+ break;
+ }
+ dest->addrlen = ai->ai_addrlen;
+
+ if(dest->addrlen > sizeof(struct Curl_sockaddr_storage))
+ dest->addrlen = sizeof(struct Curl_sockaddr_storage);
+ memcpy(&dest->sa_addr, ai->ai_addr, dest->addrlen);
+}
+
+static CURLcode socket_open(struct Curl_easy *data,
+ struct Curl_sockaddr_ex *addr,
+ curl_socket_t *sockfd)
+{
+ DEBUGASSERT(data);
+ DEBUGASSERT(data->conn);
+ if(data->set.fopensocket) {
+ /*
+ * If the opensocket callback is set, all the destination address
+ * information is passed to the callback. Depending on this information the
+ * callback may opt to abort the connection, this is indicated returning
+ * CURL_SOCKET_BAD; otherwise it will return a not-connected socket. When
+ * the callback returns a valid socket the destination address information
+ * might have been changed and this 'new' address will actually be used
+ * here to connect.
+ */
+ Curl_set_in_callback(data, true);
+ *sockfd = data->set.fopensocket(data->set.opensocket_client,
+ CURLSOCKTYPE_IPCXN,
+ (struct curl_sockaddr *)addr);
+ Curl_set_in_callback(data, false);
+ }
+ else {
+ /* opensocket callback not set, so simply create the socket now */
+ *sockfd = socket(addr->family, addr->socktype, addr->protocol);
+ }
+
+ if(*sockfd == CURL_SOCKET_BAD)
+ /* no socket, no connection */
+ return CURLE_COULDNT_CONNECT;
+
+#if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
+ if(data->conn->scope_id && (addr->family == AF_INET6)) {
+ struct sockaddr_in6 * const sa6 = (void *)&addr->sa_addr;
+ sa6->sin6_scope_id = data->conn->scope_id;
+ }
+#endif
+ return CURLE_OK;
+}
+
+/*
+ * Create a socket based on info from 'conn' and 'ai'.
+ *
+ * 'addr' should be a pointer to the correct struct to get data back, or NULL.
+ * 'sockfd' must be a pointer to a socket descriptor.
+ *
+ * If the open socket callback is set, used that!
+ *
+ */
+CURLcode Curl_socket_open(struct Curl_easy *data,
+ const struct Curl_addrinfo *ai,
+ struct Curl_sockaddr_ex *addr,
+ int transport,
+ curl_socket_t *sockfd)
+{
+ struct Curl_sockaddr_ex dummy;
+
+ if(!addr)
+ /* if the caller doesn't want info back, use a local temp copy */
+ addr = &dummy;
+
+ Curl_sock_assign_addr(addr, ai, transport);
+ return socket_open(data, addr, sockfd);
+}
+
+static int socket_close(struct Curl_easy *data, struct connectdata *conn,
+ int use_callback, curl_socket_t sock)
+{
+ if(use_callback && conn && conn->fclosesocket) {
+ int rc;
+ Curl_multi_closed(data, sock);
+ Curl_set_in_callback(data, true);
+ rc = conn->fclosesocket(conn->closesocket_client, sock);
+ Curl_set_in_callback(data, false);
+ return rc;
+ }
+
+ if(conn)
+ /* tell the multi-socket code about this */
+ Curl_multi_closed(data, sock);
+
+ sclose(sock);
+
+ return 0;
+}
+
+/*
+ * Close a socket.
+ *
+ * 'conn' can be NULL, beware!
+ */
+int Curl_socket_close(struct Curl_easy *data, struct connectdata *conn,
+ curl_socket_t sock)
+{
+ return socket_close(data, conn, FALSE, sock);
+}
+
+#ifdef USE_WINSOCK
+/* When you run a program that uses the Windows Sockets API, you may
+ experience slow performance when you copy data to a TCP server.
+
+ https://support.microsoft.com/kb/823764
+
+ Work-around: Make the Socket Send Buffer Size Larger Than the Program Send
+ Buffer Size
+
+ The problem described in this knowledge-base is applied only to pre-Vista
+ Windows. Following function trying to detect OS version and skips
+ SO_SNDBUF adjustment for Windows Vista and above.
+*/
+#define DETECT_OS_NONE 0
+#define DETECT_OS_PREVISTA 1
+#define DETECT_OS_VISTA_OR_LATER 2
+
+void Curl_sndbufset(curl_socket_t sockfd)
+{
+ int val = CURL_MAX_WRITE_SIZE + 32;
+ int curval = 0;
+ int curlen = sizeof(curval);
+
+ static int detectOsState = DETECT_OS_NONE;
+
+ if(detectOsState == DETECT_OS_NONE) {
+ if(curlx_verify_windows_version(6, 0, 0, PLATFORM_WINNT,
+ VERSION_GREATER_THAN_EQUAL))
+ detectOsState = DETECT_OS_VISTA_OR_LATER;
+ else
+ detectOsState = DETECT_OS_PREVISTA;
+ }
+
+ if(detectOsState == DETECT_OS_VISTA_OR_LATER)
+ return;
+
+ if(getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&curval, &curlen) == 0)
+ if(curval > val)
+ return;
+
+ setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char *)&val, sizeof(val));
+}
+#endif
+
+#ifndef CURL_DISABLE_BINDLOCAL
+static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn,
+ curl_socket_t sockfd, int af, unsigned int scope)
+{
+ struct Curl_sockaddr_storage sa;
+ struct sockaddr *sock = (struct sockaddr *)&sa; /* bind to this address */
+ curl_socklen_t sizeof_sa = 0; /* size of the data sock points to */
+ struct sockaddr_in *si4 = (struct sockaddr_in *)&sa;
+#ifdef ENABLE_IPV6
+ struct sockaddr_in6 *si6 = (struct sockaddr_in6 *)&sa;
+#endif
+
+ struct Curl_dns_entry *h = NULL;
+ unsigned short port = data->set.localport; /* use this port number, 0 for
+ "random" */
+ /* how many port numbers to try to bind to, increasing one at a time */
+ int portnum = data->set.localportrange;
+ const char *dev = data->set.str[STRING_DEVICE];
+ int error;
+#ifdef IP_BIND_ADDRESS_NO_PORT
+ int on = 1;
+#endif
+#ifndef ENABLE_IPV6
+ (void)scope;
+#endif
+
+ /*************************************************************
+ * Select device to bind socket to
+ *************************************************************/
+ if(!dev && !port)
+ /* no local kind of binding was requested */
+ return CURLE_OK;
+
+ memset(&sa, 0, sizeof(struct Curl_sockaddr_storage));
+
+ if(dev && (strlen(dev)<255) ) {
+ char myhost[256] = "";
+ int done = 0; /* -1 for error, 1 for address found */
+ bool is_interface = FALSE;
+ bool is_host = FALSE;
+ static const char *if_prefix = "if!";
+ static const char *host_prefix = "host!";
+
+ if(strncmp(if_prefix, dev, strlen(if_prefix)) == 0) {
+ dev += strlen(if_prefix);
+ is_interface = TRUE;
+ }
+ else if(strncmp(host_prefix, dev, strlen(host_prefix)) == 0) {
+ dev += strlen(host_prefix);
+ is_host = TRUE;
+ }
+
+ /* interface */
+ if(!is_host) {
+#ifdef SO_BINDTODEVICE
+ /*
+ * This binds the local socket to a particular interface. This will
+ * force even requests to other local interfaces to go out the external
+ * interface. Only bind to the interface when specified as interface,
+ * not just as a hostname or ip address.
+ *
+ * The interface might be a VRF, eg: vrf-blue, which means it cannot be
+ * converted to an IP address and would fail Curl_if2ip. Simply try to
+ * use it straight away.
+ */
+ if(setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
+ dev, (curl_socklen_t)strlen(dev) + 1) == 0) {
+ /* This is often "errno 1, error: Operation not permitted" if you're
+ * not running as root or another suitable privileged user. If it
+ * succeeds it means the parameter was a valid interface and not an IP
+ * address. Return immediately.
+ */
+ infof(data, "socket successfully bound to interface '%s'", dev);
+ return CURLE_OK;
+ }
+#endif
+
+ switch(Curl_if2ip(af,
+#ifdef ENABLE_IPV6
+ scope, conn->scope_id,
+#endif
+ dev, myhost, sizeof(myhost))) {
+ case IF2IP_NOT_FOUND:
+ if(is_interface) {
+ /* Do not fall back to treating it as a host name */
+ failf(data, "Couldn't bind to interface '%s'", dev);
+ return CURLE_INTERFACE_FAILED;
+ }
+ break;
+ case IF2IP_AF_NOT_SUPPORTED:
+ /* Signal the caller to try another address family if available */
+ return CURLE_UNSUPPORTED_PROTOCOL;
+ case IF2IP_FOUND:
+ is_interface = TRUE;
+ /*
+ * We now have the numerical IP address in the 'myhost' buffer
+ */
+ infof(data, "Local Interface %s is ip %s using address family %i",
+ dev, myhost, af);
+ done = 1;
+ break;
+ }
+ }
+ if(!is_interface) {
+ /*
+ * This was not an interface, resolve the name as a host name
+ * or IP number
+ *
+ * Temporarily force name resolution to use only the address type
+ * of the connection. The resolve functions should really be changed
+ * to take a type parameter instead.
+ */
+ unsigned char ipver = conn->ip_version;
+ int rc;
+
+ if(af == AF_INET)
+ conn->ip_version = CURL_IPRESOLVE_V4;
+#ifdef ENABLE_IPV6
+ else if(af == AF_INET6)
+ conn->ip_version = CURL_IPRESOLVE_V6;
+#endif
+
+ rc = Curl_resolv(data, dev, 80, FALSE, &h);
+ if(rc == CURLRESOLV_PENDING)
+ (void)Curl_resolver_wait_resolv(data, &h);
+ conn->ip_version = ipver;
+
+ if(h) {
+ /* convert the resolved address, sizeof myhost >= INET_ADDRSTRLEN */
+ Curl_printable_address(h->addr, myhost, sizeof(myhost));
+ infof(data, "Name '%s' family %i resolved to '%s' family %i",
+ dev, af, myhost, h->addr->ai_family);
+ Curl_resolv_unlock(data, h);
+ if(af != h->addr->ai_family) {
+ /* bad IP version combo, signal the caller to try another address
+ family if available */
+ return CURLE_UNSUPPORTED_PROTOCOL;
+ }
+ done = 1;
+ }
+ else {
+ /*
+ * provided dev was no interface (or interfaces are not supported
+ * e.g. solaris) no ip address and no domain we fail here
+ */
+ done = -1;
+ }
+ }
+
+ if(done > 0) {
+#ifdef ENABLE_IPV6
+ /* IPv6 address */
+ if(af == AF_INET6) {
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+ char *scope_ptr = strchr(myhost, '%');
+ if(scope_ptr)
+ *(scope_ptr++) = '\0';
+#endif
+ if(Curl_inet_pton(AF_INET6, myhost, &si6->sin6_addr) > 0) {
+ si6->sin6_family = AF_INET6;
+ si6->sin6_port = htons(port);
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+ if(scope_ptr) {
+ /* The "myhost" string either comes from Curl_if2ip or from
+ Curl_printable_address. The latter returns only numeric scope
+ IDs and the former returns none at all. So the scope ID, if
+ present, is known to be numeric */
+ unsigned long scope_id = strtoul(scope_ptr, NULL, 10);
+ if(scope_id > UINT_MAX)
+ return CURLE_UNSUPPORTED_PROTOCOL;
+
+ si6->sin6_scope_id = (unsigned int)scope_id;
+ }
+#endif
+ }
+ sizeof_sa = sizeof(struct sockaddr_in6);
+ }
+ else
+#endif
+ /* IPv4 address */
+ if((af == AF_INET) &&
+ (Curl_inet_pton(AF_INET, myhost, &si4->sin_addr) > 0)) {
+ si4->sin_family = AF_INET;
+ si4->sin_port = htons(port);
+ sizeof_sa = sizeof(struct sockaddr_in);
+ }
+ }
+
+ if(done < 1) {
+ /* errorbuf is set false so failf will overwrite any message already in
+ the error buffer, so the user receives this error message instead of a
+ generic resolve error. */
+ data->state.errorbuf = FALSE;
+ failf(data, "Couldn't bind to '%s'", dev);
+ return CURLE_INTERFACE_FAILED;
+ }
+ }
+ else {
+ /* no device was given, prepare sa to match af's needs */
+#ifdef ENABLE_IPV6
+ if(af == AF_INET6) {
+ si6->sin6_family = AF_INET6;
+ si6->sin6_port = htons(port);
+ sizeof_sa = sizeof(struct sockaddr_in6);
+ }
+ else
+#endif
+ if(af == AF_INET) {
+ si4->sin_family = AF_INET;
+ si4->sin_port = htons(port);
+ sizeof_sa = sizeof(struct sockaddr_in);
+ }
+ }
+#ifdef IP_BIND_ADDRESS_NO_PORT
+ (void)setsockopt(sockfd, SOL_IP, IP_BIND_ADDRESS_NO_PORT, &on, sizeof(on));
+#endif
+ for(;;) {
+ if(bind(sockfd, sock, sizeof_sa) >= 0) {
+ /* we succeeded to bind */
+ struct Curl_sockaddr_storage add;
+ curl_socklen_t size = sizeof(add);
+ memset(&add, 0, sizeof(struct Curl_sockaddr_storage));
+ if(getsockname(sockfd, (struct sockaddr *) &add, &size) < 0) {
+ char buffer[STRERROR_LEN];
+ data->state.os_errno = error = SOCKERRNO;
+ failf(data, "getsockname() failed with errno %d: %s",
+ error, Curl_strerror(error, buffer, sizeof(buffer)));
+ return CURLE_INTERFACE_FAILED;
+ }
+ infof(data, "Local port: %hu", port);
+ conn->bits.bound = TRUE;
+ return CURLE_OK;
+ }
+
+ if(--portnum > 0) {
+ port++; /* try next port */
+ if(port == 0)
+ break;
+ infof(data, "Bind to local port %d failed, trying next", port - 1);
+ /* We reuse/clobber the port variable here below */
+ if(sock->sa_family == AF_INET)
+ si4->sin_port = ntohs(port);
+#ifdef ENABLE_IPV6
+ else
+ si6->sin6_port = ntohs(port);
+#endif
+ }
+ else
+ break;
+ }
+ {
+ char buffer[STRERROR_LEN];
+ data->state.os_errno = error = SOCKERRNO;
+ failf(data, "bind failed with errno %d: %s",
+ error, Curl_strerror(error, buffer, sizeof(buffer)));
+ }
+
+ return CURLE_INTERFACE_FAILED;
+}
+#endif
+
+/*
+ * verifyconnect() returns TRUE if the connect really has happened.
+ */
+static bool verifyconnect(curl_socket_t sockfd, int *error)
+{
+ bool rc = TRUE;
+#ifdef SO_ERROR
+ int err = 0;
+ curl_socklen_t errSize = sizeof(err);
+
+#ifdef WIN32
+ /*
+ * In October 2003 we effectively nullified this function on Windows due to
+ * problems with it using all CPU in multi-threaded cases.
+ *
+ * In May 2004, we bring it back to offer more info back on connect failures.
+ * Gisle Vanem could reproduce the former problems with this function, but
+ * could avoid them by adding this SleepEx() call below:
+ *
+ * "I don't have Rational Quantify, but the hint from his post was
+ * ntdll::NtRemoveIoCompletion(). So I'd assume the SleepEx (or maybe
+ * just Sleep(0) would be enough?) would release whatever
+ * mutex/critical-section the ntdll call is waiting on.
+ *
+ * Someone got to verify this on Win-NT 4.0, 2000."
+ */
+
+#ifdef _WIN32_WCE
+ Sleep(0);
+#else
+ SleepEx(0, FALSE);
+#endif
+
+#endif
+
+ if(0 != getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *)&err, &errSize))
+ err = SOCKERRNO;
+#ifdef _WIN32_WCE
+ /* Old WinCE versions don't support SO_ERROR */
+ if(WSAENOPROTOOPT == err) {
+ SET_SOCKERRNO(0);
+ err = 0;
+ }
+#endif
+#if defined(EBADIOCTL) && defined(__minix)
+ /* Minix 3.1.x doesn't support getsockopt on UDP sockets */
+ if(EBADIOCTL == err) {
+ SET_SOCKERRNO(0);
+ err = 0;
+ }
+#endif
+ if((0 == err) || (EISCONN == err))
+ /* we are connected, awesome! */
+ rc = TRUE;
+ else
+ /* This wasn't a successful connect */
+ rc = FALSE;
+ if(error)
+ *error = err;
+#else
+ (void)sockfd;
+ if(error)
+ *error = SOCKERRNO;
+#endif
+ return rc;
+}
+
+/**
+ * Determine the curl code for a socket connect() == -1 with errno.
+ */
+static CURLcode socket_connect_result(struct Curl_easy *data,
+ const char *ipaddress, int error)
+{
+ switch(error) {
+ case EINPROGRESS:
+ case EWOULDBLOCK:
+#if defined(EAGAIN)
+#if (EAGAIN) != (EWOULDBLOCK)
+ /* On some platforms EAGAIN and EWOULDBLOCK are the
+ * same value, and on others they are different, hence
+ * the odd #if
+ */
+ case EAGAIN:
+#endif
+#endif
+ return CURLE_OK;
+
+ default:
+ /* unknown error, fallthrough and try another address! */
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+ (void)ipaddress;
+#else
+ {
+ char buffer[STRERROR_LEN];
+ infof(data, "Immediate connect fail for %s: %s",
+ ipaddress, Curl_strerror(error, buffer, sizeof(buffer)));
+ }
+#endif
+ data->state.os_errno = error;
+ /* connect failed */
+ return CURLE_COULDNT_CONNECT;
+ }
+}
+
+/* We have a recv buffer to enhance reads with len < NW_SMALL_READS.
+ * This happens often on TLS connections where the TLS implementation
+ * tries to read the head of a TLS record, determine the length of the
+ * full record and then make a subsequent read for that.
+ * On large reads, we will not fill the buffer to avoid the double copy. */
+#define NW_RECV_CHUNK_SIZE (64 * 1024)
+#define NW_RECV_CHUNKS 1
+#define NW_SMALL_READS (1024)
+
+struct cf_socket_ctx {
+ int transport;
+ struct Curl_sockaddr_ex addr; /* address to connect to */
+ curl_socket_t sock; /* current attempt socket */
+ struct bufq recvbuf; /* used when `buffer_recv` is set */
+ char r_ip[MAX_IPADR_LEN]; /* remote IP as string */
+ int r_port; /* remote port number */
+ char l_ip[MAX_IPADR_LEN]; /* local IP as string */
+ int l_port; /* local port number */
+ struct curltime started_at; /* when socket was created */
+ struct curltime connected_at; /* when socket connected/got first byte */
+ struct curltime first_byte_at; /* when first byte was recvd */
+ int error; /* errno of last failure or 0 */
+#ifdef DEBUGBUILD
+ int wblock_percent; /* percent of writes doing EAGAIN */
+ int wpartial_percent; /* percent of bytes written in send */
+ int rblock_percent; /* percent of reads doing EAGAIN */
+ size_t recv_max; /* max enforced read size */
+#endif
+ BIT(got_first_byte); /* if first byte was received */
+ BIT(accepted); /* socket was accepted, not connected */
+ BIT(active);
+ BIT(buffer_recv);
+};
+
+static void cf_socket_ctx_init(struct cf_socket_ctx *ctx,
+ const struct Curl_addrinfo *ai,
+ int transport)
+{
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->sock = CURL_SOCKET_BAD;
+ ctx->transport = transport;
+ Curl_sock_assign_addr(&ctx->addr, ai, transport);
+ Curl_bufq_init(&ctx->recvbuf, NW_RECV_CHUNK_SIZE, NW_RECV_CHUNKS);
+#ifdef DEBUGBUILD
+ {
+ char *p = getenv("CURL_DBG_SOCK_WBLOCK");
+ if(p) {
+ long l = strtol(p, NULL, 10);
+ if(l >= 0 && l <= 100)
+ ctx->wblock_percent = (int)l;
+ }
+ p = getenv("CURL_DBG_SOCK_WPARTIAL");
+ if(p) {
+ long l = strtol(p, NULL, 10);
+ if(l >= 0 && l <= 100)
+ ctx->wpartial_percent = (int)l;
+ }
+ p = getenv("CURL_DBG_SOCK_RBLOCK");
+ if(p) {
+ long l = strtol(p, NULL, 10);
+ if(l >= 0 && l <= 100)
+ ctx->rblock_percent = (int)l;
+ }
+ p = getenv("CURL_DBG_SOCK_RMAX");
+ if(p) {
+ long l = strtol(p, NULL, 10);
+ if(l >= 0)
+ ctx->recv_max = (size_t)l;
+ }
+ }
+#endif
+}
+
+struct reader_ctx {
+ struct Curl_cfilter *cf;
+ struct Curl_easy *data;
+};
+
+static ssize_t nw_in_read(void *reader_ctx,
+ unsigned char *buf, size_t len,
+ CURLcode *err)
+{
+ struct reader_ctx *rctx = reader_ctx;
+ struct cf_socket_ctx *ctx = rctx->cf->ctx;
+ ssize_t nread;
+
+ *err = CURLE_OK;
+ nread = sread(ctx->sock, buf, len);
+
+ if(-1 == nread) {
+ int sockerr = SOCKERRNO;
+
+ if(
+#ifdef WSAEWOULDBLOCK
+ /* This is how Windows does it */
+ (WSAEWOULDBLOCK == sockerr)
+#else
+ /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
+ due to its inability to send off data without blocking. We therefore
+ treat both error codes the same here */
+ (EWOULDBLOCK == sockerr) || (EAGAIN == sockerr) || (EINTR == sockerr)
+#endif
+ ) {
+ /* this is just a case of EWOULDBLOCK */
+ *err = CURLE_AGAIN;
+ nread = -1;
+ }
+ else {
+ char buffer[STRERROR_LEN];
+
+ failf(rctx->data, "Recv failure: %s",
+ Curl_strerror(sockerr, buffer, sizeof(buffer)));
+ rctx->data->state.os_errno = sockerr;
+ *err = CURLE_RECV_ERROR;
+ nread = -1;
+ }
+ }
+ CURL_TRC_CF(rctx->data, rctx->cf, "nw_in_read(len=%zu) -> %d, err=%d",
+ len, (int)nread, *err);
+ return nread;
+}
+
+static void cf_socket_close(struct Curl_cfilter *cf, struct Curl_easy *data)
+{
+ struct cf_socket_ctx *ctx = cf->ctx;
+
+ if(ctx && CURL_SOCKET_BAD != ctx->sock) {
+ if(ctx->active) {
+ /* We share our socket at cf->conn->sock[cf->sockindex] when active.
+ * If it is no longer there, someone has stolen (and hopefully
+ * closed it) and we just forget about it.
+ */
+ if(ctx->sock == cf->conn->sock[cf->sockindex]) {
+ CURL_TRC_CF(data, cf, "cf_socket_close(%" CURL_FORMAT_SOCKET_T
+ ", active)", ctx->sock);
+ socket_close(data, cf->conn, !ctx->accepted, ctx->sock);
+ cf->conn->sock[cf->sockindex] = CURL_SOCKET_BAD;
+ }
+ else {
+ CURL_TRC_CF(data, cf, "cf_socket_close(%" CURL_FORMAT_SOCKET_T
+ ") no longer at conn->sock[], discarding", ctx->sock);
+ /* TODO: we do not want this to happen. Need to check which
+ * code is messing with conn->sock[cf->sockindex] */
+ }
+ ctx->sock = CURL_SOCKET_BAD;
+ if(cf->sockindex == FIRSTSOCKET)
+ cf->conn->remote_addr = NULL;
+ }
+ else {
+ /* this is our local socket, we did never publish it */
+ CURL_TRC_CF(data, cf, "cf_socket_close(%" CURL_FORMAT_SOCKET_T
+ ", not active)", ctx->sock);
+ socket_close(data, cf->conn, !ctx->accepted, ctx->sock);
+ ctx->sock = CURL_SOCKET_BAD;
+ }
+ Curl_bufq_reset(&ctx->recvbuf);
+ ctx->active = FALSE;
+ ctx->buffer_recv = FALSE;
+ memset(&ctx->started_at, 0, sizeof(ctx->started_at));
+ memset(&ctx->connected_at, 0, sizeof(ctx->connected_at));
+ }
+
+ cf->connected = FALSE;
+}
+
+static void cf_socket_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
+{
+ struct cf_socket_ctx *ctx = cf->ctx;
+
+ cf_socket_close(cf, data);
+ CURL_TRC_CF(data, cf, "destroy");
+ Curl_bufq_free(&ctx->recvbuf);
+ free(ctx);
+ cf->ctx = NULL;
+}
+
+static CURLcode set_local_ip(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ struct cf_socket_ctx *ctx = cf->ctx;
+
+#ifdef HAVE_GETSOCKNAME
+ if(!(data->conn->handler->protocol & CURLPROTO_TFTP)) {
+ /* TFTP does not connect, so it cannot get the IP like this */
+
+ char buffer[STRERROR_LEN];
+ struct Curl_sockaddr_storage ssloc;
+ curl_socklen_t slen = sizeof(struct Curl_sockaddr_storage);
+
+ memset(&ssloc, 0, sizeof(ssloc));
+ if(getsockname(ctx->sock, (struct sockaddr*) &ssloc, &slen)) {
+ int error = SOCKERRNO;
+ failf(data, "getsockname() failed with errno %d: %s",
+ error, Curl_strerror(error, buffer, sizeof(buffer)));
+ return CURLE_FAILED_INIT;
+ }
+ if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
+ ctx->l_ip, &ctx->l_port)) {
+ failf(data, "ssloc inet_ntop() failed with errno %d: %s",
+ errno, Curl_strerror(errno, buffer, sizeof(buffer)));
+ return CURLE_FAILED_INIT;
+ }
+ }
+#else
+ (void)data;
+ ctx->l_ip[0] = 0;
+ ctx->l_port = -1;
+#endif
+ return CURLE_OK;
+}
+
+static CURLcode set_remote_ip(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ struct cf_socket_ctx *ctx = cf->ctx;
+
+ /* store remote address and port used in this connection attempt */
+ if(!Curl_addr2string(&ctx->addr.sa_addr, ctx->addr.addrlen,
+ ctx->r_ip, &ctx->r_port)) {
+ char buffer[STRERROR_LEN];
+
+ ctx->error = errno;
+ /* malformed address or bug in inet_ntop, try next address */
+ failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
+ errno, Curl_strerror(errno, buffer, sizeof(buffer)));
+ return CURLE_FAILED_INIT;
+ }
+ return CURLE_OK;
+}
+
+static CURLcode cf_socket_open(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ struct cf_socket_ctx *ctx = cf->ctx;
+ int error = 0;
+ bool isconnected = FALSE;
+ CURLcode result = CURLE_COULDNT_CONNECT;
+ bool is_tcp;
+
+ (void)data;
+ DEBUGASSERT(ctx->sock == CURL_SOCKET_BAD);
+ ctx->started_at = Curl_now();
+ result = socket_open(data, &ctx->addr, &ctx->sock);
+ if(result)
+ goto out;
+
+ result = set_remote_ip(cf, data);
+ if(result)
+ goto out;
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+ {
+ const char *ipmsg;
+#ifdef ENABLE_IPV6
+ if(ctx->addr.family == AF_INET6) {
+ set_ipv6_v6only(ctx->sock, 0);
+ ipmsg = " Trying [%s]:%d...";
+ }
+ else
+#endif
+ ipmsg = " Trying %s:%d...";
+ infof(data, ipmsg, ctx->r_ip, ctx->r_port);
+ }
+#endif
+
+#ifdef ENABLE_IPV6
+ is_tcp = (ctx->addr.family == AF_INET
+ || ctx->addr.family == AF_INET6) &&
+ ctx->addr.socktype == SOCK_STREAM;
+#else
+ is_tcp = (ctx->addr.family == AF_INET) &&
+ ctx->addr.socktype == SOCK_STREAM;
+#endif
+ if(is_tcp && data->set.tcp_nodelay)
+ tcpnodelay(data, ctx->sock);
+
+ nosigpipe(data, ctx->sock);
+
+ Curl_sndbufset(ctx->sock);
+
+ if(is_tcp && data->set.tcp_keepalive)
+ tcpkeepalive(data, ctx->sock);
+
+ if(data->set.fsockopt) {
+ /* activate callback for setting socket options */
+ Curl_set_in_callback(data, true);
+ error = data->set.fsockopt(data->set.sockopt_client,
+ ctx->sock,
+ CURLSOCKTYPE_IPCXN);
+ Curl_set_in_callback(data, false);
+
+ if(error == CURL_SOCKOPT_ALREADY_CONNECTED)
+ isconnected = TRUE;
+ else if(error) {
+ result = CURLE_ABORTED_BY_CALLBACK;
+ goto out;
+ }
+ }
+
+#ifndef CURL_DISABLE_BINDLOCAL
+ /* possibly bind the local end to an IP, interface or port */
+ if(ctx->addr.family == AF_INET
+#ifdef ENABLE_IPV6
+ || ctx->addr.family == AF_INET6
+#endif
+ ) {
+ result = bindlocal(data, cf->conn, ctx->sock, ctx->addr.family,
+ Curl_ipv6_scope(&ctx->addr.sa_addr));
+ if(result) {
+ if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+ /* The address family is not supported on this interface.
+ We can continue trying addresses */
+ result = CURLE_COULDNT_CONNECT;
+ }
+ goto out;
+ }
+ }
+#endif
+
+ /* set socket non-blocking */
+ (void)curlx_nonblock(ctx->sock, TRUE);
+
+out:
+ if(result) {
+ if(ctx->sock != CURL_SOCKET_BAD) {
+ socket_close(data, cf->conn, TRUE, ctx->sock);
+ ctx->sock = CURL_SOCKET_BAD;
+ }
+ }
+ else if(isconnected) {
+ set_local_ip(cf, data);
+ ctx->connected_at = Curl_now();
+ cf->connected = TRUE;
+ }
+ CURL_TRC_CF(data, cf, "cf_socket_open() -> %d, fd=%" CURL_FORMAT_SOCKET_T,
+ result, ctx->sock);
+ return result;
+}
+
+static int do_connect(struct Curl_cfilter *cf, struct Curl_easy *data,
+ bool is_tcp_fastopen)
+{
+ struct cf_socket_ctx *ctx = cf->ctx;
+#ifdef TCP_FASTOPEN_CONNECT
+ int optval = 1;
+#endif
+ int rc = -1;
+
+ (void)data;
+ if(is_tcp_fastopen) {
+#if defined(CONNECT_DATA_IDEMPOTENT) /* Darwin */
+# if defined(HAVE_BUILTIN_AVAILABLE)
+ /* while connectx function is available since macOS 10.11 / iOS 9,
+ it did not have the interface declared correctly until
+ Xcode 9 / macOS SDK 10.13 */
+ if(__builtin_available(macOS 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *)) {
+ sa_endpoints_t endpoints;
+ endpoints.sae_srcif = 0;
+ endpoints.sae_srcaddr = NULL;
+ endpoints.sae_srcaddrlen = 0;
+ endpoints.sae_dstaddr = &ctx->addr.sa_addr;
+ endpoints.sae_dstaddrlen = ctx->addr.addrlen;
+
+ rc = connectx(ctx->sock, &endpoints, SAE_ASSOCID_ANY,
+ CONNECT_RESUME_ON_READ_WRITE | CONNECT_DATA_IDEMPOTENT,
+ NULL, 0, NULL, NULL);
+ }
+ else {
+ rc = connect(ctx->sock, &ctx->addr.sa_addr, ctx->addr.addrlen);
+ }
+# else
+ rc = connect(ctx->sock, &ctx->addr.sa_addr, ctx->addr.addrlen);
+# endif /* HAVE_BUILTIN_AVAILABLE */
+#elif defined(TCP_FASTOPEN_CONNECT) /* Linux >= 4.11 */
+ if(setsockopt(ctx->sock, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
+ (void *)&optval, sizeof(optval)) < 0)
+ infof(data, "Failed to enable TCP Fast Open on fd %"
+ CURL_FORMAT_SOCKET_T, ctx->sock);
+
+ rc = connect(ctx->sock, &ctx->addr.sa_addr, ctx->addr.addrlen);
+#elif defined(MSG_FASTOPEN) /* old Linux */
+ if(cf->conn->given->flags & PROTOPT_SSL)
+ rc = connect(ctx->sock, &ctx->addr.sa_addr, ctx->addr.addrlen);
+ else
+ rc = 0; /* Do nothing */
+#endif
+ }
+ else {
+ rc = connect(ctx->sock, &ctx->addr.sa_addr, ctx->addr.addrlen);
+ }
+ return rc;
+}
+
+static CURLcode cf_tcp_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool blocking, bool *done)
+{
+ struct cf_socket_ctx *ctx = cf->ctx;
+ CURLcode result = CURLE_COULDNT_CONNECT;
+ int rc = 0;
+
+ (void)data;
+ if(cf->connected) {
+ *done = TRUE;
+ return CURLE_OK;
+ }
+
+ /* TODO: need to support blocking connect? */
+ if(blocking)
+ return CURLE_UNSUPPORTED_PROTOCOL;
+
+ *done = FALSE; /* a very negative world view is best */
+ if(ctx->sock == CURL_SOCKET_BAD) {
+
+ result = cf_socket_open(cf, data);
+ if(result)
+ goto out;
+
+ if(cf->connected) {
+ *done = TRUE;
+ return CURLE_OK;
+ }
+
+ /* Connect TCP socket */
+ rc = do_connect(cf, data, cf->conn->bits.tcp_fastopen);
+ if(-1 == rc) {
+ result = socket_connect_result(data, ctx->r_ip, SOCKERRNO);
+ goto out;
+ }
+ }
+
+#ifdef mpeix
+ /* Call this function once now, and ignore the results. We do this to
+ "clear" the error state on the socket so that we can later read it
+ reliably. This is reported necessary on the MPE/iX operating
+ system. */
+ (void)verifyconnect(ctx->sock, NULL);
+#endif
+ /* check socket for connect */
+ rc = SOCKET_WRITABLE(ctx->sock, 0);
+
+ if(rc == 0) { /* no connection yet */
+ CURL_TRC_CF(data, cf, "not connected yet");
+ return CURLE_OK;
+ }
+ else if(rc == CURL_CSELECT_OUT || cf->conn->bits.tcp_fastopen) {
+ if(verifyconnect(ctx->sock, &ctx->error)) {
+ /* we are connected with TCP, awesome! */
+ ctx->connected_at = Curl_now();
+ set_local_ip(cf, data);
+ *done = TRUE;
+ cf->connected = TRUE;
+ CURL_TRC_CF(data, cf, "connected");
+ return CURLE_OK;
+ }
+ }
+ else if(rc & CURL_CSELECT_ERR) {
+ (void)verifyconnect(ctx->sock, &ctx->error);
+ result = CURLE_COULDNT_CONNECT;
+ }
+
+out:
+ if(result) {
+ if(ctx->error) {
+ data->state.os_errno = ctx->error;
+ SET_SOCKERRNO(ctx->error);
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+ {
+ char buffer[STRERROR_LEN];
+ infof(data, "connect to %s port %u failed: %s",
+ ctx->r_ip, ctx->r_port,
+ Curl_strerror(ctx->error, buffer, sizeof(buffer)));
+ }
+#endif
+ }
+ if(ctx->sock != CURL_SOCKET_BAD) {
+ socket_close(data, cf->conn, TRUE, ctx->sock);
+ ctx->sock = CURL_SOCKET_BAD;
+ }
+ *done = FALSE;
+ }
+ return result;
+}
+
+static void cf_socket_get_host(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ const char **phost,
+ const char **pdisplay_host,
+ int *pport)
+{
+ (void)data;
+ *phost = cf->conn->host.name;
+ *pdisplay_host = cf->conn->host.dispname;
+ *pport = cf->conn->port;
+}
+
+static int cf_socket_get_select_socks(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ curl_socket_t *socks)
+{
+ struct cf_socket_ctx *ctx = cf->ctx;
+ int rc = GETSOCK_BLANK;
+
+ (void)data;
+ if(!cf->connected && ctx->sock != CURL_SOCKET_BAD) {
+ socks[0] = ctx->sock;
+ rc |= GETSOCK_WRITESOCK(0);
+ }
+
+ return rc;
+}
+
+static bool cf_socket_data_pending(struct Curl_cfilter *cf,
+ const struct Curl_easy *data)
+{
+ struct cf_socket_ctx *ctx = cf->ctx;
+ int readable;
+
+ (void)data;
+ if(!Curl_bufq_is_empty(&ctx->recvbuf))
+ return TRUE;
+
+ readable = SOCKET_READABLE(ctx->sock, 0);
+ return (readable > 0 && (readable & CURL_CSELECT_IN));
+}
+
+static ssize_t cf_socket_send(struct Curl_cfilter *cf, struct Curl_easy *data,
+ const void *buf, size_t len, CURLcode *err)
+{
+ struct cf_socket_ctx *ctx = cf->ctx;
+ curl_socket_t fdsave;
+ ssize_t nwritten;
+ size_t orig_len = len;
+
+ *err = CURLE_OK;
+ fdsave = cf->conn->sock[cf->sockindex];
+ cf->conn->sock[cf->sockindex] = ctx->sock;
+
+#ifdef DEBUGBUILD
+ /* simulate network blocking/partial writes */
+ if(ctx->wblock_percent > 0) {
+ unsigned char c;
+ Curl_rand(data, &c, 1);
+ if(c >= ((100-ctx->wblock_percent)*256/100)) {
+ CURL_TRC_CF(data, cf, "send(len=%zu) SIMULATE EWOULDBLOCK", orig_len);
+ *err = CURLE_AGAIN;
+ nwritten = -1;
+ cf->conn->sock[cf->sockindex] = fdsave;
+ return nwritten;
+ }
+ }
+ if(cf->cft != &Curl_cft_udp && ctx->wpartial_percent > 0 && len > 8) {
+ len = len * ctx->wpartial_percent / 100;
+ if(!len)
+ len = 1;
+ CURL_TRC_CF(data, cf, "send(len=%zu) SIMULATE partial write of %zu bytes",
+ orig_len, len);
+ }
+#endif
+
+#if defined(MSG_FASTOPEN) && !defined(TCP_FASTOPEN_CONNECT) /* Linux */
+ if(cf->conn->bits.tcp_fastopen) {
+ nwritten = sendto(ctx->sock, buf, len, MSG_FASTOPEN,
+ &cf->conn->remote_addr->sa_addr,
+ cf->conn->remote_addr->addrlen);
+ cf->conn->bits.tcp_fastopen = FALSE;
+ }
+ else
+#endif
+ nwritten = swrite(ctx->sock, buf, len);
+
+ if(-1 == nwritten) {
+ int sockerr = SOCKERRNO;
+
+ if(
+#ifdef WSAEWOULDBLOCK
+ /* This is how Windows does it */
+ (WSAEWOULDBLOCK == sockerr)
+#else
+ /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
+ due to its inability to send off data without blocking. We therefore
+ treat both error codes the same here */
+ (EWOULDBLOCK == sockerr) || (EAGAIN == sockerr) || (EINTR == sockerr) ||
+ (EINPROGRESS == sockerr)
+#endif
+ ) {
+ /* this is just a case of EWOULDBLOCK */
+ *err = CURLE_AGAIN;
+ }
+ else {
+ char buffer[STRERROR_LEN];
+ failf(data, "Send failure: %s",
+ Curl_strerror(sockerr, buffer, sizeof(buffer)));
+ data->state.os_errno = sockerr;
+ *err = CURLE_SEND_ERROR;
+ }
+ }
+
+ CURL_TRC_CF(data, cf, "send(len=%zu) -> %d, err=%d",
+ orig_len, (int)nwritten, *err);
+ cf->conn->sock[cf->sockindex] = fdsave;
+ return nwritten;
+}
+
+static ssize_t cf_socket_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
+ char *buf, size_t len, CURLcode *err)
+{
+ struct cf_socket_ctx *ctx = cf->ctx;
+ curl_socket_t fdsave;
+ ssize_t nread;
+
+ *err = CURLE_OK;
+
+ fdsave = cf->conn->sock[cf->sockindex];
+ cf->conn->sock[cf->sockindex] = ctx->sock;
+
+#ifdef DEBUGBUILD
+ /* simulate network blocking/partial reads */
+ if(cf->cft != &Curl_cft_udp && ctx->rblock_percent > 0) {
+ unsigned char c;
+ Curl_rand(data, &c, 1);
+ if(c >= ((100-ctx->rblock_percent)*256/100)) {
+ CURL_TRC_CF(data, cf, "recv(len=%zu) SIMULATE EWOULDBLOCK", len);
+ *err = CURLE_AGAIN;
+ nread = -1;
+ cf->conn->sock[cf->sockindex] = fdsave;
+ return nread;
+ }
+ }
+ if(cf->cft != &Curl_cft_udp && ctx->recv_max && ctx->recv_max < len) {
+ size_t orig_len = len;
+ len = ctx->recv_max;
+ CURL_TRC_CF(data, cf, "recv(len=%zu) SIMULATE max read of %zu bytes",
+ orig_len, len);
+ }
+#endif
+
+ if(ctx->buffer_recv && !Curl_bufq_is_empty(&ctx->recvbuf)) {
+ CURL_TRC_CF(data, cf, "recv from buffer");
+ nread = Curl_bufq_read(&ctx->recvbuf, (unsigned char *)buf, len, err);
+ }
+ else {
+ struct reader_ctx rctx;
+
+ rctx.cf = cf;
+ rctx.data = data;
+
+ /* "small" reads may trigger filling our buffer, "large" reads
+ * are probably not worth the additional copy */
+ if(ctx->buffer_recv && len < NW_SMALL_READS) {
+ ssize_t nwritten;
+ nwritten = Curl_bufq_slurp(&ctx->recvbuf, nw_in_read, &rctx, err);
+ if(nwritten < 0 && !Curl_bufq_is_empty(&ctx->recvbuf)) {
+ /* we have a partial read with an error. need to deliver
+ * what we got, return the error later. */
+ CURL_TRC_CF(data, cf, "partial read: empty buffer first");
+ nread = Curl_bufq_read(&ctx->recvbuf, (unsigned char *)buf, len, err);
+ }
+ else if(nwritten < 0) {
+ nread = -1;
+ goto out;
+ }
+ else if(nwritten == 0) {
+ /* eof */
+ *err = CURLE_OK;
+ nread = 0;
+ }
+ else {
+ CURL_TRC_CF(data, cf, "buffered %zd additional bytes", nwritten);
+ nread = Curl_bufq_read(&ctx->recvbuf, (unsigned char *)buf, len, err);
+ }
+ }
+ else {
+ nread = nw_in_read(&rctx, (unsigned char *)buf, len, err);
+ }
+ }
+
+out:
+ CURL_TRC_CF(data, cf, "recv(len=%zu) -> %d, err=%d", len, (int)nread,
+ *err);
+ if(nread > 0 && !ctx->got_first_byte) {
+ ctx->first_byte_at = Curl_now();
+ ctx->got_first_byte = TRUE;
+ }
+ cf->conn->sock[cf->sockindex] = fdsave;
+ return nread;
+}
+
+static void conn_set_primary_ip(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+#ifdef HAVE_GETPEERNAME
+ struct cf_socket_ctx *ctx = cf->ctx;
+ if(!(data->conn->handler->protocol & CURLPROTO_TFTP)) {
+ /* TFTP does not connect the endpoint: getpeername() failed with errno
+ 107: Transport endpoint is not connected */
+
+ char buffer[STRERROR_LEN];
+ struct Curl_sockaddr_storage ssrem;
+ curl_socklen_t plen;
+ int port;
+
+ plen = sizeof(ssrem);
+ memset(&ssrem, 0, plen);
+ if(getpeername(ctx->sock, (struct sockaddr*) &ssrem, &plen)) {
+ int error = SOCKERRNO;
+ failf(data, "getpeername() failed with errno %d: %s",
+ error, Curl_strerror(error, buffer, sizeof(buffer)));
+ return;
+ }
+ if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
+ cf->conn->primary_ip, &port)) {
+ failf(data, "ssrem inet_ntop() failed with errno %d: %s",
+ errno, Curl_strerror(errno, buffer, sizeof(buffer)));
+ return;
+ }
+ }
+#else
+ cf->conn->primary_ip[0] = 0;
+ (void)data;
+#endif
+}
+
+static void cf_socket_active(struct Curl_cfilter *cf, struct Curl_easy *data)
+{
+ struct cf_socket_ctx *ctx = cf->ctx;
+
+ /* use this socket from now on */
+ cf->conn->sock[cf->sockindex] = ctx->sock;
+ /* the first socket info gets set at conn and data */
+ if(cf->sockindex == FIRSTSOCKET) {
+ cf->conn->remote_addr = &ctx->addr;
+ #ifdef ENABLE_IPV6
+ cf->conn->bits.ipv6 = (ctx->addr.family == AF_INET6)? TRUE : FALSE;
+ #endif
+ conn_set_primary_ip(cf, data);
+ set_local_ip(cf, data);
+ Curl_persistconninfo(data, cf->conn, ctx->l_ip, ctx->l_port);
+ /* buffering is currently disabled by default because we have stalls
+ * in parallel transfers where not all buffered data is consumed and no
+ * socket events happen.
+ */
+ ctx->buffer_recv = FALSE;
+ }
+ ctx->active = TRUE;
+}
+
+static CURLcode cf_socket_cntrl(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ int event, int arg1, void *arg2)
+{
+ struct cf_socket_ctx *ctx = cf->ctx;
+
+ (void)arg1;
+ (void)arg2;
+ switch(event) {
+ case CF_CTRL_CONN_INFO_UPDATE:
+ cf_socket_active(cf, data);
+ break;
+ case CF_CTRL_DATA_SETUP:
+ Curl_persistconninfo(data, cf->conn, ctx->l_ip, ctx->l_port);
+ break;
+ }
+ return CURLE_OK;
+}
+
+static bool cf_socket_conn_is_alive(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *input_pending)
+{
+ struct cf_socket_ctx *ctx = cf->ctx;
+ struct pollfd pfd[1];
+ int r;
+
+ *input_pending = FALSE;
+ (void)data;
+ if(!ctx || ctx->sock == CURL_SOCKET_BAD)
+ return FALSE;
+
+ /* Check with 0 timeout if there are any events pending on the socket */
+ pfd[0].fd = ctx->sock;
+ pfd[0].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
+ pfd[0].revents = 0;
+
+ r = Curl_poll(pfd, 1, 0);
+ if(r < 0) {
+ CURL_TRC_CF(data, cf, "is_alive: poll error, assume dead");
+ return FALSE;
+ }
+ else if(r == 0) {
+ CURL_TRC_CF(data, cf, "is_alive: poll timeout, assume alive");
+ return TRUE;
+ }
+ else if(pfd[0].revents & (POLLERR|POLLHUP|POLLPRI|POLLNVAL)) {
+ CURL_TRC_CF(data, cf, "is_alive: err/hup/etc events, assume dead");
+ return FALSE;
+ }
+
+ CURL_TRC_CF(data, cf, "is_alive: valid events, looks alive");
+ *input_pending = TRUE;
+ return TRUE;
+}
+
+static CURLcode cf_socket_query(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ int query, int *pres1, void *pres2)
+{
+ struct cf_socket_ctx *ctx = cf->ctx;
+
+ switch(query) {
+ case CF_QUERY_SOCKET:
+ DEBUGASSERT(pres2);
+ *((curl_socket_t *)pres2) = ctx->sock;
+ return CURLE_OK;
+ case CF_QUERY_CONNECT_REPLY_MS:
+ if(ctx->got_first_byte) {
+ timediff_t ms = Curl_timediff(ctx->first_byte_at, ctx->started_at);
+ *pres1 = (ms < INT_MAX)? (int)ms : INT_MAX;
+ }
+ else
+ *pres1 = -1;
+ return CURLE_OK;
+ case CF_QUERY_TIMER_CONNECT: {
+ struct curltime *when = pres2;
+ switch(ctx->transport) {
+ case TRNSPRT_UDP:
+ case TRNSPRT_QUIC:
+ /* Since UDP connected sockets work different from TCP, we use the
+ * time of the first byte from the peer as the "connect" time. */
+ if(ctx->got_first_byte) {
+ *when = ctx->first_byte_at;
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ *when = ctx->connected_at;
+ break;
+ }
+ return CURLE_OK;
+ }
+ default:
+ break;
+ }
+ return cf->next?
+ cf->next->cft->query(cf->next, data, query, pres1, pres2) :
+ CURLE_UNKNOWN_OPTION;
+}
+
+struct Curl_cftype Curl_cft_tcp = {
+ "TCP",
+ CF_TYPE_IP_CONNECT,
+ CURL_LOG_LVL_NONE,
+ cf_socket_destroy,
+ cf_tcp_connect,
+ cf_socket_close,
+ cf_socket_get_host,
+ cf_socket_get_select_socks,
+ cf_socket_data_pending,
+ cf_socket_send,
+ cf_socket_recv,
+ cf_socket_cntrl,
+ cf_socket_conn_is_alive,
+ Curl_cf_def_conn_keep_alive,
+ cf_socket_query,
+};
+
+CURLcode Curl_cf_tcp_create(struct Curl_cfilter **pcf,
+ struct Curl_easy *data,
+ struct connectdata *conn,
+ const struct Curl_addrinfo *ai,
+ int transport)
+{
+ struct cf_socket_ctx *ctx = NULL;
+ struct Curl_cfilter *cf = NULL;
+ CURLcode result;
+
+ (void)data;
+ (void)conn;
+ DEBUGASSERT(transport == TRNSPRT_TCP);
+ ctx = calloc(sizeof(*ctx), 1);
+ if(!ctx) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+ cf_socket_ctx_init(ctx, ai, transport);
+
+ result = Curl_cf_create(&cf, &Curl_cft_tcp, ctx);
+
+out:
+ *pcf = (!result)? cf : NULL;
+ if(result) {
+ Curl_safefree(cf);
+ Curl_safefree(ctx);
+ }
+
+ return result;
+}
+
+static CURLcode cf_udp_setup_quic(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ struct cf_socket_ctx *ctx = cf->ctx;
+ int rc;
+
+ /* QUIC needs a connected socket, nonblocking */
+ DEBUGASSERT(ctx->sock != CURL_SOCKET_BAD);
+
+ rc = connect(ctx->sock, &ctx->addr.sa_addr, ctx->addr.addrlen);
+ if(-1 == rc) {
+ return socket_connect_result(data, ctx->r_ip, SOCKERRNO);
+ }
+ set_local_ip(cf, data);
+ CURL_TRC_CF(data, cf, "%s socket %" CURL_FORMAT_SOCKET_T
+ " connected: [%s:%d] -> [%s:%d]",
+ (ctx->transport == TRNSPRT_QUIC)? "QUIC" : "UDP",
+ ctx->sock, ctx->l_ip, ctx->l_port, ctx->r_ip, ctx->r_port);
+
+ (void)curlx_nonblock(ctx->sock, TRUE);
+ switch(ctx->addr.family) {
+#if defined(__linux__) && defined(IP_MTU_DISCOVER)
+ case AF_INET: {
+ int val = IP_PMTUDISC_DO;
+ (void)setsockopt(ctx->sock, IPPROTO_IP, IP_MTU_DISCOVER, &val,
+ sizeof(val));
+ break;
+ }
+#endif
+#if defined(__linux__) && defined(IPV6_MTU_DISCOVER)
+ case AF_INET6: {
+ int val = IPV6_PMTUDISC_DO;
+ (void)setsockopt(ctx->sock, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &val,
+ sizeof(val));
+ break;
+ }
+#endif
+ }
+ return CURLE_OK;
+}
+
+static CURLcode cf_udp_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool blocking, bool *done)
+{
+ struct cf_socket_ctx *ctx = cf->ctx;
+ CURLcode result = CURLE_COULDNT_CONNECT;
+
+ (void)blocking;
+ if(cf->connected) {
+ *done = TRUE;
+ return CURLE_OK;
+ }
+ *done = FALSE;
+ if(ctx->sock == CURL_SOCKET_BAD) {
+ result = cf_socket_open(cf, data);
+ if(result) {
+ CURL_TRC_CF(data, cf, "cf_udp_connect(), open failed -> %d", result);
+ goto out;
+ }
+
+ if(ctx->transport == TRNSPRT_QUIC) {
+ result = cf_udp_setup_quic(cf, data);
+ if(result)
+ goto out;
+ CURL_TRC_CF(data, cf, "cf_udp_connect(), opened socket=%"
+ CURL_FORMAT_SOCKET_T " (%s:%d)",
+ ctx->sock, ctx->l_ip, ctx->l_port);
+ }
+ else {
+ CURL_TRC_CF(data, cf, "cf_udp_connect(), opened socket=%"
+ CURL_FORMAT_SOCKET_T " (unconnected)", ctx->sock);
+ }
+ *done = TRUE;
+ cf->connected = TRUE;
+ }
+out:
+ return result;
+}
+
+struct Curl_cftype Curl_cft_udp = {
+ "UDP",
+ CF_TYPE_IP_CONNECT,
+ CURL_LOG_LVL_NONE,
+ cf_socket_destroy,
+ cf_udp_connect,
+ cf_socket_close,
+ cf_socket_get_host,
+ cf_socket_get_select_socks,
+ cf_socket_data_pending,
+ cf_socket_send,
+ cf_socket_recv,
+ cf_socket_cntrl,
+ cf_socket_conn_is_alive,
+ Curl_cf_def_conn_keep_alive,
+ cf_socket_query,
+};
+
+CURLcode Curl_cf_udp_create(struct Curl_cfilter **pcf,
+ struct Curl_easy *data,
+ struct connectdata *conn,
+ const struct Curl_addrinfo *ai,
+ int transport)
+{
+ struct cf_socket_ctx *ctx = NULL;
+ struct Curl_cfilter *cf = NULL;
+ CURLcode result;
+
+ (void)data;
+ (void)conn;
+ DEBUGASSERT(transport == TRNSPRT_UDP || transport == TRNSPRT_QUIC);
+ ctx = calloc(sizeof(*ctx), 1);
+ if(!ctx) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+ cf_socket_ctx_init(ctx, ai, transport);
+
+ result = Curl_cf_create(&cf, &Curl_cft_udp, ctx);
+
+out:
+ *pcf = (!result)? cf : NULL;
+ if(result) {
+ Curl_safefree(cf);
+ Curl_safefree(ctx);
+ }
+
+ return result;
+}
+
+/* this is the TCP filter which can also handle this case */
+struct Curl_cftype Curl_cft_unix = {
+ "UNIX",
+ CF_TYPE_IP_CONNECT,
+ CURL_LOG_LVL_NONE,
+ cf_socket_destroy,
+ cf_tcp_connect,
+ cf_socket_close,
+ cf_socket_get_host,
+ cf_socket_get_select_socks,
+ cf_socket_data_pending,
+ cf_socket_send,
+ cf_socket_recv,
+ cf_socket_cntrl,
+ cf_socket_conn_is_alive,
+ Curl_cf_def_conn_keep_alive,
+ cf_socket_query,
+};
+
+CURLcode Curl_cf_unix_create(struct Curl_cfilter **pcf,
+ struct Curl_easy *data,
+ struct connectdata *conn,
+ const struct Curl_addrinfo *ai,
+ int transport)
+{
+ struct cf_socket_ctx *ctx = NULL;
+ struct Curl_cfilter *cf = NULL;
+ CURLcode result;
+
+ (void)data;
+ (void)conn;
+ DEBUGASSERT(transport == TRNSPRT_UNIX);
+ ctx = calloc(sizeof(*ctx), 1);
+ if(!ctx) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+ cf_socket_ctx_init(ctx, ai, transport);
+
+ result = Curl_cf_create(&cf, &Curl_cft_unix, ctx);
+
+out:
+ *pcf = (!result)? cf : NULL;
+ if(result) {
+ Curl_safefree(cf);
+ Curl_safefree(ctx);
+ }
+
+ return result;
+}
+
+static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool blocking, bool *done)
+{
+ /* we start accepted, if we ever close, we cannot go on */
+ (void)data;
+ (void)blocking;
+ if(cf->connected) {
+ *done = TRUE;
+ return CURLE_OK;
+ }
+ return CURLE_FAILED_INIT;
+}
+
+struct Curl_cftype Curl_cft_tcp_accept = {
+ "TCP-ACCEPT",
+ CF_TYPE_IP_CONNECT,
+ CURL_LOG_LVL_NONE,
+ cf_socket_destroy,
+ cf_tcp_accept_connect,
+ cf_socket_close,
+ cf_socket_get_host, /* TODO: not accurate */
+ cf_socket_get_select_socks,
+ cf_socket_data_pending,
+ cf_socket_send,
+ cf_socket_recv,
+ cf_socket_cntrl,
+ cf_socket_conn_is_alive,
+ Curl_cf_def_conn_keep_alive,
+ cf_socket_query,
+};
+
+CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data,
+ struct connectdata *conn,
+ int sockindex, curl_socket_t *s)
+{
+ CURLcode result;
+ struct Curl_cfilter *cf = NULL;
+ struct cf_socket_ctx *ctx = NULL;
+
+ /* replace any existing */
+ Curl_conn_cf_discard_all(data, conn, sockindex);
+ DEBUGASSERT(conn->sock[sockindex] == CURL_SOCKET_BAD);
+
+ ctx = calloc(sizeof(*ctx), 1);
+ if(!ctx) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+ ctx->transport = conn->transport;
+ ctx->sock = *s;
+ ctx->accepted = FALSE;
+ result = Curl_cf_create(&cf, &Curl_cft_tcp_accept, ctx);
+ if(result)
+ goto out;
+ Curl_conn_cf_add(data, conn, sockindex, cf);
+
+ conn->sock[sockindex] = ctx->sock;
+ set_local_ip(cf, data);
+ ctx->active = TRUE;
+ ctx->connected_at = Curl_now();
+ cf->connected = TRUE;
+ CURL_TRC_CF(data, cf, "Curl_conn_tcp_listen_set(%"
+ CURL_FORMAT_SOCKET_T ")", ctx->sock);
+
+out:
+ if(result) {
+ Curl_safefree(cf);
+ Curl_safefree(ctx);
+ }
+ return result;
+}
+
+static void set_accepted_remote_ip(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ struct cf_socket_ctx *ctx = cf->ctx;
+#ifdef HAVE_GETPEERNAME
+ char buffer[STRERROR_LEN];
+ struct Curl_sockaddr_storage ssrem;
+ curl_socklen_t plen;
+
+ ctx->r_ip[0] = 0;
+ ctx->r_port = 0;
+ plen = sizeof(ssrem);
+ memset(&ssrem, 0, plen);
+ if(getpeername(ctx->sock, (struct sockaddr*) &ssrem, &plen)) {
+ int error = SOCKERRNO;
+ failf(data, "getpeername() failed with errno %d: %s",
+ error, Curl_strerror(error, buffer, sizeof(buffer)));
+ return;
+ }
+ if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
+ ctx->r_ip, &ctx->r_port)) {
+ failf(data, "ssrem inet_ntop() failed with errno %d: %s",
+ errno, Curl_strerror(errno, buffer, sizeof(buffer)));
+ return;
+ }
+#else
+ ctx->r_ip[0] = 0;
+ ctx->r_port = 0;
+ (void)data;
+#endif
+}
+
+CURLcode Curl_conn_tcp_accepted_set(struct Curl_easy *data,
+ struct connectdata *conn,
+ int sockindex, curl_socket_t *s)
+{
+ struct Curl_cfilter *cf = NULL;
+ struct cf_socket_ctx *ctx = NULL;
+
+ cf = conn->cfilter[sockindex];
+ if(!cf || cf->cft != &Curl_cft_tcp_accept)
+ return CURLE_FAILED_INIT;
+
+ ctx = cf->ctx;
+ /* discard the listen socket */
+ socket_close(data, conn, TRUE, ctx->sock);
+ ctx->sock = *s;
+ conn->sock[sockindex] = ctx->sock;
+ set_accepted_remote_ip(cf, data);
+ set_local_ip(cf, data);
+ ctx->active = TRUE;
+ ctx->accepted = TRUE;
+ ctx->connected_at = Curl_now();
+ cf->connected = TRUE;
+ CURL_TRC_CF(data, cf, "accepted_set(sock=%" CURL_FORMAT_SOCKET_T
+ ", remote=%s port=%d)",
+ ctx->sock, ctx->r_ip, ctx->r_port);
+
+ return CURLE_OK;
+}
+
+/**
+ * Return TRUE iff `cf` is a socket filter.
+ */
+static bool cf_is_socket(struct Curl_cfilter *cf)
+{
+ return cf && (cf->cft == &Curl_cft_tcp ||
+ cf->cft == &Curl_cft_udp ||
+ cf->cft == &Curl_cft_unix ||
+ cf->cft == &Curl_cft_tcp_accept);
+}
+
+CURLcode Curl_cf_socket_peek(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ curl_socket_t *psock,
+ const struct Curl_sockaddr_ex **paddr,
+ const char **pr_ip_str, int *pr_port,
+ const char **pl_ip_str, int *pl_port)
+{
+ if(cf_is_socket(cf) && cf->ctx) {
+ struct cf_socket_ctx *ctx = cf->ctx;
+
+ if(psock)
+ *psock = ctx->sock;
+ if(paddr)
+ *paddr = &ctx->addr;
+ if(pr_ip_str)
+ *pr_ip_str = ctx->r_ip;
+ if(pr_port)
+ *pr_port = ctx->r_port;
+ if(pl_port ||pl_ip_str) {
+ set_local_ip(cf, data);
+ if(pl_ip_str)
+ *pl_ip_str = ctx->l_ip;
+ if(pl_port)
+ *pl_port = ctx->l_port;
+ }
+ return CURLE_OK;
+ }
+ return CURLE_FAILED_INIT;
+}
diff --git a/iotdb-client/odbc/deps/curl-src/lib/cf-socket.h b/iotdb-client/odbc/deps/curl-src/lib/cf-socket.h
new file mode 100644
index 0000000000000..1d40df737fcef
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/cf-socket.h
@@ -0,0 +1,191 @@
+#ifndef HEADER_CURL_CF_SOCKET_H
+#define HEADER_CURL_CF_SOCKET_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#include "nonblock.h" /* for curlx_nonblock(), formerly Curl_nonblock() */
+#include "sockaddr.h"
+
+struct Curl_addrinfo;
+struct Curl_cfilter;
+struct Curl_easy;
+struct connectdata;
+struct Curl_sockaddr_ex;
+
+#ifndef SIZEOF_CURL_SOCKET_T
+/* configure and cmake check and set the define */
+# ifdef _WIN64
+# define SIZEOF_CURL_SOCKET_T 8
+# else
+/* default guess */
+# define SIZEOF_CURL_SOCKET_T 4
+# endif
+#endif
+
+#if SIZEOF_CURL_SOCKET_T < 8
+# define CURL_FORMAT_SOCKET_T "d"
+#else
+# define CURL_FORMAT_SOCKET_T "qd"
+#endif
+
+
+/*
+ * The Curl_sockaddr_ex structure is basically libcurl's external API
+ * curl_sockaddr structure with enough space available to directly hold any
+ * protocol-specific address structures. The variable declared here will be
+ * used to pass / receive data to/from the fopensocket callback if this has
+ * been set, before that, it is initialized from parameters.
+ */
+struct Curl_sockaddr_ex {
+ int family;
+ int socktype;
+ int protocol;
+ unsigned int addrlen;
+ union {
+ struct sockaddr addr;
+ struct Curl_sockaddr_storage buff;
+ } _sa_ex_u;
+};
+#define sa_addr _sa_ex_u.addr
+
+
+/*
+ * Create a socket based on info from 'conn' and 'ai'.
+ *
+ * Fill in 'addr' and 'sockfd' accordingly if OK is returned. If the open
+ * socket callback is set, used that!
+ *
+ */
+CURLcode Curl_socket_open(struct Curl_easy *data,
+ const struct Curl_addrinfo *ai,
+ struct Curl_sockaddr_ex *addr,
+ int transport,
+ curl_socket_t *sockfd);
+
+int Curl_socket_close(struct Curl_easy *data, struct connectdata *conn,
+ curl_socket_t sock);
+
+#ifdef USE_WINSOCK
+/* When you run a program that uses the Windows Sockets API, you may
+ experience slow performance when you copy data to a TCP server.
+
+ https://support.microsoft.com/kb/823764
+
+ Work-around: Make the Socket Send Buffer Size Larger Than the Program Send
+ Buffer Size
+
+*/
+void Curl_sndbufset(curl_socket_t sockfd);
+#else
+#define Curl_sndbufset(y) Curl_nop_stmt
+#endif
+
+/**
+ * Assign the address `ai` to the Curl_sockaddr_ex `dest` and
+ * set the transport used.
+ */
+void Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
+ const struct Curl_addrinfo *ai,
+ int transport);
+
+/**
+ * Creates a cfilter that opens a TCP socket to the given address
+ * when calling its `connect` implementation.
+ * The filter will not touch any connection/data flags and can be
+ * used in happy eyeballing. Once selected for use, its `_active()`
+ * method needs to be called.
+ */
+CURLcode Curl_cf_tcp_create(struct Curl_cfilter **pcf,
+ struct Curl_easy *data,
+ struct connectdata *conn,
+ const struct Curl_addrinfo *ai,
+ int transport);
+
+/**
+ * Creates a cfilter that opens a UDP socket to the given address
+ * when calling its `connect` implementation.
+ * The filter will not touch any connection/data flags and can be
+ * used in happy eyeballing. Once selected for use, its `_active()`
+ * method needs to be called.
+ */
+CURLcode Curl_cf_udp_create(struct Curl_cfilter **pcf,
+ struct Curl_easy *data,
+ struct connectdata *conn,
+ const struct Curl_addrinfo *ai,
+ int transport);
+
+/**
+ * Creates a cfilter that opens a UNIX socket to the given address
+ * when calling its `connect` implementation.
+ * The filter will not touch any connection/data flags and can be
+ * used in happy eyeballing. Once selected for use, its `_active()`
+ * method needs to be called.
+ */
+CURLcode Curl_cf_unix_create(struct Curl_cfilter **pcf,
+ struct Curl_easy *data,
+ struct connectdata *conn,
+ const struct Curl_addrinfo *ai,
+ int transport);
+
+/**
+ * Creates a cfilter that keeps a listening socket.
+ */
+CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data,
+ struct connectdata *conn,
+ int sockindex,
+ curl_socket_t *s);
+
+/**
+ * Replace the listen socket with the accept()ed one.
+ */
+CURLcode Curl_conn_tcp_accepted_set(struct Curl_easy *data,
+ struct connectdata *conn,
+ int sockindex,
+ curl_socket_t *s);
+
+/**
+ * Peek at the socket and remote ip/port the socket filter is using.
+ * The filter owns all returned values.
+ * @param psock pointer to hold socket descriptor or NULL
+ * @param paddr pointer to hold addr reference or NULL
+ * @param pr_ip_str pointer to hold remote addr as string or NULL
+ * @param pr_port pointer to hold remote port number or NULL
+ * @param pl_ip_str pointer to hold local addr as string or NULL
+ * @param pl_port pointer to hold local port number or NULL
+ * Returns error if the filter is of invalid type.
+ */
+CURLcode Curl_cf_socket_peek(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ curl_socket_t *psock,
+ const struct Curl_sockaddr_ex **paddr,
+ const char **pr_ip_str, int *pr_port,
+ const char **pl_ip_str, int *pl_port);
+
+extern struct Curl_cftype Curl_cft_tcp;
+extern struct Curl_cftype Curl_cft_udp;
+extern struct Curl_cftype Curl_cft_unix;
+extern struct Curl_cftype Curl_cft_tcp_accept;
+
+#endif /* HEADER_CURL_CF_SOCKET_H */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/cfilters.c b/iotdb-client/odbc/deps/curl-src/lib/cfilters.c
new file mode 100644
index 0000000000000..f74eb40039773
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/cfilters.c
@@ -0,0 +1,648 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "urldata.h"
+#include "strerror.h"
+#include "cfilters.h"
+#include "connect.h"
+#include "url.h" /* for Curl_safefree() */
+#include "sendf.h"
+#include "sockaddr.h" /* required for Curl_sockaddr_storage */
+#include "multiif.h"
+#include "progress.h"
+#include "warnless.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
+#endif
+
+#ifdef DEBUGBUILD
+/* used by unit2600.c */
+void Curl_cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data)
+{
+ cf->connected = FALSE;
+ if(cf->next)
+ cf->next->cft->do_close(cf->next, data);
+}
+#endif
+
+static void conn_report_connect_stats(struct Curl_easy *data,
+ struct connectdata *conn);
+
+void Curl_cf_def_get_host(struct Curl_cfilter *cf, struct Curl_easy *data,
+ const char **phost, const char **pdisplay_host,
+ int *pport)
+{
+ if(cf->next)
+ cf->next->cft->get_host(cf->next, data, phost, pdisplay_host, pport);
+ else {
+ *phost = cf->conn->host.name;
+ *pdisplay_host = cf->conn->host.dispname;
+ *pport = cf->conn->port;
+ }
+}
+
+int Curl_cf_def_get_select_socks(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ curl_socket_t *socks)
+{
+ return cf->next?
+ cf->next->cft->get_select_socks(cf->next, data, socks) : 0;
+}
+
+bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
+ const struct Curl_easy *data)
+{
+ return cf->next?
+ cf->next->cft->has_data_pending(cf->next, data) : FALSE;
+}
+
+ssize_t Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data,
+ const void *buf, size_t len, CURLcode *err)
+{
+ return cf->next?
+ cf->next->cft->do_send(cf->next, data, buf, len, err) :
+ CURLE_RECV_ERROR;
+}
+
+ssize_t Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
+ char *buf, size_t len, CURLcode *err)
+{
+ return cf->next?
+ cf->next->cft->do_recv(cf->next, data, buf, len, err) :
+ CURLE_SEND_ERROR;
+}
+
+bool Curl_cf_def_conn_is_alive(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *input_pending)
+{
+ return cf->next?
+ cf->next->cft->is_alive(cf->next, data, input_pending) :
+ FALSE; /* pessimistic in absence of data */
+}
+
+CURLcode Curl_cf_def_conn_keep_alive(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ return cf->next?
+ cf->next->cft->keep_alive(cf->next, data) :
+ CURLE_OK;
+}
+
+CURLcode Curl_cf_def_query(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ int query, int *pres1, void *pres2)
+{
+ return cf->next?
+ cf->next->cft->query(cf->next, data, query, pres1, pres2) :
+ CURLE_UNKNOWN_OPTION;
+}
+
+void Curl_conn_cf_discard_chain(struct Curl_cfilter **pcf,
+ struct Curl_easy *data)
+{
+ struct Curl_cfilter *cfn, *cf = *pcf;
+
+ if(cf) {
+ *pcf = NULL;
+ while(cf) {
+ cfn = cf->next;
+ /* prevent destroying filter to mess with its sub-chain, since
+ * we have the reference now and will call destroy on it.
+ */
+ cf->next = NULL;
+ cf->cft->destroy(cf, data);
+ free(cf);
+ cf = cfn;
+ }
+ }
+}
+
+void Curl_conn_cf_discard_all(struct Curl_easy *data,
+ struct connectdata *conn, int index)
+{
+ Curl_conn_cf_discard_chain(&conn->cfilter[index], data);
+}
+
+void Curl_conn_close(struct Curl_easy *data, int index)
+{
+ struct Curl_cfilter *cf;
+
+ DEBUGASSERT(data->conn);
+ /* it is valid to call that without filters being present */
+ cf = data->conn->cfilter[index];
+ if(cf) {
+ cf->cft->do_close(cf, data);
+ }
+}
+
+ssize_t Curl_conn_recv(struct Curl_easy *data, int num, char *buf,
+ size_t len, CURLcode *code)
+{
+ struct Curl_cfilter *cf;
+
+ DEBUGASSERT(data);
+ DEBUGASSERT(data->conn);
+ cf = data->conn->cfilter[num];
+ while(cf && !cf->connected) {
+ cf = cf->next;
+ }
+ if(cf) {
+ return cf->cft->do_recv(cf, data, buf, len, code);
+ }
+ failf(data, "recv: no filter connected");
+ *code = CURLE_FAILED_INIT;
+ return -1;
+}
+
+ssize_t Curl_conn_send(struct Curl_easy *data, int num,
+ const void *mem, size_t len, CURLcode *code)
+{
+ struct Curl_cfilter *cf;
+
+ DEBUGASSERT(data);
+ DEBUGASSERT(data->conn);
+ cf = data->conn->cfilter[num];
+ while(cf && !cf->connected) {
+ cf = cf->next;
+ }
+ if(cf) {
+ return cf->cft->do_send(cf, data, mem, len, code);
+ }
+ failf(data, "send: no filter connected");
+ DEBUGASSERT(0);
+ *code = CURLE_FAILED_INIT;
+ return -1;
+}
+
+CURLcode Curl_cf_create(struct Curl_cfilter **pcf,
+ const struct Curl_cftype *cft,
+ void *ctx)
+{
+ struct Curl_cfilter *cf;
+ CURLcode result = CURLE_OUT_OF_MEMORY;
+
+ DEBUGASSERT(cft);
+ cf = calloc(sizeof(*cf), 1);
+ if(!cf)
+ goto out;
+
+ cf->cft = cft;
+ cf->ctx = ctx;
+ result = CURLE_OK;
+out:
+ *pcf = cf;
+ return result;
+}
+
+void Curl_conn_cf_add(struct Curl_easy *data,
+ struct connectdata *conn,
+ int index,
+ struct Curl_cfilter *cf)
+{
+ (void)data;
+ DEBUGASSERT(conn);
+ DEBUGASSERT(!cf->conn);
+ DEBUGASSERT(!cf->next);
+
+ cf->next = conn->cfilter[index];
+ cf->conn = conn;
+ cf->sockindex = index;
+ conn->cfilter[index] = cf;
+ CURL_TRC_CF(data, cf, "added");
+}
+
+void Curl_conn_cf_insert_after(struct Curl_cfilter *cf_at,
+ struct Curl_cfilter *cf_new)
+{
+ struct Curl_cfilter *tail, **pnext;
+
+ DEBUGASSERT(cf_at);
+ DEBUGASSERT(cf_new);
+ DEBUGASSERT(!cf_new->conn);
+
+ tail = cf_at->next;
+ cf_at->next = cf_new;
+ do {
+ cf_new->conn = cf_at->conn;
+ cf_new->sockindex = cf_at->sockindex;
+ pnext = &cf_new->next;
+ cf_new = cf_new->next;
+ } while(cf_new);
+ *pnext = tail;
+}
+
+bool Curl_conn_cf_discard_sub(struct Curl_cfilter *cf,
+ struct Curl_cfilter *discard,
+ struct Curl_easy *data,
+ bool destroy_always)
+{
+ struct Curl_cfilter **pprev = &cf->next;
+ bool found = FALSE;
+
+ /* remove from sub-chain and destroy */
+ DEBUGASSERT(cf);
+ while(*pprev) {
+ if(*pprev == cf) {
+ *pprev = discard->next;
+ discard->next = NULL;
+ found = TRUE;
+ break;
+ }
+ pprev = &((*pprev)->next);
+ }
+ if(found || destroy_always) {
+ discard->next = NULL;
+ discard->cft->destroy(discard, data);
+ free(discard);
+ }
+ return found;
+}
+
+CURLcode Curl_conn_cf_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool blocking, bool *done)
+{
+ if(cf)
+ return cf->cft->do_connect(cf, data, blocking, done);
+ return CURLE_FAILED_INIT;
+}
+
+void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data)
+{
+ if(cf)
+ cf->cft->do_close(cf, data);
+}
+
+int Curl_conn_cf_get_select_socks(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ curl_socket_t *socks)
+{
+ if(cf)
+ return cf->cft->get_select_socks(cf, data, socks);
+ return 0;
+}
+
+ssize_t Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data,
+ const void *buf, size_t len, CURLcode *err)
+{
+ if(cf)
+ return cf->cft->do_send(cf, data, buf, len, err);
+ *err = CURLE_SEND_ERROR;
+ return -1;
+}
+
+ssize_t Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
+ char *buf, size_t len, CURLcode *err)
+{
+ if(cf)
+ return cf->cft->do_recv(cf, data, buf, len, err);
+ *err = CURLE_RECV_ERROR;
+ return -1;
+}
+
+CURLcode Curl_conn_connect(struct Curl_easy *data,
+ int sockindex,
+ bool blocking,
+ bool *done)
+{
+ struct Curl_cfilter *cf;
+ CURLcode result = CURLE_OK;
+
+ DEBUGASSERT(data);
+ DEBUGASSERT(data->conn);
+
+ cf = data->conn->cfilter[sockindex];
+ DEBUGASSERT(cf);
+ if(!cf)
+ return CURLE_FAILED_INIT;
+
+ *done = cf->connected;
+ if(!*done) {
+ result = cf->cft->do_connect(cf, data, blocking, done);
+ if(!result && *done) {
+ Curl_conn_ev_update_info(data, data->conn);
+ conn_report_connect_stats(data, data->conn);
+ data->conn->keepalive = Curl_now();
+ }
+ else if(result) {
+ conn_report_connect_stats(data, data->conn);
+ }
+ }
+
+ return result;
+}
+
+bool Curl_conn_is_connected(struct connectdata *conn, int sockindex)
+{
+ struct Curl_cfilter *cf;
+
+ cf = conn->cfilter[sockindex];
+ return cf && cf->connected;
+}
+
+bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex)
+{
+ struct Curl_cfilter *cf;
+
+ cf = data->conn->cfilter[sockindex];
+ while(cf) {
+ if(cf->connected)
+ return TRUE;
+ if(cf->cft->flags & CF_TYPE_IP_CONNECT)
+ return FALSE;
+ cf = cf->next;
+ }
+ return FALSE;
+}
+
+bool Curl_conn_cf_is_ssl(struct Curl_cfilter *cf)
+{
+ for(; cf; cf = cf->next) {
+ if(cf->cft->flags & CF_TYPE_SSL)
+ return TRUE;
+ if(cf->cft->flags & CF_TYPE_IP_CONNECT)
+ return FALSE;
+ }
+ return FALSE;
+}
+
+bool Curl_conn_is_ssl(struct connectdata *conn, int sockindex)
+{
+ return conn? Curl_conn_cf_is_ssl(conn->cfilter[sockindex]) : FALSE;
+}
+
+bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex)
+{
+ struct Curl_cfilter *cf = conn? conn->cfilter[sockindex] : NULL;
+
+ for(; cf; cf = cf->next) {
+ if(cf->cft->flags & CF_TYPE_MULTIPLEX)
+ return TRUE;
+ if(cf->cft->flags & CF_TYPE_IP_CONNECT
+ || cf->cft->flags & CF_TYPE_SSL)
+ return FALSE;
+ }
+ return FALSE;
+}
+
+bool Curl_conn_data_pending(struct Curl_easy *data, int sockindex)
+{
+ struct Curl_cfilter *cf;
+
+ (void)data;
+ DEBUGASSERT(data);
+ DEBUGASSERT(data->conn);
+
+ cf = data->conn->cfilter[sockindex];
+ while(cf && !cf->connected) {
+ cf = cf->next;
+ }
+ if(cf) {
+ return cf->cft->has_data_pending(cf, data);
+ }
+ return FALSE;
+}
+
+int Curl_conn_get_select_socks(struct Curl_easy *data, int sockindex,
+ curl_socket_t *socks)
+{
+ struct Curl_cfilter *cf;
+
+ DEBUGASSERT(data);
+ DEBUGASSERT(data->conn);
+ cf = data->conn->cfilter[sockindex];
+
+ /* if the next one is not yet connected, that's the one we want */
+ while(cf && cf->next && !cf->next->connected)
+ cf = cf->next;
+ if(cf) {
+ return cf->cft->get_select_socks(cf, data, socks);
+ }
+ return GETSOCK_BLANK;
+}
+
+void Curl_conn_get_host(struct Curl_easy *data, int sockindex,
+ const char **phost, const char **pdisplay_host,
+ int *pport)
+{
+ struct Curl_cfilter *cf;
+
+ DEBUGASSERT(data->conn);
+ cf = data->conn->cfilter[sockindex];
+ if(cf) {
+ cf->cft->get_host(cf, data, phost, pdisplay_host, pport);
+ }
+ else {
+ /* Some filter ask during shutdown for this, mainly for debugging
+ * purposes. We hand out the defaults, however this is not always
+ * accurate, as the connection might be tunneled, etc. But all that
+ * state is already gone here. */
+ *phost = data->conn->host.name;
+ *pdisplay_host = data->conn->host.dispname;
+ *pport = data->conn->remote_port;
+ }
+}
+
+CURLcode Curl_cf_def_cntrl(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ int event, int arg1, void *arg2)
+{
+ (void)cf;
+ (void)data;
+ (void)event;
+ (void)arg1;
+ (void)arg2;
+ return CURLE_OK;
+}
+
+CURLcode Curl_conn_cf_cntrl(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool ignore_result,
+ int event, int arg1, void *arg2)
+{
+ CURLcode result = CURLE_OK;
+
+ for(; cf; cf = cf->next) {
+ if(Curl_cf_def_cntrl == cf->cft->cntrl)
+ continue;
+ result = cf->cft->cntrl(cf, data, event, arg1, arg2);
+ if(!ignore_result && result)
+ break;
+ }
+ return result;
+}
+
+curl_socket_t Curl_conn_cf_get_socket(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ curl_socket_t sock;
+ if(cf && !cf->cft->query(cf, data, CF_QUERY_SOCKET, NULL, &sock))
+ return sock;
+ return CURL_SOCKET_BAD;
+}
+
+curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex)
+{
+ struct Curl_cfilter *cf;
+
+ cf = data->conn? data->conn->cfilter[sockindex] : NULL;
+ /* if the top filter has not connected, ask it (and its sub-filters)
+ * for the socket. Otherwise conn->sock[sockindex] should have it.
+ */
+ if(cf && !cf->connected)
+ return Curl_conn_cf_get_socket(cf, data);
+ return data->conn? data->conn->sock[sockindex] : CURL_SOCKET_BAD;
+}
+
+static CURLcode cf_cntrl_all(struct connectdata *conn,
+ struct Curl_easy *data,
+ bool ignore_result,
+ int event, int arg1, void *arg2)
+{
+ CURLcode result = CURLE_OK;
+ size_t i;
+
+ for(i = 0; i < ARRAYSIZE(conn->cfilter); ++i) {
+ result = Curl_conn_cf_cntrl(conn->cfilter[i], data, ignore_result,
+ event, arg1, arg2);
+ if(!ignore_result && result)
+ break;
+ }
+ return result;
+}
+
+void Curl_conn_ev_data_attach(struct connectdata *conn,
+ struct Curl_easy *data)
+{
+ cf_cntrl_all(conn, data, TRUE, CF_CTRL_DATA_ATTACH, 0, NULL);
+}
+
+void Curl_conn_ev_data_detach(struct connectdata *conn,
+ struct Curl_easy *data)
+{
+ cf_cntrl_all(conn, data, TRUE, CF_CTRL_DATA_DETACH, 0, NULL);
+}
+
+CURLcode Curl_conn_ev_data_setup(struct Curl_easy *data)
+{
+ return cf_cntrl_all(data->conn, data, FALSE,
+ CF_CTRL_DATA_SETUP, 0, NULL);
+}
+
+CURLcode Curl_conn_ev_data_idle(struct Curl_easy *data)
+{
+ return cf_cntrl_all(data->conn, data, FALSE,
+ CF_CTRL_DATA_IDLE, 0, NULL);
+}
+
+/**
+ * Notify connection filters that the transfer represented by `data`
+ * is donw with sending data (e.g. has uploaded everything).
+ */
+void Curl_conn_ev_data_done_send(struct Curl_easy *data)
+{
+ cf_cntrl_all(data->conn, data, TRUE, CF_CTRL_DATA_DONE_SEND, 0, NULL);
+}
+
+/**
+ * Notify connection filters that the transfer represented by `data`
+ * is finished - eventually premature, e.g. before being complete.
+ */
+void Curl_conn_ev_data_done(struct Curl_easy *data, bool premature)
+{
+ cf_cntrl_all(data->conn, data, TRUE, CF_CTRL_DATA_DONE, premature, NULL);
+}
+
+CURLcode Curl_conn_ev_data_pause(struct Curl_easy *data, bool do_pause)
+{
+ return cf_cntrl_all(data->conn, data, FALSE,
+ CF_CTRL_DATA_PAUSE, do_pause, NULL);
+}
+
+void Curl_conn_ev_update_info(struct Curl_easy *data,
+ struct connectdata *conn)
+{
+ cf_cntrl_all(conn, data, TRUE, CF_CTRL_CONN_INFO_UPDATE, 0, NULL);
+}
+
+/**
+ * Update connection statistics
+ */
+static void conn_report_connect_stats(struct Curl_easy *data,
+ struct connectdata *conn)
+{
+ struct Curl_cfilter *cf = conn->cfilter[FIRSTSOCKET];
+ if(cf) {
+ struct curltime connected;
+ struct curltime appconnected;
+
+ memset(&connected, 0, sizeof(connected));
+ cf->cft->query(cf, data, CF_QUERY_TIMER_CONNECT, NULL, &connected);
+ if(connected.tv_sec || connected.tv_usec)
+ Curl_pgrsTimeWas(data, TIMER_CONNECT, connected);
+
+ memset(&appconnected, 0, sizeof(appconnected));
+ cf->cft->query(cf, data, CF_QUERY_TIMER_APPCONNECT, NULL, &appconnected);
+ if(appconnected.tv_sec || appconnected.tv_usec)
+ Curl_pgrsTimeWas(data, TIMER_APPCONNECT, appconnected);
+ }
+}
+
+bool Curl_conn_is_alive(struct Curl_easy *data, struct connectdata *conn,
+ bool *input_pending)
+{
+ struct Curl_cfilter *cf = conn->cfilter[FIRSTSOCKET];
+ return cf && !cf->conn->bits.close &&
+ cf->cft->is_alive(cf, data, input_pending);
+}
+
+CURLcode Curl_conn_keep_alive(struct Curl_easy *data,
+ struct connectdata *conn,
+ int sockindex)
+{
+ struct Curl_cfilter *cf = conn->cfilter[sockindex];
+ return cf? cf->cft->keep_alive(cf, data) : CURLE_OK;
+}
+
+size_t Curl_conn_get_max_concurrent(struct Curl_easy *data,
+ struct connectdata *conn,
+ int sockindex)
+{
+ CURLcode result;
+ int n = 0;
+
+ struct Curl_cfilter *cf = conn->cfilter[sockindex];
+ result = cf? cf->cft->query(cf, data, CF_QUERY_MAX_CONCURRENT,
+ &n, NULL) : CURLE_UNKNOWN_OPTION;
+ return (result || n <= 0)? 1 : (size_t)n;
+}
diff --git a/iotdb-client/odbc/deps/curl-src/lib/cfilters.h b/iotdb-client/odbc/deps/curl-src/lib/cfilters.h
new file mode 100644
index 0000000000000..2c65264d98376
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/cfilters.h
@@ -0,0 +1,539 @@
+#ifndef HEADER_CURL_CFILTERS_H
+#define HEADER_CURL_CFILTERS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+
+struct Curl_cfilter;
+struct Curl_easy;
+struct Curl_dns_entry;
+struct connectdata;
+
+/* Callback to destroy resources held by this filter instance.
+ * Implementations MUST NOT chain calls to cf->next.
+ */
+typedef void Curl_cft_destroy_this(struct Curl_cfilter *cf,
+ struct Curl_easy *data);
+
+typedef void Curl_cft_close(struct Curl_cfilter *cf,
+ struct Curl_easy *data);
+
+typedef CURLcode Curl_cft_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool blocking, bool *done);
+
+/* Return the hostname and port the connection goes to.
+ * This may change with the connection state of filters when tunneling
+ * is involved.
+ * @param cf the filter to ask
+ * @param data the easy handle currently active
+ * @param phost on return, points to the relevant, real hostname.
+ * this is owned by the connection.
+ * @param pdisplay_host on return, points to the printable hostname.
+ * this is owned by the connection.
+ * @param pport on return, contains the port number
+ */
+typedef void Curl_cft_get_host(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ const char **phost,
+ const char **pdisplay_host,
+ int *pport);
+
+/* Filters may return sockets and fdset flags they are waiting for.
+ * The passes array has room for up to MAX_SOCKSPEREASYHANDLE sockets.
+ * @return read/write fdset for index in socks
+ * or GETSOCK_BLANK when nothing to wait on
+ */
+typedef int Curl_cft_get_select_socks(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ curl_socket_t *socks);
+
+typedef bool Curl_cft_data_pending(struct Curl_cfilter *cf,
+ const struct Curl_easy *data);
+
+typedef ssize_t Curl_cft_send(struct Curl_cfilter *cf,
+ struct Curl_easy *data, /* transfer */
+ const void *buf, /* data to write */
+ size_t len, /* amount to write */
+ CURLcode *err); /* error to return */
+
+typedef ssize_t Curl_cft_recv(struct Curl_cfilter *cf,
+ struct Curl_easy *data, /* transfer */
+ char *buf, /* store data here */
+ size_t len, /* amount to read */
+ CURLcode *err); /* error to return */
+
+typedef bool Curl_cft_conn_is_alive(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *input_pending);
+
+typedef CURLcode Curl_cft_conn_keep_alive(struct Curl_cfilter *cf,
+ struct Curl_easy *data);
+
+/**
+ * Events/controls for connection filters, their arguments and
+ * return code handling. Filter callbacks are invoked "top down".
+ * Return code handling:
+ * "first fail" meaning that the first filter returning != CURLE_OK, will
+ * abort further event distribution and determine the result.
+ * "ignored" meaning return values are ignored and the event is distributed
+ * to all filters in the chain. Overall result is always CURLE_OK.
+ */
+/* data event arg1 arg2 return */
+#define CF_CTRL_DATA_ATTACH 1 /* 0 NULL ignored */
+#define CF_CTRL_DATA_DETACH 2 /* 0 NULL ignored */
+#define CF_CTRL_DATA_SETUP 4 /* 0 NULL first fail */
+#define CF_CTRL_DATA_IDLE 5 /* 0 NULL first fail */
+#define CF_CTRL_DATA_PAUSE 6 /* on/off NULL first fail */
+#define CF_CTRL_DATA_DONE 7 /* premature NULL ignored */
+#define CF_CTRL_DATA_DONE_SEND 8 /* 0 NULL ignored */
+/* update conn info at connection and data */
+#define CF_CTRL_CONN_INFO_UPDATE (256+0) /* 0 NULL ignored */
+
+/**
+ * Handle event/control for the filter.
+ * Implementations MUST NOT chain calls to cf->next.
+ */
+typedef CURLcode Curl_cft_cntrl(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ int event, int arg1, void *arg2);
+
+
+/**
+ * Queries to ask via a `Curl_cft_query *query` method on a cfilter chain.
+ * - MAX_CONCURRENT: the maximum number of parallel transfers the filter
+ * chain expects to handle at the same time.
+ * default: 1 if no filter overrides.
+ * - CONNECT_REPLY_MS: milliseconds until the first indication of a server
+ * response was received on a connect. For TCP, this
+ * reflects the time until the socket connected. On UDP
+ * this gives the time the first bytes from the server
+ * were received.
+ * -1 if not determined yet.
+ * - CF_QUERY_SOCKET: the socket used by the filter chain
+ */
+/* query res1 res2 */
+#define CF_QUERY_MAX_CONCURRENT 1 /* number - */
+#define CF_QUERY_CONNECT_REPLY_MS 2 /* number - */
+#define CF_QUERY_SOCKET 3 /* - curl_socket_t */
+#define CF_QUERY_TIMER_CONNECT 4 /* - struct curltime */
+#define CF_QUERY_TIMER_APPCONNECT 5 /* - struct curltime */
+
+/**
+ * Query the cfilter for properties. Filters ignorant of a query will
+ * pass it "down" the filter chain.
+ */
+typedef CURLcode Curl_cft_query(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ int query, int *pres1, void *pres2);
+
+/**
+ * Type flags for connection filters. A filter can have none, one or
+ * many of those. Use to evaluate state/capabilities of a filter chain.
+ *
+ * CF_TYPE_IP_CONNECT: provides an IP connection or sth equivalent, like
+ * a CONNECT tunnel, a UNIX domain socket, a QUIC
+ * connection, etc.
+ * CF_TYPE_SSL: provide SSL/TLS
+ * CF_TYPE_MULTIPLEX: provides multiplexing of easy handles
+ */
+#define CF_TYPE_IP_CONNECT (1 << 0)
+#define CF_TYPE_SSL (1 << 1)
+#define CF_TYPE_MULTIPLEX (1 << 2)
+
+/* A connection filter type, e.g. specific implementation. */
+struct Curl_cftype {
+ const char *name; /* name of the filter type */
+ int flags; /* flags of filter type */
+ int log_level; /* log level for such filters */
+ Curl_cft_destroy_this *destroy; /* destroy resources of this cf */
+ Curl_cft_connect *do_connect; /* establish connection */
+ Curl_cft_close *do_close; /* close conn */
+ Curl_cft_get_host *get_host; /* host filter talks to */
+ Curl_cft_get_select_socks *get_select_socks;/* sockets to select on */
+ Curl_cft_data_pending *has_data_pending;/* conn has data pending */
+ Curl_cft_send *do_send; /* send data */
+ Curl_cft_recv *do_recv; /* receive data */
+ Curl_cft_cntrl *cntrl; /* events/control */
+ Curl_cft_conn_is_alive *is_alive; /* FALSE if conn is dead, Jim! */
+ Curl_cft_conn_keep_alive *keep_alive; /* try to keep it alive */
+ Curl_cft_query *query; /* query filter chain */
+};
+
+/* A connection filter instance, e.g. registered at a connection */
+struct Curl_cfilter {
+ const struct Curl_cftype *cft; /* the type providing implementation */
+ struct Curl_cfilter *next; /* next filter in chain */
+ void *ctx; /* filter type specific settings */
+ struct connectdata *conn; /* the connection this filter belongs to */
+ int sockindex; /* the index the filter is installed at */
+ BIT(connected); /* != 0 iff this filter is connected */
+};
+
+/* Default implementations for the type functions, implementing nop. */
+void Curl_cf_def_destroy_this(struct Curl_cfilter *cf,
+ struct Curl_easy *data);
+
+/* Default implementations for the type functions, implementing pass-through
+ * the filter chain. */
+void Curl_cf_def_get_host(struct Curl_cfilter *cf, struct Curl_easy *data,
+ const char **phost, const char **pdisplay_host,
+ int *pport);
+int Curl_cf_def_get_select_socks(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ curl_socket_t *socks);
+bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
+ const struct Curl_easy *data);
+ssize_t Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data,
+ const void *buf, size_t len, CURLcode *err);
+ssize_t Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
+ char *buf, size_t len, CURLcode *err);
+CURLcode Curl_cf_def_cntrl(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ int event, int arg1, void *arg2);
+bool Curl_cf_def_conn_is_alive(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *input_pending);
+CURLcode Curl_cf_def_conn_keep_alive(struct Curl_cfilter *cf,
+ struct Curl_easy *data);
+CURLcode Curl_cf_def_query(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ int query, int *pres1, void *pres2);
+
+/**
+ * Create a new filter instance, unattached to the filter chain.
+ * Use Curl_conn_cf_add() to add it to the chain.
+ * @param pcf on success holds the created instance
+ * @param cft the filter type
+ * @param ctx the type specific context to use
+ */
+CURLcode Curl_cf_create(struct Curl_cfilter **pcf,
+ const struct Curl_cftype *cft,
+ void *ctx);
+
+/**
+ * Add a filter instance to the `sockindex` filter chain at connection
+ * `conn`. The filter must not already be attached. It is inserted at
+ * the start of the chain (top).
+ */
+void Curl_conn_cf_add(struct Curl_easy *data,
+ struct connectdata *conn,
+ int sockindex,
+ struct Curl_cfilter *cf);
+
+/**
+ * Insert a filter (chain) after `cf_at`.
+ * `cf_new` must not already be attached.
+ */
+void Curl_conn_cf_insert_after(struct Curl_cfilter *cf_at,
+ struct Curl_cfilter *cf_new);
+
+/**
+ * Discard, e.g. remove and destroy `discard` iff
+ * it still is in the filter chain below `cf`. If `discard`
+ * is no longer found beneath `cf` return FALSE.
+ * if `destroy_always` is TRUE, will call `discard`s destroy
+ * function and free it even if not found in the subchain.
+ */
+bool Curl_conn_cf_discard_sub(struct Curl_cfilter *cf,
+ struct Curl_cfilter *discard,
+ struct Curl_easy *data,
+ bool destroy_always);
+
+/**
+ * Discard all cfilters starting with `*pcf` and clearing it afterwards.
+ */
+void Curl_conn_cf_discard_chain(struct Curl_cfilter **pcf,
+ struct Curl_easy *data);
+
+/**
+ * Remove and destroy all filters at chain `sockindex` on connection `conn`.
+ */
+void Curl_conn_cf_discard_all(struct Curl_easy *data,
+ struct connectdata *conn,
+ int sockindex);
+
+
+CURLcode Curl_conn_cf_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool blocking, bool *done);
+void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data);
+int Curl_conn_cf_get_select_socks(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ curl_socket_t *socks);
+ssize_t Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data,
+ const void *buf, size_t len, CURLcode *err);
+ssize_t Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
+ char *buf, size_t len, CURLcode *err);
+CURLcode Curl_conn_cf_cntrl(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool ignore_result,
+ int event, int arg1, void *arg2);
+
+/**
+ * Determine if the connection filter chain is using SSL to the remote host
+ * (or will be once connected).
+ */
+bool Curl_conn_cf_is_ssl(struct Curl_cfilter *cf);
+
+/**
+ * Get the socket used by the filter chain starting at `cf`.
+ * Returns CURL_SOCKET_BAD if not available.
+ */
+curl_socket_t Curl_conn_cf_get_socket(struct Curl_cfilter *cf,
+ struct Curl_easy *data);
+
+
+#define CURL_CF_SSL_DEFAULT -1
+#define CURL_CF_SSL_DISABLE 0
+#define CURL_CF_SSL_ENABLE 1
+
+/**
+ * Bring the filter chain at `sockindex` for connection `data->conn` into
+ * connected state. Which will set `*done` to TRUE.
+ * This can be called on an already connected chain with no side effects.
+ * When not `blocking`, calls may return without error and `*done != TRUE`,
+ * while the individual filters negotiated the connection.
+ */
+CURLcode Curl_conn_connect(struct Curl_easy *data, int sockindex,
+ bool blocking, bool *done);
+
+/**
+ * Check if the filter chain at `sockindex` for connection `conn` is
+ * completely connected.
+ */
+bool Curl_conn_is_connected(struct connectdata *conn, int sockindex);
+
+/**
+ * Determine if we have reached the remote host on IP level, e.g.
+ * have a TCP connection. This turns TRUE before a possible SSL
+ * handshake has been started/done.
+ */
+bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex);
+
+/**
+ * Determine if the connection is using SSL to the remote host
+ * (or will be once connected). This will return FALSE, if SSL
+ * is only used in proxying and not for the tunnel itself.
+ */
+bool Curl_conn_is_ssl(struct connectdata *conn, int sockindex);
+
+/**
+ * Connection provides multiplexing of easy handles at `socketindex`.
+ */
+bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex);
+
+/**
+ * Close the filter chain at `sockindex` for connection `data->conn`.
+ * Filters remain in place and may be connected again afterwards.
+ */
+void Curl_conn_close(struct Curl_easy *data, int sockindex);
+
+/**
+ * Return if data is pending in some connection filter at chain
+ * `sockindex` for connection `data->conn`.
+ */
+bool Curl_conn_data_pending(struct Curl_easy *data,
+ int sockindex);
+
+/**
+ * Return the socket used on data's connection for the index.
+ * Returns CURL_SOCKET_BAD if not available.
+ */
+curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex);
+
+/**
+ * Get any select fd flags and the socket filters at chain `sockindex`
+ * at connection `conn` might be waiting for.
+ */
+int Curl_conn_get_select_socks(struct Curl_easy *data, int sockindex,
+ curl_socket_t *socks);
+
+/**
+ * Receive data through the filter chain at `sockindex` for connection
+ * `data->conn`. Copy at most `len` bytes into `buf`. Return the
+ * actuel number of bytes copied or a negative value on error.
+ * The error code is placed into `*code`.
+ */
+ssize_t Curl_conn_recv(struct Curl_easy *data, int sockindex, char *buf,
+ size_t len, CURLcode *code);
+
+/**
+ * Send `len` bytes of data from `buf` through the filter chain `sockindex`
+ * at connection `data->conn`. Return the actual number of bytes written
+ * or a negative value on error.
+ * The error code is placed into `*code`.
+ */
+ssize_t Curl_conn_send(struct Curl_easy *data, int sockindex,
+ const void *buf, size_t len, CURLcode *code);
+
+/**
+ * The easy handle `data` is being attached to `conn`. This does
+ * not mean that data will actually do a transfer. Attachment is
+ * also used for temporary actions on the connection.
+ */
+void Curl_conn_ev_data_attach(struct connectdata *conn,
+ struct Curl_easy *data);
+
+/**
+ * The easy handle `data` is being detached (no longer served)
+ * by connection `conn`. All filters are informed to release any resources
+ * related to `data`.
+ * Note: there may be several `data` attached to a connection at the same
+ * time.
+ */
+void Curl_conn_ev_data_detach(struct connectdata *conn,
+ struct Curl_easy *data);
+
+/**
+ * Notify connection filters that they need to setup data for
+ * a transfer.
+ */
+CURLcode Curl_conn_ev_data_setup(struct Curl_easy *data);
+
+/**
+ * Notify connection filters that now would be a good time to
+ * perform any idle, e.g. time related, actions.
+ */
+CURLcode Curl_conn_ev_data_idle(struct Curl_easy *data);
+
+/**
+ * Notify connection filters that the transfer represented by `data`
+ * is donw with sending data (e.g. has uploaded everything).
+ */
+void Curl_conn_ev_data_done_send(struct Curl_easy *data);
+
+/**
+ * Notify connection filters that the transfer represented by `data`
+ * is finished - eventually premature, e.g. before being complete.
+ */
+void Curl_conn_ev_data_done(struct Curl_easy *data, bool premature);
+
+/**
+ * Notify connection filters that the transfer of data is paused/unpaused.
+ */
+CURLcode Curl_conn_ev_data_pause(struct Curl_easy *data, bool do_pause);
+
+/**
+ * Inform connection filters to update their info in `conn`.
+ */
+void Curl_conn_ev_update_info(struct Curl_easy *data,
+ struct connectdata *conn);
+
+/**
+ * Check if FIRSTSOCKET's cfilter chain deems connection alive.
+ */
+bool Curl_conn_is_alive(struct Curl_easy *data, struct connectdata *conn,
+ bool *input_pending);
+
+/**
+ * Try to upkeep the connection filters at sockindex.
+ */
+CURLcode Curl_conn_keep_alive(struct Curl_easy *data,
+ struct connectdata *conn,
+ int sockindex);
+
+void Curl_cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data);
+void Curl_conn_get_host(struct Curl_easy *data, int sockindex,
+ const char **phost, const char **pdisplay_host,
+ int *pport);
+
+/**
+ * Get the maximum number of parallel transfers the connection
+ * expects to be able to handle at `sockindex`.
+ */
+size_t Curl_conn_get_max_concurrent(struct Curl_easy *data,
+ struct connectdata *conn,
+ int sockindex);
+
+
+/**
+ * Types and macros used to keep the current easy handle in filter calls,
+ * allowing for nested invocations. See #10336.
+ *
+ * `cf_call_data` is intended to be a member of the cfilter's `ctx` type.
+ * A filter defines the macro `CF_CTX_CALL_DATA` to give access to that.
+ *
+ * With all values 0, the default, this indicates that there is no cfilter
+ * call with `data` ongoing.
+ * Macro `CF_DATA_SAVE` preserves the current `cf_call_data` in a local
+ * variable and sets the `data` given, incrementing the `depth` counter.
+ *
+ * Macro `CF_DATA_RESTORE` restores the old values from the local variable,
+ * while checking that `depth` values are as expected (debug build), catching
+ * cases where a "lower" RESTORE was not called.
+ *
+ * Finally, macro `CF_DATA_CURRENT` gives the easy handle of the current
+ * invocation.
+ */
+struct cf_call_data {
+ struct Curl_easy *data;
+#ifdef DEBUGBUILD
+ int depth;
+#endif
+};
+
+/**
+ * define to access the `struct cf_call_data for a cfilter. Normally
+ * a member in the cfilter's `ctx`.
+ *
+ * #define CF_CTX_CALL_DATA(cf) -> struct cf_call_data instance
+*/
+
+#ifdef DEBUGBUILD
+
+#define CF_DATA_SAVE(save, cf, data) \
+ do { \
+ (save) = CF_CTX_CALL_DATA(cf); \
+ DEBUGASSERT((save).data == NULL || (save).depth > 0); \
+ CF_CTX_CALL_DATA(cf).depth++; \
+ CF_CTX_CALL_DATA(cf).data = (struct Curl_easy *)data; \
+ } while(0)
+
+#define CF_DATA_RESTORE(cf, save) \
+ do { \
+ DEBUGASSERT(CF_CTX_CALL_DATA(cf).depth == (save).depth + 1); \
+ DEBUGASSERT((save).data == NULL || (save).depth > 0); \
+ CF_CTX_CALL_DATA(cf) = (save); \
+ } while(0)
+
+#else /* DEBUGBUILD */
+
+#define CF_DATA_SAVE(save, cf, data) \
+ do { \
+ (save) = CF_CTX_CALL_DATA(cf); \
+ CF_CTX_CALL_DATA(cf).data = (struct Curl_easy *)data; \
+ } while(0)
+
+#define CF_DATA_RESTORE(cf, save) \
+ do { \
+ CF_CTX_CALL_DATA(cf) = (save); \
+ } while(0)
+
+#endif /* !DEBUGBUILD */
+
+#define CF_DATA_CURRENT(cf) \
+ ((cf)? (CF_CTX_CALL_DATA(cf).data) : NULL)
+
+#endif /* HEADER_CURL_CFILTERS_H */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/config-amigaos.h b/iotdb-client/odbc/deps/curl-src/lib/config-amigaos.h
new file mode 100644
index 0000000000000..8f4d3e6c31ae6
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/config-amigaos.h
@@ -0,0 +1,130 @@
+#ifndef HEADER_CURL_CONFIG_AMIGAOS_H
+#define HEADER_CURL_CONFIG_AMIGAOS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/* Hand crafted config file for AmigaOS */
+/* ================================================================ */
+
+#ifdef __AMIGA__ /* Any AmigaOS flavour */
+
+#define HAVE_ARPA_INET_H 1
+#define HAVE_CLOSESOCKET_CAMEL 1
+#define HAVE_INTTYPES_H 1
+#define HAVE_IOCTLSOCKET_CAMEL 1
+#define HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1
+#define HAVE_LONGLONG 1
+#define HAVE_NETDB_H 1
+#define HAVE_NETINET_IN_H 1
+#define HAVE_NET_IF_H 1
+#define HAVE_PWD_H 1
+#define HAVE_SELECT 1
+#define HAVE_SIGNAL 1
+#define HAVE_SOCKET 1
+#define HAVE_STRCASECMP 1
+#define HAVE_STRDUP 1
+#define HAVE_STRICMP 1
+#define HAVE_STRINGS_H 1
+#define HAVE_STRUCT_TIMEVAL 1
+#define HAVE_SYS_PARAM_H 1
+#define HAVE_SYS_SOCKET_H 1
+#define HAVE_SYS_SOCKIO_H 1
+#define HAVE_SYS_STAT_H 1
+#define HAVE_SYS_TIME_H 1
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_UNISTD_H 1
+#define HAVE_UTIME 1
+#define HAVE_UTIME_H 1
+#define HAVE_WRITABLE_ARGV 1
+#define HAVE_SYS_IOCTL_H 1
+
+#define NEED_MALLOC_H 1
+
+#define SIZEOF_INT 4
+#define SIZEOF_SIZE_T 4
+
+#ifndef SIZEOF_CURL_OFF_T
+#define SIZEOF_CURL_OFF_T 8
+#endif
+
+#define USE_MANUAL 1
+#define CURL_DISABLE_LDAP 1
+
+#ifndef OS
+#define OS "AmigaOS"
+#endif
+
+#define PACKAGE "curl"
+#define PACKAGE_BUGREPORT "a suitable mailing list: https://curl.se/mail/"
+#define PACKAGE_NAME "curl"
+#define PACKAGE_STRING "curl -"
+#define PACKAGE_TARNAME "curl"
+#define PACKAGE_VERSION "-"
+
+#if defined(USE_AMISSL)
+#define CURL_CA_PATH "AmiSSL:Certs"
+#elif defined(__MORPHOS__)
+#define CURL_CA_BUNDLE "MOSSYS:Data/SSL/curl-ca-bundle.crt"
+#else
+#define CURL_CA_BUNDLE "s:curl-ca-bundle.crt"
+#endif
+
+#define STDC_HEADERS 1
+
+#define in_addr_t int
+
+#ifndef F_OK
+# define F_OK 0
+#endif
+
+#ifndef O_RDONLY
+# define O_RDONLY 0x0000
+#endif
+
+#ifndef LONG_MAX
+# define LONG_MAX 0x7fffffffL
+#endif
+
+#ifndef LONG_MIN
+# define LONG_MIN (-0x7fffffffL-1)
+#endif
+
+#define HAVE_RECV 1
+#define RECV_TYPE_ARG1 long
+#define RECV_TYPE_ARG2 char *
+#define RECV_TYPE_ARG3 long
+#define RECV_TYPE_ARG4 long
+#define RECV_TYPE_RETV long
+
+#define HAVE_SEND 1
+#define SEND_TYPE_ARG1 int
+#define SEND_QUAL_ARG2 const
+#define SEND_TYPE_ARG2 char *
+#define SEND_TYPE_ARG3 int
+#define SEND_TYPE_ARG4 int
+#define SEND_TYPE_RETV int
+
+#endif /* __AMIGA__ */
+#endif /* HEADER_CURL_CONFIG_AMIGAOS_H */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/config-dos.h b/iotdb-client/odbc/deps/curl-src/lib/config-dos.h
new file mode 100644
index 0000000000000..550c410a12968
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/config-dos.h
@@ -0,0 +1,139 @@
+#ifndef HEADER_CURL_CONFIG_DOS_H
+#define HEADER_CURL_CONFIG_DOS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+
+/* ================================================================ */
+/* lib/config-dos.h - Hand crafted config file for DOS */
+/* ================================================================ */
+
+#ifndef OS
+#if defined(DJGPP)
+ #define OS "MSDOS/djgpp"
+#elif defined(__HIGHC__)
+ #define OS "MSDOS/HighC"
+#else
+ #define OS "MSDOS/?"
+#endif
+#endif
+
+#define PACKAGE "curl"
+
+#define USE_MANUAL 1
+
+#define HAVE_ARPA_INET_H 1
+#define HAVE_FCNTL_H 1
+#define HAVE_FREEADDRINFO 1
+#define HAVE_GETADDRINFO 1
+#define HAVE_GETTIMEOFDAY 1
+#define HAVE_IO_H 1
+#define HAVE_IOCTL_FIONBIO 1
+#define HAVE_IOCTLSOCKET 1
+#define HAVE_IOCTLSOCKET_FIONBIO 1
+#define HAVE_LOCALE_H 1
+#define HAVE_LONGLONG 1
+#define HAVE_NETDB_H 1
+#define HAVE_NETINET_IN_H 1
+#define HAVE_NETINET_TCP_H 1
+#define HAVE_NET_IF_H 1
+#define HAVE_RECV 1
+#define HAVE_SELECT 1
+#define HAVE_SEND 1
+#define HAVE_SETLOCALE 1
+#define HAVE_SETMODE 1
+#define HAVE_SIGNAL 1
+#define HAVE_SOCKET 1
+#define HAVE_STRDUP 1
+#define HAVE_STRICMP 1
+#define HAVE_STRTOLL 1
+#define HAVE_STRUCT_TIMEVAL 1
+#define HAVE_SYS_IOCTL_H 1
+#define HAVE_SYS_SOCKET_H 1
+#define HAVE_SYS_STAT_H 1
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_UNISTD_H 1
+
+#define NEED_MALLOC_H 1
+
+#define SIZEOF_INT 4
+#define SIZEOF_LONG 4
+#define SIZEOF_SIZE_T 4
+#define SIZEOF_CURL_OFF_T 8
+#define STDC_HEADERS 1
+
+/* Qualifiers for send() and recv() */
+
+#define SEND_TYPE_ARG1 int
+#define SEND_QUAL_ARG2 const
+#define SEND_TYPE_ARG2 void *
+#define SEND_TYPE_ARG3 int
+#define SEND_TYPE_ARG4 int
+#define SEND_TYPE_RETV int
+
+#define RECV_TYPE_ARG1 int
+#define RECV_TYPE_ARG2 void *
+#define RECV_TYPE_ARG3 int
+#define RECV_TYPE_ARG4 int
+#define RECV_TYPE_RETV int
+
+#define BSD
+
+/* CURLDEBUG definition enables memory tracking */
+/* #define CURLDEBUG */
+
+/* to disable LDAP */
+#define CURL_DISABLE_LDAP 1
+
+#define in_addr_t u_long
+
+#if defined(__HIGHC__) || \
+ (defined(__GNUC__) && (__GNUC__ < 4))
+ #define ssize_t int
+#endif
+
+/* Target HAVE_x section */
+
+#if defined(DJGPP)
+ #define HAVE_BASENAME 1
+ #define HAVE_STRCASECMP 1
+ #define HAVE_SIGACTION 1
+ #define HAVE_SIGSETJMP 1
+ #define HAVE_SYS_TIME_H 1
+ #define HAVE_TERMIOS_H 1
+ #define HAVE_VARIADIC_MACROS_GCC 1
+
+#elif defined(__HIGHC__)
+ #define HAVE_SYS_TIME_H 1
+ #define strerror(e) strerror_s_((e))
+#endif
+
+#ifdef MSDOS /* Watt-32 */
+ #define HAVE_CLOSE_S 1
+#endif
+
+#undef word
+#undef byte
+
+#endif /* HEADER_CURL_CONFIG_DOS_H */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/config-mac.h b/iotdb-client/odbc/deps/curl-src/lib/config-mac.h
new file mode 100644
index 0000000000000..c29888f8f7eea
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/config-mac.h
@@ -0,0 +1,103 @@
+#ifndef HEADER_CURL_CONFIG_MAC_H
+#define HEADER_CURL_CONFIG_MAC_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+/* =================================================================== */
+/* Hand crafted config file for Mac OS 9 */
+/* =================================================================== */
+/* On Mac OS X you must run configure to generate curl_config.h file */
+/* =================================================================== */
+
+#ifndef OS
+#define OS "mac"
+#endif
+
+#include
+#if TYPE_LONGLONG
+#define HAVE_LONGLONG 1
+#endif
+
+/* Define if you want the built-in manual */
+#define USE_MANUAL 1
+
+#define HAVE_NETINET_IN_H 1
+#define HAVE_SYS_SOCKET_H 1
+#define HAVE_NETDB_H 1
+#define HAVE_ARPA_INET_H 1
+#define HAVE_UNISTD_H 1
+#define HAVE_NET_IF_H 1
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_GETTIMEOFDAY 1
+#define HAVE_FCNTL_H 1
+#define HAVE_SYS_STAT_H 1
+#define HAVE_UTIME_H 1
+#define HAVE_SYS_TIME_H 1
+#define HAVE_SYS_UTIME_H 1
+#define HAVE_SYS_IOCTL_H 1
+#define HAVE_ALARM 1
+#define HAVE_FTRUNCATE 1
+#define HAVE_UTIME 1
+#define HAVE_SELECT 1
+#define HAVE_SOCKET 1
+#define HAVE_STRUCT_TIMEVAL 1
+
+#define HAVE_SIGACTION 1
+
+#ifdef MACOS_SSL_SUPPORT
+# define USE_OPENSSL 1
+#endif
+
+#define CURL_DISABLE_LDAP 1
+
+#define HAVE_IOCTL_FIONBIO 1
+
+#define SIZEOF_INT 4
+#define SIZEOF_LONG 4
+#define SIZEOF_SIZE_T 4
+#ifdef HAVE_LONGLONG
+#define SIZEOF_CURL_OFF_T 8
+#else
+#define SIZEOF_CURL_OFF_T 4
+#endif
+
+#define HAVE_RECV 1
+#define RECV_TYPE_ARG1 int
+#define RECV_TYPE_ARG2 void *
+#define RECV_TYPE_ARG3 size_t
+#define RECV_TYPE_ARG4 int
+#define RECV_TYPE_RETV ssize_t
+
+#define HAVE_SEND 1
+#define SEND_TYPE_ARG1 int
+#define SEND_QUAL_ARG2 const
+#define SEND_TYPE_ARG2 void *
+#define SEND_TYPE_ARG3 size_t
+#define SEND_TYPE_ARG4 int
+#define SEND_TYPE_RETV ssize_t
+
+#define HAVE_EXTRA_STRICMP_H 1
+#define HAVE_EXTRA_STRDUP_H 1
+
+#endif /* HEADER_CURL_CONFIG_MAC_H */
diff --git a/iotdb-client/odbc/deps/curl-src/lib/config-os400.h b/iotdb-client/odbc/deps/curl-src/lib/config-os400.h
new file mode 100644
index 0000000000000..e9a62886306be
--- /dev/null
+++ b/iotdb-client/odbc/deps/curl-src/lib/config-os400.h
@@ -0,0 +1,346 @@
+#ifndef HEADER_CURL_CONFIG_OS400_H
+#define HEADER_CURL_CONFIG_OS400_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.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.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/* Hand crafted config file for OS/400 */
+/* ================================================================ */
+
+#pragma enum(int)
+
+#undef PACKAGE
+
+/* Version number of this archive. */
+#undef VERSION
+
+/* Define cpu-machine-OS */
+#ifndef OS
+#define OS "OS/400"
+#endif
+
+/* OS400 supports a 3-argument ASCII version of gethostbyaddr_r(), but its
+ * prototype is incompatible with the "standard" one (1st argument is not
+ * const). However, getaddrinfo() is supported (ASCII version defined as
+ * a local wrapper in setup-os400.h) in a threadsafe way: we can then
+ * configure getaddrinfo() as such and get rid of gethostbyname_r() without
+ * loss of threadsafeness. */
+#undef HAVE_GETHOSTBYNAME_R
+#undef HAVE_GETHOSTBYNAME_R_3
+#undef HAVE_GETHOSTBYNAME_R_5
+#undef HAVE_GETHOSTBYNAME_R_6
+#define HAVE_GETADDRINFO
+#define HAVE_GETADDRINFO_THREADSAFE
+
+/* Define if you need the _REENTRANT define for some functions */
+#undef NEED_REENTRANT
+
+/* Define if you want to enable IPv6 support */
+#define ENABLE_IPV6
+
+/* Define if struct sockaddr_in6 has the sin6_scope_id member */
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+
+/* Define this to 'int' if ssize_t is not an available typedefed type */
+#undef ssize_t
+
+/* Define this as a suitable file to read random data from */
+#undef RANDOM_FILE
+
+/* Define to 1 if you have the alarm function. */
+#define HAVE_ALARM 1
+
+/* Define if you have the header file. */
+#define HAVE_ARPA_INET_H
+
+/* Define if you have the `closesocket' function. */
+#undef HAVE_CLOSESOCKET
+
+/* Define if you have the header file. */
+#define HAVE_FCNTL_H
+
+/* Define if you have the `geteuid' function. */
+#define HAVE_GETEUID
+
+/* Define if you have the `gethostname' function. */
+#define HAVE_GETHOSTNAME
+
+/* Define if you have the `getpass_r' function. */
+#undef HAVE_GETPASS_R
+
+/* Define to 1 if you have the getpeername function. */
+#define HAVE_GETPEERNAME 1
+
+/* Define if you have the `getpwuid' function. */
+#define HAVE_GETPWUID
+
+/* Define to 1 if you have the getsockname function. */
+#define HAVE_GETSOCKNAME 1
+
+/* Define if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY
+
+/* Define if you have the `timeval' struct. */
+#define HAVE_STRUCT_TIMEVAL
+
+/* Define if you have the header file. */
+#define HAVE_INTTYPES_H
+
+/* Define if you have the header file. */
+#undef HAVE_IO_H
+
+/* Define if you have the `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* Define if you have GSS API. */
+#define HAVE_GSSAPI
+
+/* Define if you have the GNU gssapi libraries */
+#undef HAVE_GSSGNU
+
+/* Define if you have the Heimdal gssapi libraries */
+#define HAVE_GSSHEIMDAL
+
+/* Define if you have the MIT gssapi libraries */
+#undef HAVE_GSSMIT
+
+/* Define if you need the malloc.h header file even with stdlib.h */
+/* #define NEED_MALLOC_H 1 */
+
+/* Define if you have the header file. */
+#define HAVE_NETDB_H
+
+/* Define if you have the header file. */
+#define HAVE_NETINET_IN_H
+
+/* Define if you have the header file. */
+#define HAVE_NET_IF_H
+
+/* Define if you have the header file. */
+#define HAVE_PWD_H
+
+/* Define if you have the `select' function. */
+#define HAVE_SELECT
+
+/* Define if you have the `sigaction' function. */
+#define HAVE_SIGACTION
+
+/* Define if you have the `signal' function. */
+#undef HAVE_SIGNAL
+
+/* Define if you have the `socket' function. */
+#define HAVE_SOCKET
+
+/* Define if you have the header file. */
+#undef HAVE_STDINT_H
+
+
+/* The following define is needed on OS400 to enable strcmpi(), stricmp() and
+ strdup(). */
+#define __cplusplus__strings__
+
+/* Define if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the `strcmpi' function. */
+#define HAVE_STRCMPI
+
+/* Define if you have the `stricmp' function. */
+#define HAVE_STRICMP
+
+/* Define if you have the `strdup' function. */
+#define HAVE_STRDUP
+
+/* Define if you have the header file. */
+#define HAVE_STRINGS_H
+
+/* Define if you have the header file. */
+#undef HAVE_STROPTS_H
+
+/* Define if you have the `strtok_r' function. */
+#define HAVE_STRTOK_R
+
+/* Define if you have the `strtoll' function. */
+#undef HAVE_STRTOLL /* Allows ASCII compile on V5R1. */
+
+/* Define if you have the header file. */
+#define HAVE_SYS_PARAM_H
+
+/* Define if you have the header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define if you have the header file. */
+#define HAVE_SYS_SOCKET_H
+
+/* Define if you have the header file. */
+#undef HAVE_SYS_SOCKIO_H
+
+/* Define if you have the header file. */
+#define HAVE_SYS_STAT_H
+
+/* Define if you have the header file. */
+#define HAVE_SYS_TIME_H
+
+/* Define if you have the header file. */
+#define HAVE_SYS_TYPES_H
+
+/* Define if you have the header file. */
+#define HAVE_SYS_UN_H
+
+/* Define if you have the header file. */
+#define HAVE_SYS_IOCTL_H
+
+/* Define if you have the header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define if you have the header file. */
+#undef HAVE_TERMIO_H
+
+/* Define if you have the