diff --git a/vendor/curl/CMake/CurlTests.c b/vendor/curl/CMake/CurlTests.c index de2313080dd..410a0f70ce9 100644 --- a/vendor/curl/CMake/CurlTests.c +++ b/vendor/curl/CMake/CurlTests.c @@ -203,7 +203,7 @@ int main(void) #ifdef HAVE_UNISTD_H # include #endif -#ifdef HAVE_SYS_SOCKET_H +#ifndef _WIN32 # include #endif #ifdef HAVE_SYS_IOCTL_H @@ -230,7 +230,7 @@ int main(void) #ifdef HAVE_UNISTD_H # include #endif -#ifdef HAVE_SYS_SOCKET_H +#ifndef _WIN32 # include #endif #ifdef HAVE_SYS_IOCTL_H @@ -257,7 +257,7 @@ int main(void) #ifdef HAVE_SYS_TYPES_H # include #endif -#ifdef HAVE_SYS_SOCKET_H +#ifndef _WIN32 # include #endif int main(void) diff --git a/vendor/curl/RELEASE-NOTES b/vendor/curl/RELEASE-NOTES index 44078c66219..9aa5003d0aa 100644 --- a/vendor/curl/RELEASE-NOTES +++ b/vendor/curl/RELEASE-NOTES @@ -1,51 +1,193 @@ -curl and libcurl 8.14.1 +curl and libcurl 8.15.1 - Public curl releases: 268 - Command line options: 269 + Public curl releases: 270 + Command line options: 272 curl_easy_setopt() options: 308 - Public functions in libcurl: 96 - Contributors: 3431 + Public functions in libcurl: 97 + Contributors: 3486 This release includes the following changes: + o build: bump minimum required mingw-w64 to v3.0 (from v1.0) [33] + o curl: add --follow [129] + o curl: add --out-null [101] + o curl: add --parallel-max-host to limit concurrent connections per host [81] + o curl: make --retry-delay and --retry-max-time accept decimal seconds [112] + o hostip: cache negative name resolves [175] + o ip happy eyeballing: keep attempts running [80] + o multi: add curl_multi_get_offt [56] + o multi: add CURLMOPT_NETWORK_CHANGED to signal network changed [84] + o netrc: use the NETRC environment variable (first) if set [70] + o smtp: allow suffix behind a mail address for RFC 3461 [127] + o tls: make default TLS version be minimum 1.2 [71] + o tool_getparam: add support for `--longopt=value` [69] + o vquic: drop msh3 [8] + o writeout: add %time{} [74] This release includes the following bugfixes: - o asyn-thrdd: fix cleanup when RR fails due to OOM [20] - o autotools: recognize more Linux targets when setting `-D_GNU_SOURCE` [35] - o BUG-BOUNTY.md. mention the medium bounty amount in 2025 [5] - o cmake: fix missed version number for multi-pkg-config detections [14] - o cmdline-docs: mention HTTP resumed uploads to be shaky [21] - o curl: make -N handled correctly [34] - o curl: upload from '.' fix [9] - o dllmain: exclude from Cygwin builds [32] - o docs/tests: remove mention of hyper [23] - o docs: fix typos [12] - o ftp: fix teardown of DATA connection in done [31] - o http: fail early when rewind of input failed when following redirects [2] - o license: update some copyright links to curl.se [24] - o memanalyze.pl: fix getaddrinfo/freeaddrinfo checks [25] - o misc: fix spelling [15] - o misc: we write *an* IPv6 address [10] - o multi: fix add_handle resizing [3] - o spelling: 'a' vs 'an' [8] - o spelling: call it null-terminate consistently [6] - o test1510: fix expectation [19] - o tests: await portfile to be complete [1] - o tests: fix checks for https-mtls proto [30] - o tests: improve server start reliability [18] - o tests: move test docs into /docs [16] - o tests: re-enable 1510, document heimdal memleak [22] - o tests: test mtls also w/ clientAuth EKU only [28] - o tests: test mtls with --insecure [29] - o tls BIOs: handle BIO_CTRL_EOF correctly [33] - o tool_getparam: make --no-anyauth not be accepted [13] - o tool_getparam: refactored, simplified [4] - o tool_getparam: remove two nextarg NULL checks [11] - o VULN-DISCLOSURE-POLICY.md: the distros list wants <= 7 days embargo [26] - o wolfssl: fix sending of early data [7] - o ws: handle blocked sends better [27] - o ws: tests and fixes [17] + o _PROTOCOLS.md: mention file:// is only for absolute paths [102] + o alpn: query filter [104] + o ares: destroy channel on shutdown [178] + o BINDINGS.md: add LibQurl [156] + o bufq: add integer overflow checks before chunk allocations [108] + o build: allow libtests/clients to use libcurl dependencies directly [87] + o build: disable `TCP_NODELAY` for emscripten [176] + o build: enable _GNU_SOURCE on GNU/Hurd [27] + o build: extend GNU C guards to clang where applicable, fix fallouts [61] + o build: fix build errors/warnings in rare configurations [7] + o build: fix disable-verbose [48] + o build: fix mingw-w64 version guard for mingw32ce [124] + o build: if no perl, fix to use the pre-built hugehelp, if present [144] + o build: link to Apple frameworks required by static wolfSSL [40] + o build: tidy up compiler definition for tests [37] + o cf-https-connect: delete unused declaration [15] + o cmake: capitalize 'Rustls' in the config summary + o cmake: defer building `unitprotos.h` till a test target needs it [75] + o cmake: define `WIN32_LEAN_AND_MEAN` for examples [159] + o cmake: drop redundant unity mode for `curlinfo` [155] + o cmake: enable `-Wall` for MSVC 1944 [128] + o cmake: fix `ENABLE_UNIX_SOCKETS=OFF` with pre-fill enabled on unix + o cmake: fix to disable Schannel and SSPI for non-Windows targets + o cmake: fix to restrict `SystemConfiguration` to macOS [139] + o cmake: keep websockets disabled if HTTP is disabled + o cmake: make `runtests` targets build the curl tool [32] + o cmake: make the ExternalProject test work [183] + o cmake: omit linking duplicate/unnecessary libs to tests & examples [45] + o cmake: re-add simple test target, and name it `tests` [142] + o cmake: set `CURL_DIRSUFFIX` automatically in multi-config builds [154] + o CODE_STYLE: sync with recent `checksrc.pl` updates [49] + o config-win32.h: do not use winsock2 `inet_ntop()`/`inet_pton()` [58] + o configure: if no perl, disable unity and shell completion, related tidy ups [137] + o connectdata: remove primary+secondary ip_quadruple [126] + o connection: terminate after goaway [62] + o contrithanks: fix for BSD `sed` tool [98] + o curl-config: remove X prefix use [138] + o curl/system.h: fix for GCC 3.3.x and older [38] + o curl: make the URL indexes 64 bit [117] + o curl: tool_read_cb fix of segfault [18] + o curl_addrinfo: drop workaround for old-mingw [14] + o curl_easy_ssls_export: make the example more clear [78] + o curl_fnmatch, servers: drop local macros in favour of `sizeof()` [21] + o curl_mime_data_cb.md: mention what datasize is for [107] + o curl_ossl: extend callback table for nghttp3 1.11.0 [46] + o curl_setup.h: move UWP detection after `config-win32.h` (revert) [51] + o curl_setup.h: move UWP detection after `config-win32.h` [23] + o CURLOPT: bump `CURL_REDIR_*` macros to `long` [110] + o CURLOPT: bump `CURL_SSLVERSION_*` macros to `long` [149] + o CURLOPT: bump `CURLALTSVC_*` macros to `long` [96] + o CURLOPT: bump `CURLFTP*` enums to `long`, drop casts [54] + o CURLOPT: bump `CURLHEADER_*` macros to `long`, drop casts [94] + o CURLOPT: bump `CURLPROTO_*` macros to `long` [148] + o CURLOPT: bump `CURLPROXY_*` enums to `long`, drop casts [95] + o CURLOPT: bump `CURLWS_NOAUTOPONG`, `CURLWS_RAW_MODE` macros to `long` [150] + o CURLOPT: bump remaining macros to `long` [147] + o CURLOPT: drop redundant `long` casts [55] + o CURLOPT: replace `(long)` cast with `L` suffix for `CURLHSTS_*` macros + o delta: fix warnings, fix for non-GNU `date` tool [99] + o DEPRECATE.md: drop support for Windows XP/2003 [31] + o DEPRECATE.md: remove leftover "nothing" [57] + o DISTROS.md: add Haiku [39] + o docs/cmdline-opts: the auth types are not mutually exclusive [103] + o docs: add CURLOPT type change history, drop casts where present [143] + o docs: fix name in curl_easy_ssls_export man page [12] + o doh: rename symbols to avoid collision with mingw-w64 headers [66] + o easy handle: check validity on external calls [28] + o examples: drop long cast for `CURLALTSVC_*` + o gnutls: some small cleanups [41] + o hmac: return error if init fails [2] + o hostip: do DNS cache pruning in milliseconds [132] + o http: const up readonly H2_NON_FIELD [10] + o http: silence `-Warray-bounds` with gcc 13+ [44] + o inet_pton, inet_ntop: drop declarations when unused [59] + o lib1560: fix memory leak when run without UTF-8 support [17] + o lib1560: replace an `int` with `bool` [97] + o lib2700: use `testnum` [151] + o lib517: use `LL` 64-bit literals & re-enable a test case (`time_t`) [100] + o libcurl: reset rewind flag in curl_easy_reset() [184] + o libssh: Use sftp_aio instead of sftp_async for sftp_recv [92] + o libtests: update format strings to avoid casts, drop some macros [109] + o libtests: use `FMT_SOCKET_T`, drop more casts [136] + o managen: reset text mode at end of table marker [145] + o memanalyze: fix warnings [22] + o memory: make function overrides work reliably in unity builds [93] + o multi event: remove only announced [25] + o multi: don't insert a node into the splay tree twice [68] + o multi: fix assert in multi_getsock() [53] + o multi: fix bad splay management [133] + o multi: process pending, one by one [90] + o multi: replace remaining EXPIRE_RUN_NOW [67] + o multissl: initialize when requesting a random number [30] + o ngtcp2: extend callback tables for nghttp3 1.11.0 and ngtcp2 1.14.0 [47] + o openssl: check SSL_write() length on retries [152] + o openssl: clear errors after a failed `d2i_X509()` [161] + o openssl: output unescaped utf8 x509 issuer/subject DNs [169] + o openssl: some small cleanups [42] + o openssl: split cert_stuff into smaller sub functions [72] + o parallel-max: bump the max value to 65535 [86] + o pytest: add SOCKS tests and scoring [9] + o pytest: increase server KeepAliveTimeout [26] + o pytest: relax error check on test_07_22 [16] + o runtests: add `--ci` option, show `Env:` only when non-empty [134] + o schannel: add an error message for client cert not found [165] + o schannel: assume `CERT_CHAIN_REVOCATION_CHECK_CHAIN` [114] + o schannel: drop fallbacks for 4 macros [121] + o schannel: drop fallbacks for unused `BCRYPT_*` macros [122] + o schannel: drop old-mingw special case [77] + o schannel: fix recent update for mingw32ce [123] + o schannel: not supported with UWP, drop redundant code [105] + o schannel: use if(result) like the code style says [125] + o scripts: enable strict warnings in Perl where missing, fix fallouts [63] + o scripts: fix two Perl uninitialized value warnings [60] + o servers: convert two macros to scoped static const strings [89] + o setopt: refactor out the booleans from setopt_long to setopt_bool [83] + o setopt: split out cookielist() and cookiefile() [130] + o socks: do_SOCKS5: Fix invalid buffer content on short send [43] + o spacecheck.pl: when detecting unicode, mention line number [85] + o test1148: drop redundant `LC_NUMBER=` env setting [13] + o test1560: set locale/codeset with `LC_ALL` (was: `LANG`), test in CI [19] + o test1560: skip some URLs if UTF-8 is not supported [34] + o test1: raise alloc limits [11] + o test428: re-enable for Windows [5] + o test436: fix running on Windows with `_curlrc` present [153] + o tests/ech_tests.sh: indent, if/for style, inline ifs [131] + o tests: constify command-line arguments [82] + o tests: drop unused `CURL_FORCEHOST` envs [36] + o tests: fix perl warnings in http2-server, http3-server [119] + o tests: fix prechecks to call the bundle libtest tool [120] + o tests: fix UTF-8 detection, per-test `LC_*` settings, CI coverage [6] + o tests: merge clients into libtests, drop duplicate code [76] + o tests: set `CURL_ENTROPY` per test, not globally [35] + o tests: unset some envs instead of blanking them [4] + o tidy-up: `Curl_thread_create()` callback return type [20] + o tidy-up: move literal to the right side of comparisons [65] + o tidy-up: prefer `ifdef`/`ifndef` for single checks [64] + o tls: CURLINFO_TLS_SSL_PTR testing [79] + o tool_cb_wrt: stop alloc/free for every chunk windows console output [140] + o tool_operate: avoid superfluous strdup'ing output [1] + o tool_operate: use the correct config pointer [115] + o tool_paramhlp: fix secs2ms() [116] + o tool_parsecfg: use dynbuf for quoted arguments [162] + o tool_urlglob: polish, cleanups, improvements [141] + o unit-tests: build the unitprotos.h from here [73] + o unit2604: avoid `UNCONST()` [135] + o urlapi: allow more path characters "raw" when asked to URL encode [146] + o urldata: reduce two long struct fields to unsigned short [174] + o vquic-tls: fix SSL backend type for QUIC connections using gnutls [29] + o vquic: use curl_getenv [168] + o vtls: set seen http version on successful ALPN [160] + o windows: assume `ADDRESS_FAMILY`, drop feature checks [88] + o windows: document toolchain support for `CERT_NAME_SEARCH_ALL_NAMES_FLAG` + o windows: document toolchain support for some macros (cont.) [111] + o windows: document toolchain support for some macros [113] + o windows: drop `CRYPT_E_*` macro fallbacks, limit one to mingw32ce [118] + o windows: drop two interim, single-use macros [106] + o windows: drop unused `curlx/version_win32.h` includes [52] + o windows: fix `if_nametoindex()` detection with autotools, improve with cmake [24] + o windows: include `wincrypt.h` before `iphlpapi.h` for mingw-w64 <6 [50] + o windows: target version macro tidy-ups [3] + o wolfssl: rename ML-KEM hybrids to match IETF draft [173] + o ws: avoid NULL pointer deref in curl_ws_recv [91] This release includes the following known bugs: @@ -57,9 +199,7 @@ For all changes ever done in curl: Planned upcoming removals include: - o Support for the msh3 HTTP/3 backend o Supporting curl builds using VS2008 - o The Secure Transport and BearSSL TLS backends o The winbuild build system o Windows CE support @@ -68,47 +208,188 @@ Planned upcoming removals include: This release would not have looked like this without help, code, reports and advice from friends like these: - Calvin Ruocco, Dan Fandrich, Daniel Stenberg, denandz on github, - Ethan Everett, Jacob Mealey, Jeremy Drake, Jeroen Ooms, John Bampton, - Kadambini Nema, Michael Kaufmann, Rasmus Melchior Jacobsen, Ray Satiro, - Samuel Henrique, Stefan Eissing, Viktor Szakats, x-xiang on github, - Yedaya Katsman, Yuyi Wang, z2_ - (20 contributors) + adamse on github, Ahmad Gani, Alice Lee Poetics, Ammar Faizi, Anthony Hu, + Berthin Torres Callañaupa, Caolán McNamara, Cole Leavitt, d1r3ct0r, + Dan Fandrich, Daniel Böhmer, Daniel Stenberg, David Zhuang, devgs on github, + Dominik Tomecki, Eshan Kelkar, Harry Sintonen, IoannisGS on github, + Jeroen Ooms, Kai Pastor, Karthik Das, kkmuffme on github, + letshack9707 on hackerone, lf- on github, LoRd_MuldeR, Michał Petryka, + nevakrien on github, Oxan van Leeuwen, Paul Gilmartin, Petar Popovic, + Philippe Antoine, Pino Toscano, Qriist, Qriist on github, Ray Satiro, + renovate[bot], rm-rmonaghan on github, Roberto Hidalgo, Schrijvers Luc, + Sergio Durigan Junior, Stefan Eissing, Tal Regev, Todd Gamblin, + Viktor Szakats, Waldemar Kornewald, yaoy6 on github, ウさん + (47 contributors) References to bug reports and discussions on issues: - [1] = https://curl.se/bug/?i=17492 - [2] = https://curl.se/bug/?i=17472 - [3] = https://curl.se/bug/?i=17473 - [4] = https://curl.se/bug/?i=17448 - [5] = https://curl.se/bug/?i=17470 - [6] = https://curl.se/bug/?i=17489 - [7] = https://curl.se/bug/?i=17481 - [8] = https://curl.se/bug/?i=17487 - [9] = https://curl.se/bug/?i=17513 - [10] = https://curl.se/bug/?i=17484 - [11] = https://curl.se/bug/?i=17483 - [12] = https://curl.se/bug/?i=17480 - [13] = https://curl.se/bug/?i=17508 - [14] = https://curl.se/bug/?i=16980 - [15] = https://curl.se/bug/?i=17478 - [16] = https://curl.se/bug/?i=17463 - [17] = https://curl.se/bug/?i=17136 - [18] = https://curl.se/bug/?i=17516 - [19] = https://curl.se/bug/?i=17515 - [20] = https://curl.se/bug/?i=17507 - [21] = https://curl.se/bug/?i=17521 - [22] = https://curl.se/bug/?i=17462 - [23] = https://curl.se/bug/?i=17500 - [24] = https://curl.se/bug/?i=17502 - [25] = https://curl.se/bug/?i=17503 - [26] = https://curl.se/bug/?i=17497 - [27] = https://curl.se/bug/?i=17496 - [28] = https://curl.se/bug/?i=17493 - [29] = https://curl.se/bug/?i=17493 - [30] = https://curl.se/bug/?i=17493 - [31] = https://curl.se/bug/?i=17482 - [32] = https://curl.se/bug/?i=17262 - [33] = https://curl.se/bug/?i=17471 - [34] = https://curl.se/bug/?i=17527 - [35] = https://curl.se/bug/?i=17512 + [1] = https://curl.se/bug/?i=17946 + [2] = https://curl.se/bug/?i=18008 + [3] = https://curl.se/bug/?i=17981 + [4] = https://curl.se/bug/?i=17994 + [5] = https://curl.se/bug/?i=17991 + [6] = https://curl.se/bug/?i=17988 + [7] = https://curl.se/bug/?i=17962 + [8] = https://curl.se/bug/?i=17729 + [9] = https://curl.se/bug/?i=17986 + [10] = https://curl.se/bug/?i=17996 + [11] = https://curl.se/bug/?i=18004 + [12] = https://curl.se/bug/?i=17995 + [13] = https://curl.se/bug/?i=17993 + [14] = https://curl.se/bug/?i=18038 + [15] = https://curl.se/bug/?i=18036 + [16] = https://curl.se/bug/?i=18050 + [17] = https://curl.se/bug/?i=17998 + [18] = https://curl.se/bug/?i=17978 + [19] = https://curl.se/bug/?i=17938 + [20] = https://curl.se/bug/?i=17889 + [21] = https://curl.se/bug/?i=17898 + [22] = https://curl.se/bug/?i=18049 + [23] = https://curl.se/bug/?i=17980 + [24] = https://curl.se/bug/?i=17982 + [25] = https://curl.se/bug/?i=17949 + [26] = https://curl.se/bug/?i=17968 + [27] = https://curl.se/bug/?i=17975 + [28] = https://curl.se/bug/?i=17958 + [29] = https://curl.se/bug/?i=17976 + [30] = https://curl.se/bug/?i=17963 + [31] = https://curl.se/bug/?i=18016 + [32] = https://curl.se/bug/?i=17967 + [33] = https://curl.se/bug/?i=17984 + [34] = https://curl.se/bug/?i=17933 + [35] = https://curl.se/bug/?i=17971 + [36] = https://curl.se/bug/?i=17972 + [37] = https://curl.se/bug/?i=17768 + [38] = https://curl.se/bug/?i=17951 + [39] = https://curl.se/bug/?i=17953 + [40] = https://github.com/microsoft/vcpkg/pull/46444#pullrequestreview-3026575393 + [41] = https://curl.se/bug/?i=17941 + [42] = https://curl.se/bug/?i=17940 + [43] = https://curl.se/bug/?i=17942 + [44] = https://curl.se/bug/?i=18030 + [45] = https://curl.se/bug/?i=17696 + [46] = https://curl.se/bug/?i=18026 + [47] = https://curl.se/bug/?i=18019 + [48] = https://curl.se/bug/?i=18053 + [49] = https://curl.se/bug/?i=18015 + [50] = https://curl.se/bug/?i=18012 + [51] = https://curl.se/bug/?i=18014 + [52] = https://curl.se/bug/?i=18011 + [53] = https://curl.se/bug/?i=18046 + [54] = https://curl.se/bug/?i=17797 + [55] = https://curl.se/bug/?i=17791 + [56] = https://curl.se/bug/?i=17992 + [57] = https://curl.se/bug/?i=18044 + [58] = https://curl.se/bug/?i=18045 + [59] = https://curl.se/bug/?i=18043 + [60] = https://curl.se/bug/?i=18047 + [61] = https://curl.se/bug/?i=17955 + [62] = https://curl.se/bug/?i=17884 + [63] = https://curl.se/bug/?i=17877 + [64] = https://curl.se/bug/?i=18018 + [65] = https://curl.se/bug/?i=17876 + [66] = https://curl.se/bug/?i=18041 + [67] = https://curl.se/bug/?i=17883 + [68] = https://curl.se/bug/?i=18005 + [69] = https://curl.se/bug/?i=17789 + [70] = https://curl.se/bug/?i=17712 + [71] = https://curl.se/bug/?i=17894 + [72] = https://curl.se/bug/?i=18081 + [73] = https://curl.se/bug/?i=18088 + [74] = https://curl.se/bug/?i=18119 + [75] = https://curl.se/bug/?i=18086 + [76] = https://curl.se/bug/?i=18079 + [77] = https://curl.se/bug/?i=18084 + [78] = https://curl.se/bug/?i=18117 + [79] = https://curl.se/bug/?i=18066 + [80] = https://curl.se/bug/?i=18105 + [81] = https://curl.se/bug/?i=18052 + [82] = https://curl.se/bug/?i=18076 + [83] = https://curl.se/bug/?i=17887 + [84] = https://curl.se/bug/?i=17225 + [85] = https://curl.se/bug/?i=18120 + [86] = https://curl.se/bug/?i=18068 + [87] = https://curl.se/bug/?i=18069 + [88] = https://curl.se/bug/?i=18057 + [89] = https://curl.se/bug/?i=18067 + [90] = https://curl.se/bug/?i=18017 + [91] = https://curl.se/bug/?i=18065 + [92] = https://curl.se/bug/?i=17440 + [93] = https://curl.se/bug/?i=17827 + [94] = https://curl.se/bug/?i=18055 + [95] = https://curl.se/bug/?i=18054 + [96] = https://curl.se/bug/?i=18063 + [97] = https://curl.se/bug/?i=18064 + [98] = https://curl.se/bug/?i=18062 + [99] = https://curl.se/bug/?i=18061 + [100] = https://curl.se/bug/?i=18032 + [101] = https://curl.se/bug/?i=17800 + [102] = https://curl.se/bug/?i=18060 + [103] = https://curl.se/bug/?i=18059 + [104] = https://curl.se/bug/?i=17947 + [105] = https://curl.se/bug/?i=18116 + [106] = https://curl.se/bug/?i=18114 + [107] = https://curl.se/bug/?i=18115 + [108] = https://curl.se/bug/?i=18112 + [109] = https://curl.se/bug/?i=18106 + [110] = https://curl.se/bug/?i=18110 + [111] = https://curl.se/bug/?i=18113 + [112] = https://curl.se/bug/?i=18109 + [113] = https://curl.se/bug/?i=18085 + [114] = https://curl.se/bug/?i=18108 + [115] = https://curl.se/bug/?i=18200 + [116] = https://curl.se/bug/?i=18167 + [117] = https://curl.se/bug/?i=18096 + [118] = https://curl.se/bug/?i=18092 + [119] = https://curl.se/bug/?i=18100 + [120] = https://curl.se/bug/?i=18099 + [121] = https://curl.se/bug/?i=18093 + [122] = https://curl.se/bug/?i=18091 + [123] = https://curl.se/bug/?i=18097 + [124] = https://curl.se/bug/?i=18095 + [125] = https://curl.se/bug/?i=18094 + [126] = https://curl.se/bug/?i=17960 + [127] = https://curl.se/bug/?i=16643 + [128] = https://curl.se/bug/?i=18165 + [129] = https://curl.se/bug/?i=16543 + [130] = https://curl.se/bug/?i=18162 + [131] = https://curl.se/bug/?i=18187 + [132] = https://curl.se/bug/?i=18160 + [133] = https://curl.se/bug/?i=18201 + [134] = https://curl.se/bug/?i=18147 + [135] = https://curl.se/bug/?i=18143 + [136] = https://curl.se/bug/?i=18142 + [137] = https://curl.se/bug/?i=18141 + [138] = https://curl.se/bug/?i=18158 + [139] = https://curl.se/bug/?i=18149 + [140] = https://curl.se/bug/?i=18233 + [141] = https://curl.se/bug/?i=18198 + [142] = https://curl.se/bug/?i=18145 + [143] = https://curl.se/bug/?i=18130 + [144] = https://curl.se/bug/?i=18118 + [145] = https://curl.se/bug/?i=18139 + [146] = https://curl.se/bug/?i=17977 + [147] = https://curl.se/bug/?i=18134 + [148] = https://curl.se/bug/?i=18136 + [149] = https://curl.se/bug/?i=18135 + [150] = https://curl.se/bug/?i=18137 + [151] = https://curl.se/bug/?i=18138 + [152] = https://curl.se/bug/?i=18121 + [153] = https://curl.se/bug/?i=18242 + [154] = https://curl.se/bug/?i=18241 + [155] = https://curl.se/bug/?i=18238 + [156] = https://curl.se/bug/?i=18195 + [159] = https://curl.se/bug/?i=18232 + [160] = https://curl.se/bug/?i=18177 + [161] = https://curl.se/bug/?i=18190 + [162] = https://curl.se/bug/?i=18230 + [165] = https://curl.se/bug/?i=18124 + [168] = https://curl.se/bug/?i=18170 + [169] = https://curl.se/bug/?i=18171 + [173] = https://curl.se/bug/?i=18123 + [174] = https://curl.se/bug/?i=18173 + [175] = https://curl.se/bug/?i=18157 + [176] = https://curl.se/bug/?i=17974 + [178] = https://curl.se/bug/?i=18216 + [183] = https://curl.se/bug/?i=18208 + [184] = https://curl.se/bug/?i=18206 diff --git a/vendor/curl/docs/.gitignore b/vendor/curl/docs/.gitignore new file mode 100644 index 00000000000..31ca7656e95 --- /dev/null +++ b/vendor/curl/docs/.gitignore @@ -0,0 +1,7 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +*.1 +*.3 +RELEASE-TOOLS.md.dist diff --git a/vendor/curl/docs/cmdline-opts/.gitignore b/vendor/curl/docs/cmdline-opts/.gitignore new file mode 100644 index 00000000000..8d42e2c53d5 --- /dev/null +++ b/vendor/curl/docs/cmdline-opts/.gitignore @@ -0,0 +1,5 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +curl.txt diff --git a/vendor/curl/docs/examples/.gitignore b/vendor/curl/docs/examples/.gitignore new file mode 100644 index 00000000000..4b78bd78dd0 --- /dev/null +++ b/vendor/curl/docs/examples/.gitignore @@ -0,0 +1,134 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +10-at-a-time +address-scope +altsvc +anyauthput +block_ip +cacertinmem +certinfo +chkspeed +connect-to +cookie_interface +crawler +debug +default-scheme +ephiperfifo +evhiperfifo +externalsocket +fileupload +ftp-delete +ftp-wildcard +ftpget +ftpgetinfo +ftpgetresp +ftpsget +ftpupload +ftpuploadfrommem +ftpuploadresume +getinfo +getinmemory +getredirect +getreferrer +ghiper +headerapi +hiperfifo +href_extractor +hsts-preload +htmltidy +http-options +http-post +http2-download +http2-pushinmemory +http2-serverpush +http2-upload +http3 +http3-present +httpcustomheader +httpput +httpput-postfields +https +imap-append +imap-authzid +imap-copy +imap-create +imap-delete +imap-examine +imap-fetch +imap-list +imap-lsub +imap-multi +imap-noop +imap-search +imap-ssl +imap-store +imap-tls +interface +ipv6 +keepalive +localport +maxconnects +multi-app +multi-debugcallback +multi-double +multi-event +multi-formadd +multi-legacy +multi-post +multi-single +multi-uv +multithread +netrc +parseurl +persistent +pop3-authzid +pop3-dele +pop3-list +pop3-multi +pop3-noop +pop3-retr +pop3-ssl +pop3-stat +pop3-tls +pop3-top +pop3-uidl +post-callback +postinmemory +postit2 +postit2-formadd +progressfunc +protofeats +range +resolve +rtsp-options +sendrecv +sepheaders +sessioninfo +sftpget +sftpuploadresume +shared-connection-cache +simple +simplepost +simplessl +smooth-gtk-thread +smtp-authzid +smtp-expn +smtp-mail +smtp-mime +smtp-multi +smtp-ssl +smtp-tls +smtp-vrfy +sslbackend +synctime +threaded-ssl +unixsocket +url2file +urlapi +usercertinmem +websocket +websocket-cb +websocket-updown +xmlstream diff --git a/vendor/curl/docs/examples/altsvc.c b/vendor/curl/docs/examples/altsvc.c index 2f70d05e1ab..8a1ae8ed3b4 100644 --- a/vendor/curl/docs/examples/altsvc.c +++ b/vendor/curl/docs/examples/altsvc.c @@ -41,8 +41,8 @@ int main(void) curl_easy_setopt(curl, CURLOPT_ALTSVC, "altsvc.txt"); /* restrict which HTTP versions to use alternatives */ - curl_easy_setopt(curl, CURLOPT_ALTSVC_CTRL, (long) - CURLALTSVC_H1|CURLALTSVC_H2|CURLALTSVC_H3); + curl_easy_setopt(curl, CURLOPT_ALTSVC_CTRL, + CURLALTSVC_H1 | CURLALTSVC_H2 | CURLALTSVC_H3); /* Perform the request, res gets the return code */ res = curl_easy_perform(curl); diff --git a/vendor/curl/docs/examples/anyauthput.c b/vendor/curl/docs/examples/anyauthput.c index 550c827693f..c62250dce37 100644 --- a/vendor/curl/docs/examples/anyauthput.c +++ b/vendor/curl/docs/examples/anyauthput.c @@ -61,7 +61,7 @@ static int my_seek(void *userp, curl_off_t offset, int origin) { FILE *fp = (FILE *) userp; - if(-1 == fseek(fp, (long) offset, origin)) + if(fseek(fp, (long) offset, origin) == -1) /* could not seek */ return CURL_SEEKFUNC_CANTSEEK; @@ -142,7 +142,7 @@ int main(int argc, char **argv) /* tell libcurl we can use "any" auth, which lets the lib pick one, but it also costs one extra round-trip and possibly sending of all the PUT data twice!!! */ - curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY); + curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); /* set user name and password for the authentication */ curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password"); diff --git a/vendor/curl/docs/examples/block_ip.c b/vendor/curl/docs/examples/block_ip.c index bff7b6353c3..a6609d3428b 100644 --- a/vendor/curl/docs/examples/block_ip.c +++ b/vendor/curl/docs/examples/block_ip.c @@ -155,7 +155,7 @@ static struct ip *ip_list_append(struct ip *list, const char *data) ip->maskbits = 128; #endif - if(1 != inet_pton(ip->family, ip->str, &ip->netaddr)) { + if(inet_pton(ip->family, ip->str, &ip->netaddr) != 1) { free(ip->str); free(ip); return NULL; diff --git a/vendor/curl/docs/examples/cacertinmem.c b/vendor/curl/docs/examples/cacertinmem.c index 94080c641ec..3a409dc5bd6 100644 --- a/vendor/curl/docs/examples/cacertinmem.c +++ b/vendor/curl/docs/examples/cacertinmem.c @@ -41,60 +41,39 @@ static size_t writefunction(void *ptr, size_t size, size_t nmemb, void *stream) return nmemb * size; } -static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm) +static CURLcode sslctx_function(CURL *curl, void *sslctx, void *pointer) { CURLcode rv = CURLE_ABORTED_BY_CALLBACK; /** This example uses two (fake) certificates **/ + /* replace the XXX with the actual CA certificates */ static const char mypem[] = "-----BEGIN CERTIFICATE-----\n" - "MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE\n" - "AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw\n" - "CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ\n" - "BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND\n" - "VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb\n" - "qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY\n" - "HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo\n" - "G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA\n" - "0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH\n" - "k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47\n" - "JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m\n" - "AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD\n" - "vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms\n" - "tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH\n" - "7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h\n" - "I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA\n" - "h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF\n" - "d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H\n" - "pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "-----END CERTIFICATE-----\n" "-----BEGIN CERTIFICATE-----\n" - "MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UE\n" - "AwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00x\n" - "CzAJBgNVBAYTAkVTMB4XDTA4MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEW\n" - "MBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZF\n" - "RElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC\n" - "AgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHkWLn7\n" - "09gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7\n" - "XBZXehuDYAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5P\n" - "gvoFNTPhNahXwOf9jU8/kzJPeGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKe\n" - "I6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1PwkzQSulgUV1qzOMPPKC8W64iLgpq0i\n" - "5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1ThCojz2GuHURwCRi\n" - "ipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oIKiMn\n" - "MCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZ\n" - "o5NjEFIqnxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6\n" - "zqylfDJKZ0DcMDQj3dcEI2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacN\n" - "GHk0vFQYXlPKNFHtRQrmjseCNj6nOGOpMCwXEGCSn1WHElkQwg9naRHMTh5+Spqt\n" - "r0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3otkYNbn5XOmeUwssfnHdK\n" - "Z05phkOTOPu220+DkdRgfks+KzgHVZhepA==\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "-----END CERTIFICATE-----\n"; BIO *cbio = BIO_new_mem_buf(mypem, sizeof(mypem)); X509_STORE *cts = SSL_CTX_get_cert_store((SSL_CTX *)sslctx); int i; STACK_OF(X509_INFO) *inf; - (void)curl; - (void)parm; + + (void)curl; /* avoid warnings */ + (void)pointer; /* avoid warnings */ if(!cts || !cbio) { return rv; diff --git a/vendor/curl/docs/examples/crawler.c b/vendor/curl/docs/examples/crawler.c index d2f89db9dcf..6b737652d40 100644 --- a/vendor/curl/docs/examples/crawler.c +++ b/vendor/curl/docs/examples/crawler.c @@ -55,15 +55,15 @@ static void sighandler(int dummy) } /* resizable buffer */ -typedef struct { +struct memory { char *buf; size_t size; -} memory; +}; static size_t grow_buffer(void *contents, size_t sz, size_t nmemb, void *ctx) { size_t realsize = sz * nmemb; - memory *mem = (memory*) ctx; + struct memory *mem = (struct memory*) ctx; char *ptr = realloc(mem->buf, mem->size + realsize); if(!ptr) { /* out of memory */ @@ -79,14 +79,14 @@ static size_t grow_buffer(void *contents, size_t sz, size_t nmemb, void *ctx) static CURL *make_handle(const char *url) { CURL *handle = curl_easy_init(); - memory *mem; + struct memory *mem; /* Important: use HTTP2 over HTTPS */ curl_easy_setopt(handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS); curl_easy_setopt(handle, CURLOPT_URL, url); /* buffer body */ - mem = malloc(sizeof(memory)); + mem = malloc(sizeof(*mem)); mem->size = 0; mem->buf = malloc(1); curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, grow_buffer); @@ -119,7 +119,8 @@ static CURL *make_handle(const char *url) } /* HREF finder implemented in libxml2 but could be any HTML parser */ -static size_t follow_links(CURLM *multi_handle, memory *mem, const char *url) +static size_t follow_links(CURLM *multi_handle, struct memory *mem, + const char *url) { int opts = HTML_PARSE_NOBLANKS | HTML_PARSE_NOERROR | \ HTML_PARSE_NOWARNING | HTML_PARSE_NONET; @@ -213,7 +214,7 @@ int main(void) if(m->msg == CURLMSG_DONE) { CURL *handle = m->easy_handle; char *url; - memory *mem; + struct memory *mem; curl_easy_getinfo(handle, CURLINFO_PRIVATE, &mem); curl_easy_getinfo(handle, CURLINFO_EFFECTIVE_URL, &url); if(m->data.result == CURLE_OK) { diff --git a/vendor/curl/docs/examples/ephiperfifo.c b/vendor/curl/docs/examples/ephiperfifo.c index 5a25429f764..f411d2ea6c4 100644 --- a/vendor/curl/docs/examples/ephiperfifo.c +++ b/vendor/curl/docs/examples/ephiperfifo.c @@ -79,36 +79,33 @@ callback. /* Global information, common to all connections */ -typedef struct _GlobalInfo -{ +struct GlobalInfo { int epfd; /* epoll filedescriptor */ int tfd; /* timer filedescriptor */ int fifofd; /* fifo filedescriptor */ CURLM *multi; int still_running; FILE *input; -} GlobalInfo; +}; /* Information associated with a specific easy handle */ -typedef struct _ConnInfo -{ +struct ConnInfo { CURL *easy; char *url; - GlobalInfo *global; + struct GlobalInfo *global; char error[CURL_ERROR_SIZE]; -} ConnInfo; +}; /* Information associated with a specific socket */ -typedef struct _SockInfo -{ +struct SockInfo { curl_socket_t sockfd; CURL *easy; int action; long timeout; - GlobalInfo *global; -} SockInfo; + struct GlobalInfo *global; +}; #define mycase(code) \ case code: s = __STRING(code) @@ -136,12 +133,12 @@ static void mcode_or_die(const char *where, CURLMcode code) } } -static void timer_cb(GlobalInfo* g, int revents); +static void timer_cb(struct GlobalInfo *g, int revents); /* Update the timer after curl_multi library does its thing. Curl informs the * application through this callback what it wants the new timeout to be, * after it does some work. */ -static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g) +static int multi_timer_cb(CURLM *multi, long timeout_ms, struct GlobalInfo *g) { struct itimerspec its; @@ -163,7 +160,7 @@ static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g) its.it_value.tv_nsec = 1; } else { - memset(&its, 0, sizeof(struct itimerspec)); + memset(&its, 0, sizeof(its)); } timerfd_settime(g->tfd, /* flags= */0, &its, NULL); @@ -172,12 +169,12 @@ static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g) /* Check for completed transfers, and remove their easy handles */ -static void check_multi_info(GlobalInfo *g) +static void check_multi_info(struct GlobalInfo *g) { char *eff_url; CURLMsg *msg; int msgs_left; - ConnInfo *conn; + struct ConnInfo *conn; CURL *easy; CURLcode res; @@ -198,7 +195,7 @@ static void check_multi_info(GlobalInfo *g) } /* Called by libevent when we get action on a multi socket filedescriptor */ -static void event_cb(GlobalInfo *g, int fd, int revents) +static void event_cb(struct GlobalInfo *g, int fd, int revents) { CURLMcode rc; struct itimerspec its; @@ -212,13 +209,13 @@ static void event_cb(GlobalInfo *g, int fd, int revents) check_multi_info(g); if(g->still_running <= 0) { fprintf(MSG_OUT, "last transfer done, kill timeout\n"); - memset(&its, 0, sizeof(struct itimerspec)); + memset(&its, 0, sizeof(its)); timerfd_settime(g->tfd, 0, &its, NULL); } } /* Called by main loop when our timeout expires */ -static void timer_cb(GlobalInfo* g, int revents) +static void timer_cb(struct GlobalInfo *g, int revents) { CURLMcode rc; uint64_t count = 0; @@ -250,7 +247,7 @@ static void timer_cb(GlobalInfo* g, int revents) /* Clean up the SockInfo structure */ -static void remsock(SockInfo *f, GlobalInfo* g) +static void remsock(struct SockInfo *f, struct GlobalInfo *g) { if(f) { if(f->sockfd) { @@ -265,8 +262,8 @@ static void remsock(SockInfo *f, GlobalInfo* g) /* Assign information to a SockInfo structure */ -static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act, - GlobalInfo *g) +static void setsock(struct SockInfo *f, curl_socket_t s, CURL *e, int act, + struct GlobalInfo *g) { struct epoll_event ev; int kind = ((act & CURL_POLL_IN) ? EPOLLIN : 0) | @@ -292,9 +289,10 @@ static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act, /* Initialize a new SockInfo structure */ -static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g) +static void addsock(curl_socket_t s, CURL *easy, int action, + struct GlobalInfo *g) { - SockInfo *fdp = (SockInfo*)calloc(1, sizeof(SockInfo)); + struct SockInfo *fdp = (struct SockInfo*)calloc(1, sizeof(struct SockInfo)); fdp->global = g; setsock(fdp, s, easy, action, g); @@ -304,8 +302,8 @@ static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g) /* CURLMOPT_SOCKETFUNCTION */ static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp) { - GlobalInfo *g = (GlobalInfo*) cbp; - SockInfo *fdp = (SockInfo*) sockp; + struct GlobalInfo *g = (struct GlobalInfo*) cbp; + struct SockInfo *fdp = (struct SockInfo*) sockp; const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" }; fprintf(MSG_OUT, @@ -344,7 +342,7 @@ static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data) static int prog_cb(void *p, double dltotal, double dlnow, double ult, double uln) { - ConnInfo *conn = (ConnInfo *)p; + struct ConnInfo *conn = (struct ConnInfo *)p; (void)ult; (void)uln; @@ -354,12 +352,12 @@ static int prog_cb(void *p, double dltotal, double dlnow, double ult, /* Create a new easy handle, and add it to the global curl_multi */ -static void new_conn(const char *url, GlobalInfo *g) +static void new_conn(const char *url, struct GlobalInfo *g) { - ConnInfo *conn; + struct ConnInfo *conn; CURLMcode rc; - conn = (ConnInfo*)calloc(1, sizeof(ConnInfo)); + conn = (struct ConnInfo*)calloc(1, sizeof(*conn)); conn->error[0] = '\0'; conn->easy = curl_easy_init(); @@ -391,7 +389,7 @@ static void new_conn(const char *url, GlobalInfo *g) } /* This gets called whenever data is received from the fifo */ -static void fifo_cb(GlobalInfo* g, int revents) +static void fifo_cb(struct GlobalInfo *g, int revents) { char s[1024]; long int rv = 0; @@ -411,7 +409,7 @@ static void fifo_cb(GlobalInfo* g, int revents) /* Create a named pipe and tell libevent to monitor it */ static const char *fifo = "hiper.fifo"; -static int init_fifo(GlobalInfo *g) +static int init_fifo(struct GlobalInfo *g) { struct stat st; curl_socket_t sockfd; @@ -447,7 +445,7 @@ static int init_fifo(GlobalInfo *g) return 0; } -static void clean_fifo(GlobalInfo *g) +static void clean_fifo(struct GlobalInfo *g) { epoll_ctl(g->epfd, EPOLL_CTL_DEL, g->fifofd, NULL); fclose(g->input); @@ -464,7 +462,7 @@ void sigint_handler(int signo) int main(int argc, char **argv) { - GlobalInfo g; + struct GlobalInfo g; struct itimerspec its; struct epoll_event ev; struct epoll_event events[10]; @@ -474,7 +472,7 @@ int main(int argc, char **argv) g_should_exit_ = 0; signal(SIGINT, sigint_handler); - memset(&g, 0, sizeof(GlobalInfo)); + memset(&g, 0, sizeof(g)); g.epfd = epoll_create1(EPOLL_CLOEXEC); if(g.epfd == -1) { perror("epoll_create1 failed"); @@ -487,7 +485,7 @@ int main(int argc, char **argv) return 1; } - memset(&its, 0, sizeof(struct itimerspec)); + memset(&its, 0, sizeof(its)); its.it_interval.tv_sec = 0; its.it_value.tv_sec = 1; timerfd_settime(g.tfd, 0, &its, NULL); @@ -516,6 +514,7 @@ int main(int argc, char **argv) int err = epoll_wait(g.epfd, events, sizeof(events)/sizeof(struct epoll_event), 10000); if(err == -1) { + /* !checksrc! disable ERRNOVAR 1 */ if(errno == EINTR) { fprintf(MSG_OUT, "note: wait interrupted\n"); continue; diff --git a/vendor/curl/docs/examples/evhiperfifo.c b/vendor/curl/docs/examples/evhiperfifo.c index 76a7cde469f..96937fc6281 100644 --- a/vendor/curl/docs/examples/evhiperfifo.c +++ b/vendor/curl/docs/examples/evhiperfifo.c @@ -79,43 +79,40 @@ callback. /* Global information, common to all connections */ -typedef struct _GlobalInfo -{ +struct GlobalInfo { struct ev_loop *loop; struct ev_io fifo_event; struct ev_timer timer_event; CURLM *multi; int still_running; FILE *input; -} GlobalInfo; +}; /* Information associated with a specific easy handle */ -typedef struct _ConnInfo -{ +struct ConnInfo { CURL *easy; char *url; - GlobalInfo *global; + struct GlobalInfo *global; char error[CURL_ERROR_SIZE]; -} ConnInfo; +}; /* Information associated with a specific socket */ -typedef struct _SockInfo -{ +struct SockInfo { curl_socket_t sockfd; CURL *easy; int action; long timeout; struct ev_io ev; int evset; - GlobalInfo *global; -} SockInfo; + struct GlobalInfo *global; +}; static void timer_cb(EV_P_ struct ev_timer *w, int revents); /* Update the event timer after curl_multi library calls */ -static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g) +static int multi_timer_cb(CURLM *multi, long timeout_ms, struct GlobalInfo *g) { (void)multi; printf("%s %li\n", __PRETTY_FUNCTION__, timeout_ms); @@ -170,12 +167,12 @@ static void mcode_or_die(const char *where, CURLMcode code) /* Check for completed transfers, and remove their easy handles */ -static void check_multi_info(GlobalInfo *g) +static void check_multi_info(struct GlobalInfo *g) { char *eff_url; CURLMsg *msg; int msgs_left; - ConnInfo *conn; + struct ConnInfo *conn; CURL *easy; CURLcode res; @@ -200,12 +197,12 @@ static void check_multi_info(GlobalInfo *g) /* Called by libevent when we get action on a multi socket */ static void event_cb(EV_P_ struct ev_io *w, int revents) { - GlobalInfo *g; + struct GlobalInfo *g; CURLMcode rc; int action; printf("%s w %p revents %i\n", __PRETTY_FUNCTION__, (void *)w, revents); - g = (GlobalInfo*) w->data; + g = (struct GlobalInfo*) w->data; action = ((revents & EV_READ) ? CURL_POLL_IN : 0) | ((revents & EV_WRITE) ? CURL_POLL_OUT : 0); @@ -221,12 +218,12 @@ static void event_cb(EV_P_ struct ev_io *w, int revents) /* Called by libevent when our timeout expires */ static void timer_cb(EV_P_ struct ev_timer *w, int revents) { - GlobalInfo *g; + struct GlobalInfo *g; CURLMcode rc; printf("%s w %p revents %i\n", __PRETTY_FUNCTION__, (void *)w, revents); - g = (GlobalInfo *)w->data; + g = (struct GlobalInfo *)w->data; rc = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0, &g->still_running); @@ -235,7 +232,7 @@ static void timer_cb(EV_P_ struct ev_timer *w, int revents) } /* Clean up the SockInfo structure */ -static void remsock(SockInfo *f, GlobalInfo *g) +static void remsock(struct SockInfo *f, struct GlobalInfo *g) { printf("%s \n", __PRETTY_FUNCTION__); if(f) { @@ -248,8 +245,8 @@ static void remsock(SockInfo *f, GlobalInfo *g) /* Assign information to a SockInfo structure */ -static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act, - GlobalInfo *g) +static void setsock(struct SockInfo *f, curl_socket_t s, CURL *e, int act, + struct GlobalInfo *g) { int kind = ((act & CURL_POLL_IN) ? EV_READ : 0) | ((act & CURL_POLL_OUT) ? EV_WRITE : 0); @@ -270,9 +267,10 @@ static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act, /* Initialize a new SockInfo structure */ -static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g) +static void addsock(curl_socket_t s, CURL *easy, int action, + struct GlobalInfo *g) { - SockInfo *fdp = calloc(1, sizeof(SockInfo)); + struct SockInfo *fdp = calloc(1, sizeof(struct SockInfo)); fdp->global = g; setsock(fdp, s, easy, action, g); @@ -282,8 +280,8 @@ static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g) /* CURLMOPT_SOCKETFUNCTION */ static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp) { - GlobalInfo *g = (GlobalInfo*) cbp; - SockInfo *fdp = (SockInfo*) sockp; + struct GlobalInfo *g = (struct GlobalInfo*) cbp; + struct SockInfo *fdp = (struct SockInfo*) sockp; const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE"}; printf("%s e %p s %i what %i cbp %p sockp %p\n", @@ -315,7 +313,7 @@ static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp) static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data) { size_t realsize = size * nmemb; - ConnInfo *conn = (ConnInfo*) data; + struct ConnInfo *conn = (struct ConnInfo*) data; (void)ptr; (void)conn; return realsize; @@ -325,7 +323,7 @@ static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data) static int xferinfo_cb(void *p, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ult, curl_off_t uln) { - ConnInfo *conn = (ConnInfo *)p; + struct ConnInfo *conn = (struct ConnInfo *)p; (void)ult; (void)uln; @@ -336,12 +334,12 @@ static int xferinfo_cb(void *p, curl_off_t dltotal, curl_off_t dlnow, /* Create a new easy handle, and add it to the global curl_multi */ -static void new_conn(const char *url, GlobalInfo *g) +static void new_conn(const char *url, struct GlobalInfo *g) { - ConnInfo *conn; + struct ConnInfo *conn; CURLMcode rc; - conn = calloc(1, sizeof(ConnInfo)); + conn = calloc(1, sizeof(*conn)); conn->error[0]='\0'; conn->easy = curl_easy_init(); @@ -378,7 +376,7 @@ static void fifo_cb(EV_P_ struct ev_io *w, int revents) char s[1024]; long int rv = 0; int n = 0; - GlobalInfo *g = (GlobalInfo *)w->data; + struct GlobalInfo *g = (struct GlobalInfo *)w->data; (void)revents; @@ -395,7 +393,7 @@ static void fifo_cb(EV_P_ struct ev_io *w, int revents) } /* Create a named pipe and tell libevent to monitor it */ -static int init_fifo(GlobalInfo *g) +static int init_fifo(struct GlobalInfo *g) { struct stat st; static const char *fifo = "hiper.fifo"; @@ -429,11 +427,11 @@ static int init_fifo(GlobalInfo *g) int main(int argc, char **argv) { - GlobalInfo g; + struct GlobalInfo g; (void)argc; (void)argv; - memset(&g, 0, sizeof(GlobalInfo)); + memset(&g, 0, sizeof(g)); g.loop = ev_default_loop(0); if(init_fifo(&g)) diff --git a/vendor/curl/docs/examples/ftp-delete.c b/vendor/curl/docs/examples/ftp-delete.c new file mode 100644 index 00000000000..b879da48d3e --- /dev/null +++ b/vendor/curl/docs/examples/ftp-delete.c @@ -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 + +#include + +/* + * Delete a single file from an FTP server. + * + */ + +static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) +{ + (void)buffer; + (void)stream; + return size * nmemb; +} + + +int main(void) +{ + CURL *curl; + CURLcode res; + struct curl_slist *headerlist = NULL; + + curl_global_init(CURL_GLOBAL_DEFAULT); + + curl = curl_easy_init(); + if(curl) { + /* + * You better replace the URL with one that works! + */ + curl_easy_setopt(curl, CURLOPT_URL, "ftp://ftp.example.com/"); + /* Define our callback to get called when there is data to be written */ + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite); + + /* Switch on full protocol/debug output */ + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + + /* build a list of commands to pass to libcurl */ + headerlist = curl_slist_append(headerlist, "DELE file-to-remove"); + + /* pass in list of FTP commands to run after the transfer */ + curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist); + + res = curl_easy_perform(curl); + + /* always cleanup */ + curl_easy_cleanup(curl); + + /* clean up the FTP commands list */ + curl_slist_free_all(headerlist); + + if(CURLE_OK != res) { + /* we failed */ + fprintf(stderr, "curl told us %d\n", res); + } + } + + curl_global_cleanup(); + + return 0; +} diff --git a/vendor/curl/docs/examples/ftpuploadfrommem.c b/vendor/curl/docs/examples/ftpuploadfrommem.c index 25374868677..3748d68a05b 100644 --- a/vendor/curl/docs/examples/ftpuploadfrommem.c +++ b/vendor/curl/docs/examples/ftpuploadfrommem.c @@ -31,7 +31,7 @@ static const char data[]= "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " - "Nam rhoncus odio id venenatis volutpat. Vestibulum dapibus " + "___ rhoncus odio id venenatis volutpat. Vestibulum dapibus " "bibendum ullamcorper. Maecenas finibus elit augue, vel " "condimentum odio maximus nec. In hac habitasse platea dictumst. " "Vestibulum vel dolor et turpis rutrum finibus ac at nulla. " diff --git a/vendor/curl/docs/examples/ghiper.c b/vendor/curl/docs/examples/ghiper.c index 5066ff5adc7..7d8449cdf0a 100644 --- a/vendor/curl/docs/examples/ghiper.c +++ b/vendor/curl/docs/examples/ghiper.c @@ -66,34 +66,34 @@ #include #define MSG_OUT g_print /* Change to "g_error" to write to stderr */ -#define SHOW_VERBOSE 0 /* Set to non-zero for libcurl messages */ +#define SHOW_VERBOSE 0L /* Set to non-zero for libcurl messages */ #define SHOW_PROGRESS 0 /* Set to non-zero to enable progress callback */ /* Global information, common to all connections */ -typedef struct _GlobalInfo { +struct GlobalInfo { CURLM *multi; guint timer_event; int still_running; -} GlobalInfo; +}; /* Information associated with a specific easy handle */ -typedef struct _ConnInfo { +struct ConnInfo { CURL *easy; char *url; - GlobalInfo *global; + struct GlobalInfo *global; char error[CURL_ERROR_SIZE]; -} ConnInfo; +}; /* Information associated with a specific socket */ -typedef struct _SockInfo { +struct SockInfo { curl_socket_t sockfd; CURL *easy; int action; long timeout; GIOChannel *ch; guint ev; - GlobalInfo *global; -} SockInfo; + struct GlobalInfo *global; +}; /* Die if we get a bad CURLMcode somewhere */ static void mcode_or_die(const char *where, CURLMcode code) @@ -116,7 +116,7 @@ static void mcode_or_die(const char *where, CURLMcode code) } /* Check for completed transfers, and remove their easy handles */ -static void check_multi_info(GlobalInfo *g) +static void check_multi_info(struct GlobalInfo *g) { CURLMsg *msg; int msgs_left; @@ -127,7 +127,7 @@ static void check_multi_info(GlobalInfo *g) CURL *easy = msg->easy_handle; CURLcode res = msg->data.result; char *eff_url; - ConnInfo *conn; + struct ConnInfo *conn; curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn); curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url); MSG_OUT("DONE: %s => (%d) %s\n", eff_url, res, conn->error); @@ -142,7 +142,7 @@ static void check_multi_info(GlobalInfo *g) /* Called by glib when our timeout expires */ static gboolean timer_cb(gpointer data) { - GlobalInfo *g = (GlobalInfo *)data; + struct GlobalInfo *g = (struct GlobalInfo *)data; CURLMcode rc; rc = curl_multi_socket_action(g->multi, @@ -156,7 +156,7 @@ static gboolean timer_cb(gpointer data) static int update_timeout_cb(CURLM *multi, long timeout_ms, void *userp) { struct timeval timeout; - GlobalInfo *g = (GlobalInfo *)userp; + struct GlobalInfo *g = (struct GlobalInfo *)userp; timeout.tv_sec = timeout_ms/1000; timeout.tv_usec = (timeout_ms%1000)*1000; @@ -177,7 +177,7 @@ static int update_timeout_cb(CURLM *multi, long timeout_ms, void *userp) /* Called by glib when we get action on a multi socket */ static gboolean event_cb(GIOChannel *ch, GIOCondition condition, gpointer data) { - GlobalInfo *g = (GlobalInfo*) data; + struct GlobalInfo *g = (struct GlobalInfo*) data; CURLMcode rc; int fd = g_io_channel_unix_get_fd(ch); @@ -202,7 +202,7 @@ static gboolean event_cb(GIOChannel *ch, GIOCondition condition, gpointer data) } /* Clean up the SockInfo structure */ -static void remsock(SockInfo *f) +static void remsock(struct SockInfo *f) { if(!f) { return; @@ -214,8 +214,8 @@ static void remsock(SockInfo *f) } /* Assign information to a SockInfo structure */ -static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act, - GlobalInfo *g) +static void setsock(struct SockInfo *f, curl_socket_t s, CURL *e, int act, + struct GlobalInfo *g) { GIOCondition kind = ((act & CURL_POLL_IN) ? G_IO_IN : 0) | @@ -231,9 +231,10 @@ static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act, } /* Initialize a new SockInfo structure */ -static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g) +static void addsock(curl_socket_t s, CURL *easy, int action, + struct GlobalInfo *g) { - SockInfo *fdp = g_malloc0(sizeof(SockInfo)); + struct SockInfo *fdp = g_malloc0(sizeof(struct SockInfo)); fdp->global = g; fdp->ch = g_io_channel_unix_new(s); @@ -244,8 +245,8 @@ static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g) /* CURLMOPT_SOCKETFUNCTION */ static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp) { - GlobalInfo *g = (GlobalInfo*) cbp; - SockInfo *fdp = (SockInfo*) sockp; + struct GlobalInfo *g = (struct GlobalInfo*) cbp; + struct SockInfo *fdp = (struct SockInfo*) sockp; static const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" }; MSG_OUT("socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]); @@ -273,7 +274,7 @@ static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp) static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data) { size_t realsize = size * nmemb; - ConnInfo *conn = (ConnInfo*) data; + struct ConnInfo *conn = (struct ConnInfo*) data; (void)ptr; (void)conn; return realsize; @@ -283,7 +284,7 @@ static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data) static int xferinfo_cb(void *p, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ult, curl_off_t uln) { - ConnInfo *conn = (ConnInfo *)p; + struct ConnInfo *conn = (struct ConnInfo *)p; (void)ult; (void)uln; @@ -293,12 +294,12 @@ static int xferinfo_cb(void *p, curl_off_t dltotal, curl_off_t dlnow, } /* Create a new easy handle, and add it to the global curl_multi */ -static void new_conn(const char *url, GlobalInfo *g) +static void new_conn(const char *url, struct GlobalInfo *g) { - ConnInfo *conn; + struct ConnInfo *conn; CURLMcode rc; - conn = g_malloc0(sizeof(ConnInfo)); + conn = g_malloc0(sizeof(*conn)); conn->error[0] = '\0'; conn->easy = curl_easy_init(); if(!conn->easy) { @@ -310,7 +311,7 @@ static void new_conn(const char *url, GlobalInfo *g) curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url); curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb); curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn); - curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, (long)SHOW_VERBOSE); + curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, SHOW_VERBOSE); curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error); curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn); curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, SHOW_PROGRESS ? 0L : 1L); @@ -344,7 +345,7 @@ static gboolean fifo_cb(GIOChannel *ch, GIOCondition condition, gpointer data) if(tp) { buf[tp]='\0'; } - new_conn(buf, (GlobalInfo*)data); + new_conn(buf, (struct GlobalInfo*)data); g_free(buf); } else { @@ -368,7 +369,7 @@ static gboolean fifo_cb(GIOChannel *ch, GIOCondition condition, gpointer data) } } if(all) { - new_conn(all, (GlobalInfo*)data); + new_conn(all, (struct GlobalInfo*)data); g_free(all); } g_free(buf); @@ -415,7 +416,7 @@ int init_fifo(void) int main(void) { - GlobalInfo *g = g_malloc0(sizeof(GlobalInfo)); + struct GlobalInfo *g = g_malloc0(sizeof(struct GlobalInfo)); GMainLoop*gmain; int fd; GIOChannel* ch; diff --git a/vendor/curl/docs/examples/hiperfifo.c b/vendor/curl/docs/examples/hiperfifo.c index 6e96794b607..d1e534ffbd2 100644 --- a/vendor/curl/docs/examples/hiperfifo.c +++ b/vendor/curl/docs/examples/hiperfifo.c @@ -78,8 +78,7 @@ callback. /* Global information, common to all connections */ -typedef struct _GlobalInfo -{ +struct GlobalInfo { struct event_base *evbase; struct event fifo_event; struct event timer_event; @@ -87,29 +86,27 @@ typedef struct _GlobalInfo int still_running; FILE *input; int stopped; -} GlobalInfo; +}; /* Information associated with a specific easy handle */ -typedef struct _ConnInfo -{ +struct ConnInfo { CURL *easy; char *url; - GlobalInfo *global; + struct GlobalInfo *global; char error[CURL_ERROR_SIZE]; -} ConnInfo; +}; /* Information associated with a specific socket */ -typedef struct _SockInfo -{ +struct SockInfo { curl_socket_t sockfd; CURL *easy; int action; long timeout; struct event ev; - GlobalInfo *global; -} SockInfo; + struct GlobalInfo *global; +}; #define mycase(code) \ case code: s = __STRING(code) @@ -139,7 +136,7 @@ static void mcode_or_die(const char *where, CURLMcode code) /* Update the event timer after curl_multi library calls */ -static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g) +static int multi_timer_cb(CURLM *multi, long timeout_ms, struct GlobalInfo *g) { struct timeval timeout; (void)multi; @@ -163,12 +160,12 @@ static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g) /* Check for completed transfers, and remove their easy handles */ -static void check_multi_info(GlobalInfo *g) +static void check_multi_info(struct GlobalInfo *g) { char *eff_url; CURLMsg *msg; int msgs_left; - ConnInfo *conn; + struct ConnInfo *conn; CURL *easy; CURLcode res; @@ -195,7 +192,7 @@ static void check_multi_info(GlobalInfo *g) /* Called by libevent when we get action on a multi socket */ static void event_cb(int fd, short kind, void *userp) { - GlobalInfo *g = (GlobalInfo*) userp; + struct GlobalInfo *g = (struct GlobalInfo*) userp; CURLMcode rc; int action = @@ -219,7 +216,7 @@ static void event_cb(int fd, short kind, void *userp) /* Called by libevent when our timeout expires */ static void timer_cb(int fd, short kind, void *userp) { - GlobalInfo *g = (GlobalInfo *)userp; + struct GlobalInfo *g = (struct GlobalInfo *)userp; CURLMcode rc; (void)fd; (void)kind; @@ -233,7 +230,7 @@ static void timer_cb(int fd, short kind, void *userp) /* Clean up the SockInfo structure */ -static void remsock(SockInfo *f) +static void remsock(struct SockInfo *f) { if(f) { if(event_initialized(&f->ev)) { @@ -246,8 +243,8 @@ static void remsock(SockInfo *f) /* Assign information to a SockInfo structure */ -static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act, - GlobalInfo *g) +static void setsock(struct SockInfo *f, curl_socket_t s, CURL *e, int act, + struct GlobalInfo *g) { int kind = ((act & CURL_POLL_IN) ? EV_READ : 0) | @@ -266,9 +263,10 @@ static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act, /* Initialize a new SockInfo structure */ -static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g) +static void addsock(curl_socket_t s, CURL *easy, int action, + struct GlobalInfo *g) { - SockInfo *fdp = calloc(1, sizeof(SockInfo)); + struct SockInfo *fdp = calloc(1, sizeof(struct SockInfo)); fdp->global = g; setsock(fdp, s, easy, action, g); @@ -278,8 +276,8 @@ static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g) /* CURLMOPT_SOCKETFUNCTION */ static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp) { - GlobalInfo *g = (GlobalInfo*) cbp; - SockInfo *fdp = (SockInfo*) sockp; + struct GlobalInfo *g = (struct GlobalInfo*) cbp; + struct SockInfo *fdp = (struct SockInfo*) sockp; const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" }; fprintf(MSG_OUT, @@ -318,7 +316,7 @@ static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data) static int xferinfo_cb(void *p, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ult, curl_off_t uln) { - ConnInfo *conn = (ConnInfo *)p; + struct ConnInfo *conn = (struct ConnInfo *)p; (void)ult; (void)uln; @@ -329,12 +327,12 @@ static int xferinfo_cb(void *p, curl_off_t dltotal, curl_off_t dlnow, /* Create a new easy handle, and add it to the global curl_multi */ -static void new_conn(const char *url, GlobalInfo *g) +static void new_conn(const char *url, struct GlobalInfo *g) { - ConnInfo *conn; + struct ConnInfo *conn; CURLMcode rc; - conn = calloc(1, sizeof(ConnInfo)); + conn = calloc(1, sizeof(*conn)); conn->error[0] = '\0'; conn->easy = curl_easy_init(); @@ -369,7 +367,7 @@ static void fifo_cb(int fd, short event, void *arg) char s[1024]; long int rv = 0; int n = 0; - GlobalInfo *g = (GlobalInfo *)arg; + struct GlobalInfo *g = (struct GlobalInfo *)arg; (void)fd; (void)event; @@ -393,7 +391,7 @@ static void fifo_cb(int fd, short event, void *arg) /* Create a named pipe and tell libevent to monitor it */ static const char *fifo = "hiper.fifo"; -static int init_fifo(GlobalInfo *g) +static int init_fifo(struct GlobalInfo *g) { struct stat st; curl_socket_t sockfd; @@ -425,7 +423,7 @@ static int init_fifo(GlobalInfo *g) return 0; } -static void clean_fifo(GlobalInfo *g) +static void clean_fifo(struct GlobalInfo *g) { event_del(&g->fifo_event); fclose(g->input); @@ -434,11 +432,11 @@ static void clean_fifo(GlobalInfo *g) int main(int argc, char **argv) { - GlobalInfo g; + struct GlobalInfo g; (void)argc; (void)argv; - memset(&g, 0, sizeof(GlobalInfo)); + memset(&g, 0, sizeof(g)); g.evbase = event_base_new(); if(init_fifo(&g)) return 1; diff --git a/vendor/curl/docs/examples/hsts-preload.c b/vendor/curl/docs/examples/hsts-preload.c index a25773f42dd..ba9fe87a944 100644 --- a/vendor/curl/docs/examples/hsts-preload.c +++ b/vendor/curl/docs/examples/hsts-preload.c @@ -87,7 +87,7 @@ int main(void) struct state st = {0}; /* enable HSTS for this handle */ - curl_easy_setopt(curl, CURLOPT_HSTS_CTRL, (long)CURLHSTS_ENABLE); + curl_easy_setopt(curl, CURLOPT_HSTS_CTRL, CURLHSTS_ENABLE); /* function to call at first to populate the cache before the transfer */ curl_easy_setopt(curl, CURLOPT_HSTSREADFUNCTION, hstsread); diff --git a/vendor/curl/docs/examples/http2-upload.c b/vendor/curl/docs/examples/http2-upload.c index 580944f2710..c24e5937c17 100644 --- a/vendor/curl/docs/examples/http2-upload.c +++ b/vendor/curl/docs/examples/http2-upload.c @@ -158,6 +158,7 @@ int my_trace(CURL *handle, curl_infotype type, known_offset = 1; } secs = epoch_offset + tv.tv_sec; + /* !checksrc! disable BANNEDFUNC 1 */ now = localtime(&secs); /* not thread safe but we do not care */ curl_msnprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06ld", now->tm_hour, now->tm_min, now->tm_sec, (long)tv.tv_usec); diff --git a/vendor/curl/docs/examples/http3.c b/vendor/curl/docs/examples/http3.c index e278f2e313e..573ea20d2b4 100644 --- a/vendor/curl/docs/examples/http3.c +++ b/vendor/curl/docs/examples/http3.c @@ -38,8 +38,7 @@ int main(void) curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); /* Use HTTP/3 but fallback to earlier HTTP if necessary */ - curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, - (long)CURL_HTTP_VERSION_3); + curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_3); /* Perform the request, res gets the return code */ res = curl_easy_perform(curl); diff --git a/vendor/curl/docs/examples/httpput-postfields.c b/vendor/curl/docs/examples/httpput-postfields.c index fdd6ffe0dd0..5f410837b86 100644 --- a/vendor/curl/docs/examples/httpput-postfields.c +++ b/vendor/curl/docs/examples/httpput-postfields.c @@ -33,7 +33,7 @@ static const char olivertwist[]= "Among other public buildings in a certain town, which for many reasons " "it will be prudent to refrain from mentioning, and to which I will assign " "no fictitious name, there is one anciently common to most towns, great or " - "small: to wit, a workhouse; and in this workhouse was born; on a day and " + "small: to ___, a workhouse; and in this workhouse was born; on a day and " "date which I need not trouble myself to repeat, inasmuch as it can be of " "no possible consequence to the reader, in this stage of the business at " "all events; the item of mortality whose name is prefixed"; diff --git a/vendor/curl/docs/examples/imap-tls.c b/vendor/curl/docs/examples/imap-tls.c index 838923b334c..8fbc96bb55c 100644 --- a/vendor/curl/docs/examples/imap-tls.c +++ b/vendor/curl/docs/examples/imap-tls.c @@ -57,7 +57,7 @@ int main(void) * of using CURLUSESSL_TRY here, because if TLS upgrade fails, the * transfer continues anyway - see the security discussion in the libcurl * tutorial for more details. */ - curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); + curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); /* If your server does not have a valid certificate, then you can disable * part of the Transport Layer Security protection by setting the diff --git a/vendor/curl/docs/examples/ipv6.c b/vendor/curl/docs/examples/ipv6.c index 371e0f5573e..1b698705d0c 100644 --- a/vendor/curl/docs/examples/ipv6.c +++ b/vendor/curl/docs/examples/ipv6.c @@ -35,7 +35,7 @@ int main(void) curl = curl_easy_init(); if(curl) { - curl_easy_setopt(curl, CURLOPT_IPRESOLVE, (long)CURL_IPRESOLVE_V6); + curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6); curl_easy_setopt(curl, CURLOPT_URL, "https://curl.se/"); diff --git a/vendor/curl/docs/examples/multi-event.c b/vendor/curl/docs/examples/multi-event.c index 450ac7871c2..f2c3e87c2b3 100644 --- a/vendor/curl/docs/examples/multi-event.c +++ b/vendor/curl/docs/examples/multi-event.c @@ -36,18 +36,18 @@ static struct event_base *base; static CURLM *curl_handle; static struct event *timeout; -typedef struct curl_context_s { +struct curl_context { struct event *event; curl_socket_t sockfd; -} curl_context_t; +}; static void curl_perform(int fd, short event, void *arg); -static curl_context_t *create_curl_context(curl_socket_t sockfd) +static struct curl_context *create_curl_context(curl_socket_t sockfd) { - curl_context_t *context; + struct curl_context *context; - context = (curl_context_t *) malloc(sizeof(*context)); + context = (struct curl_context *) malloc(sizeof(*context)); context->sockfd = sockfd; @@ -56,7 +56,7 @@ static curl_context_t *create_curl_context(curl_socket_t sockfd) return context; } -static void destroy_curl_context(curl_context_t *context) +static void destroy_curl_context(struct curl_context *context) { event_del(context->event); event_free(context->event); @@ -125,7 +125,7 @@ static void curl_perform(int fd, short event, void *arg) { int running_handles; int flags = 0; - curl_context_t *context; + struct curl_context *context; (void)fd; @@ -134,7 +134,7 @@ static void curl_perform(int fd, short event, void *arg) if(event & EV_WRITE) flags |= CURL_CSELECT_OUT; - context = (curl_context_t *) arg; + context = (struct curl_context *) arg; curl_multi_socket_action(curl_handle, context->sockfd, flags, &running_handles); @@ -175,7 +175,7 @@ static int start_timeout(CURLM *multi, long timeout_ms, void *userp) static int handle_socket(CURL *easy, curl_socket_t s, int action, void *userp, void *socketp) { - curl_context_t *curl_context; + struct curl_context *curl_context; int events = 0; (void)easy; @@ -186,7 +186,7 @@ static int handle_socket(CURL *easy, curl_socket_t s, int action, void *userp, case CURL_POLL_OUT: case CURL_POLL_INOUT: curl_context = socketp ? - (curl_context_t *) socketp : create_curl_context(s); + (struct curl_context *) socketp : create_curl_context(s); curl_multi_assign(curl_handle, s, (void *) curl_context); @@ -205,8 +205,8 @@ static int handle_socket(CURL *easy, curl_socket_t s, int action, void *userp, break; case CURL_POLL_REMOVE: if(socketp) { - event_del(((curl_context_t*) socketp)->event); - destroy_curl_context((curl_context_t*) socketp); + event_del(((struct curl_context*) socketp)->event); + destroy_curl_context((struct curl_context*) socketp); curl_multi_assign(curl_handle, s, NULL); } break; diff --git a/vendor/curl/docs/examples/multi-uv.c b/vendor/curl/docs/examples/multi-uv.c index 1b3fca0de04..1a61745dfa3 100644 --- a/vendor/curl/docs/examples/multi-uv.c +++ b/vendor/curl/docs/examples/multi-uv.c @@ -46,18 +46,18 @@ struct datauv { CURLM *multi; }; -typedef struct curl_context_s { +struct curl_context { uv_poll_t poll_handle; curl_socket_t sockfd; struct datauv *uv; -} curl_context_t; +}; -static curl_context_t *create_curl_context(curl_socket_t sockfd, - struct datauv *uv) +static struct curl_context *create_curl_context(curl_socket_t sockfd, + struct datauv *uv) { - curl_context_t *context; + struct curl_context *context; - context = (curl_context_t *) malloc(sizeof(*context)); + context = (struct curl_context *) malloc(sizeof(*context)); context->sockfd = sockfd; context->uv = uv; @@ -70,11 +70,11 @@ static curl_context_t *create_curl_context(curl_socket_t sockfd, static void curl_close_cb(uv_handle_t *handle) { - curl_context_t *context = (curl_context_t *) handle->data; + struct curl_context *context = (struct curl_context *) handle->data; free(context); } -static void destroy_curl_context(curl_context_t *context) +static void destroy_curl_context(struct curl_context *context) { uv_close((uv_handle_t *) &context->poll_handle, curl_close_cb); } @@ -101,7 +101,7 @@ static void add_download(const char *url, int num, CURLM *multi) fprintf(stderr, "Added download %s -> %s\n", url, filename); } -static void check_multi_info(curl_context_t *context) +static void check_multi_info(struct curl_context *context) { char *done_url; CURLMsg *message; @@ -142,7 +142,7 @@ static void on_uv_socket(uv_poll_t *req, int status, int events) { int running_handles; int flags = 0; - curl_context_t *context = (curl_context_t *) req->data; + struct curl_context *context = (struct curl_context *) req->data; (void)status; if(events & UV_READABLE) flags |= CURL_CSELECT_IN; @@ -157,7 +157,7 @@ static void on_uv_socket(uv_poll_t *req, int status, int events) /* callback from libuv when timeout expires */ static void on_uv_timeout(uv_timer_t *req) { - curl_context_t *context = (curl_context_t *) req->data; + struct curl_context *context = (struct curl_context *) req->data; if(context) { int running_handles; curl_multi_socket_action(context->uv->multi, CURL_SOCKET_TIMEOUT, 0, @@ -188,7 +188,7 @@ static int cb_socket(CURL *easy, curl_socket_t s, int action, struct datauv *uv, void *socketp) { - curl_context_t *curl_context; + struct curl_context *curl_context; int events = 0; (void)easy; @@ -197,7 +197,7 @@ static int cb_socket(CURL *easy, curl_socket_t s, int action, case CURL_POLL_OUT: case CURL_POLL_INOUT: curl_context = socketp ? - (curl_context_t *) socketp : create_curl_context(s, uv); + (struct curl_context *) socketp : create_curl_context(s, uv); curl_multi_assign(uv->multi, s, (void *) curl_context); @@ -210,8 +210,8 @@ static int cb_socket(CURL *easy, curl_socket_t s, int action, break; case CURL_POLL_REMOVE: if(socketp) { - uv_poll_stop(&((curl_context_t*)socketp)->poll_handle); - destroy_curl_context((curl_context_t*) socketp); + uv_poll_stop(&((struct curl_context*)socketp)->poll_handle); + destroy_curl_context((struct curl_context*) socketp); curl_multi_assign(uv->multi, s, NULL); } break; diff --git a/vendor/curl/docs/examples/multithread.c b/vendor/curl/docs/examples/multithread.c index 7978419bdc5..ceee94022a3 100644 --- a/vendor/curl/docs/examples/multithread.c +++ b/vendor/curl/docs/examples/multithread.c @@ -80,7 +80,7 @@ int main(void) NULL, /* default attributes please */ pull_one_url, (void *)urls[i]); - if(0 != error) + if(error) fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error); else fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]); diff --git a/vendor/curl/docs/examples/pop3-tls.c b/vendor/curl/docs/examples/pop3-tls.c index 7c2d824d043..b2f504c475d 100644 --- a/vendor/curl/docs/examples/pop3-tls.c +++ b/vendor/curl/docs/examples/pop3-tls.c @@ -56,7 +56,7 @@ int main(void) * using CURLUSESSL_TRY here, because if TLS upgrade fails, the transfer * continues anyway - see the security discussion in the libcurl tutorial * for more details. */ - curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); + curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); /* If your server does not have a valid certificate, then you can disable * part of the Transport Layer Security protection by setting the diff --git a/vendor/curl/docs/examples/post-callback.c b/vendor/curl/docs/examples/post-callback.c index 1a213cb2d54..fa0c575e657 100644 --- a/vendor/curl/docs/examples/post-callback.c +++ b/vendor/curl/docs/examples/post-callback.c @@ -33,9 +33,9 @@ static const char data[]="Lorem ipsum dolor sit amet, consectetur adipiscing " "elit. Sed vel urna neque. Ut quis leo metus. Quisque eleifend, ex at " "laoreet rhoncus, odio ipsum semper metus, at tempus ante urna in mauris. " - "Suspendisse ornare tempor venenatis. Ut dui neque, pellentesque a varius " + "Suspendisse ornare tempor venenatis. Ut dui neque, pellentesque a ______ " "eget, mattis vitae ligula. Fusce ut pharetra est. Ut ullamcorper mi ac " - "sollicitudin semper. Praesent sit amet tellus varius, posuere nulla non, " + "sollicitudin semper. Praesent sit amet tellus ______, posuere nulla non, " "rhoncus ipsum."; struct WriteThis { diff --git a/vendor/curl/docs/examples/sessioninfo.c b/vendor/curl/docs/examples/sessioninfo.c index bb5721aca69..225b1ae5a51 100644 --- a/vendor/curl/docs/examples/sessioninfo.c +++ b/vendor/curl/docs/examples/sessioninfo.c @@ -102,7 +102,7 @@ int main(void) curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L); - (void) curl_easy_perform(curl); + (void)curl_easy_perform(curl); curl_easy_cleanup(curl); } diff --git a/vendor/curl/docs/examples/sftpget.c b/vendor/curl/docs/examples/sftpget.c index 6b594a1bfec..4d33939a40b 100644 --- a/vendor/curl/docs/examples/sftpget.c +++ b/vendor/curl/docs/examples/sftpget.c @@ -86,7 +86,7 @@ int main(void) /* We activate ssh agent. For this to work you need to have ssh-agent running (type set | grep SSH_AGENT to check) or pageant on Windows (there is an icon in systray if so) */ - curl_easy_setopt(curl, CURLOPT_SSH_AUTH_TYPES, (long)CURLSSH_AUTH_AGENT); + curl_easy_setopt(curl, CURLOPT_SSH_AUTH_TYPES, CURLSSH_AUTH_AGENT); #endif /* Switch on full protocol/debug output */ diff --git a/vendor/curl/docs/examples/sftpuploadresume.c b/vendor/curl/docs/examples/sftpuploadresume.c index 2803da33e0f..f1f7b0c275a 100644 --- a/vendor/curl/docs/examples/sftpuploadresume.c +++ b/vendor/curl/docs/examples/sftpuploadresume.c @@ -83,7 +83,7 @@ static int sftpResumeUpload(CURL *curlhandle, const char *remotepath, CURLcode result = CURLE_GOT_NOTHING; curl_off_t remoteFileSizeByte = sftpGetRemoteFileSize(remotepath); - if(-1 == remoteFileSizeByte) { + if(remoteFileSizeByte == -1) { printf("Error reading the remote file size: unable to resume upload\n"); return -1; } diff --git a/vendor/curl/docs/examples/simplessl.c b/vendor/curl/docs/examples/simplessl.c index f9c0a78d601..220dc62bcd1 100644 --- a/vendor/curl/docs/examples/simplessl.c +++ b/vendor/curl/docs/examples/simplessl.c @@ -66,7 +66,7 @@ int main(void) #ifdef USE_ENGINE pKeyName = "rsa_test"; pKeyType = "ENG"; - pEngine = "chil"; /* for nChiper HSM... */ + pEngine = "chil"; /* for nCipher HSM... */ #else pKeyName = "testkey.pem"; pKeyType = "PEM"; diff --git a/vendor/curl/docs/examples/smooth-gtk-thread.c b/vendor/curl/docs/examples/smooth-gtk-thread.c index c53951262af..49a412d9584 100644 --- a/vendor/curl/docs/examples/smooth-gtk-thread.c +++ b/vendor/curl/docs/examples/smooth-gtk-thread.c @@ -130,7 +130,7 @@ void *create_thread(void *progress_bar) NULL, /* default attributes please */ pull_one_url, NULL); - if(0 != error) + if(error) fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error); else fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]); diff --git a/vendor/curl/docs/examples/smtp-tls.c b/vendor/curl/docs/examples/smtp-tls.c index fd4e385023a..34a00bd5483 100644 --- a/vendor/curl/docs/examples/smtp-tls.c +++ b/vendor/curl/docs/examples/smtp-tls.c @@ -110,7 +110,7 @@ int main(void) * of using CURLUSESSL_TRY here, because if TLS upgrade fails, the * transfer continues anyway - see the security discussion in the libcurl * tutorial for more details. */ - curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); + curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); /* If your server does not have a valid certificate, then you can disable * part of the Transport Layer Security protection by setting the diff --git a/vendor/curl/docs/examples/synctime.c b/vendor/curl/docs/examples/synctime.c index 109ae0361b5..ba5f09cb075 100644 --- a/vendor/curl/docs/examples/synctime.c +++ b/vendor/curl/docs/examples/synctime.c @@ -87,12 +87,11 @@ #define SYNCTIME_UA "synctime/1.0" -typedef struct -{ +struct conf { char http_proxy[MAX_STRING1]; char proxy_user[MAX_STRING1]; char timeserver[MAX_STRING1]; -} conf_t; +}; static const char DefaultTimeServer[3][MAX_STRING1] = { @@ -229,22 +228,22 @@ static void showUsage(void) return; } -static int conf_init(conf_t *conf) +static int conf_init(struct conf *conf) { int i; - *conf->http_proxy = 0; + *conf->http_proxy = 0; for(i = 0; i < MAX_STRING1; i++) - conf->proxy_user[i] = 0; /* Clean up password from memory */ - *conf->timeserver = 0; + conf->proxy_user[i] = 0; /* Clean up password from memory */ + *conf->timeserver = 0; return 1; } int main(int argc, char *argv[]) { - CURL *curl; - conf_t conf[1]; - int RetValue; + CURL *curl; + struct conf conf[1]; + int RetValue; ShowAllHeader = 0; /* Do not show HTTP Header */ AutoSyncTime = 0; /* Do not synchronise computer clock */ @@ -299,8 +298,10 @@ int main(int argc, char *argv[]) /* Calculating time diff between GMT and localtime */ tt = time(0); + /* !checksrc! disable BANNEDFUNC 1 */ lt = localtime(&tt); tt_local = mktime(lt); + /* !checksrc! disable BANNEDFUNC 1 */ gmt = gmtime(&tt); tt_gmt = mktime(gmt); tzonediffFloat = difftime(tt_local, tt_gmt); diff --git a/vendor/curl/docs/examples/threaded-ssl.c b/vendor/curl/docs/examples/threaded-ssl.c index 263400afd8a..96681290553 100644 --- a/vendor/curl/docs/examples/threaded-ssl.c +++ b/vendor/curl/docs/examples/threaded-ssl.c @@ -83,7 +83,7 @@ int main(int argc, char **argv) NULL, /* default attributes please */ pull_one_url, (void *)urls[i]); - if(0 != error) + if(error) fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error); else fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]); diff --git a/vendor/curl/docs/examples/usercertinmem.c b/vendor/curl/docs/examples/usercertinmem.c index 75fadfe8f61..49722ca30f9 100644 --- a/vendor/curl/docs/examples/usercertinmem.c +++ b/vendor/curl/docs/examples/usercertinmem.c @@ -51,7 +51,7 @@ static size_t writefunction(void *ptr, size_t size, size_t nmemb, void *stream) return nmemb * size; } -static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm) +static CURLcode sslctx_function(CURL *curl, void *sslctx, void *pointer) { X509 *cert = NULL; BIO *bio = NULL; @@ -59,50 +59,20 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm) RSA *rsa = NULL; int ret; - const char *mypem = /* www.cacert.org */ + const char *mypem = + /* replace the XXX with the actual CA certificate */ "-----BEGIN CERTIFICATE-----\n"\ - "MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290\n"\ - "IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB\n"\ - "IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA\n"\ - "Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO\n"\ - "BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi\n"\ - "MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ\n"\ - "ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC\n"\ - "CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ\n"\ - "8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6\n"\ - "zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y\n"\ - "fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7\n"\ - "w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc\n"\ - "G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k\n"\ - "epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q\n"\ - "laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ\n"\ - "QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU\n"\ - "fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826\n"\ - "YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w\n"\ - "ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY\n"\ - "gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe\n"\ - "MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0\n"\ - "IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy\n"\ - "dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw\n"\ - "czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0\n"\ - "dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl\n"\ - "aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC\n"\ - "AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg\n"\ - "b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB\n"\ - "ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc\n"\ - "nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg\n"\ - "18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c\n"\ - "gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl\n"\ - "Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY\n"\ - "sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T\n"\ - "SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF\n"\ - "CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum\n"\ - "GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk\n"\ - "zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW\n"\ - "omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "-----END CERTIFICATE-----\n"; -/* replace the XXX with the actual RSA key */ + /* replace the XXX with the actual RSA key */ const char *mykey = "-----BEGIN RSA PRIVATE KEY-----\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ @@ -124,7 +94,7 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm) "-----END RSA PRIVATE KEY-----\n"; (void)curl; /* avoid warnings */ - (void)parm; /* avoid warnings */ + (void)pointer; /* avoid warnings */ /* get a BIO */ bio = BIO_new_mem_buf((char *)mypem, -1); diff --git a/vendor/curl/docs/examples/websocket-updown.c b/vendor/curl/docs/examples/websocket-updown.c new file mode 100644 index 00000000000..a32d48898dc --- /dev/null +++ b/vendor/curl/docs/examples/websocket-updown.c @@ -0,0 +1,125 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 + * + ***************************************************************************/ +/* + * WebSocket download-only using write callback + * + */ +#include +#include +#include + +static size_t writecb(char *b, size_t size, size_t nitems, void *p) +{ + CURL *easy = p; + size_t i; + unsigned int blen = (unsigned int)(nitems * size); + const struct curl_ws_frame *frame = curl_ws_meta(easy); + fprintf(stderr, "Type: %s\n", frame->flags & CURLWS_BINARY ? + "binary" : "text"); + if(frame->flags & CURLWS_BINARY) { + fprintf(stderr, "Bytes: %u", blen); + for(i = 0; i < nitems; i++) + fprintf(stderr, "%02x ", (unsigned char)b[i]); + fprintf(stderr, "\n"); + } + else + fprintf(stderr, "Text: %.*s\n", (int)blen, b); + return nitems; +} + +struct read_ctx { + CURL *easy; + char buf[1024]; + size_t blen; + size_t nsent; +}; + +static size_t readcb(char *buf, size_t nitems, size_t buflen, void *p) +{ + struct read_ctx *ctx = p; + size_t len = nitems * buflen; + size_t left = ctx->blen - ctx->nsent; + CURLcode result; + + if(!ctx->nsent) { + /* On first call, set the FRAME information to be used (it defaults + * to CURLWS_BINARY otherwise). */ + result = curl_ws_start_frame(ctx->easy, CURLWS_TEXT, + (curl_off_t)ctx->blen); + if(result) { + fprintf(stderr, "error staring frame: %d\n", result); + return CURL_READFUNC_ABORT; + } + } + fprintf(stderr, "read(len=%d, left=%d)\n", (int)len, (int)left); + if(left) { + if(left < len) + len = left; + memcpy(buf, ctx->buf + ctx->nsent, len); + ctx->nsent += len; + return len; + } + return 0; +} + +int main(int argc, const char *argv[]) +{ + CURL *easy; + struct read_ctx rctx; + CURLcode res; + const char *payload = "Hello, friend!"; + + memset(&rctx, 0, sizeof(rctx)); + + easy = curl_easy_init(); + if(!easy) + return 1; + + if(argc == 2) + curl_easy_setopt(easy, CURLOPT_URL, argv[1]); + else + curl_easy_setopt(easy, CURLOPT_URL, "wss://example.com"); + + curl_easy_setopt(easy, CURLOPT_WRITEFUNCTION, writecb); + curl_easy_setopt(easy, CURLOPT_WRITEDATA, easy); + curl_easy_setopt(easy, CURLOPT_READFUNCTION, readcb); + /* tell curl that we want to send the payload */ + rctx.easy = easy; + rctx.blen = strlen(payload); + memcpy(rctx.buf, payload, rctx.blen); + curl_easy_setopt(easy, CURLOPT_READDATA, &rctx); + curl_easy_setopt(easy, CURLOPT_UPLOAD, 1L); + + + /* Perform the request, res gets the return code */ + res = curl_easy_perform(easy); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + /* always cleanup */ + curl_easy_cleanup(easy); + return 0; +} diff --git a/vendor/curl/docs/examples/websocket.c b/vendor/curl/docs/examples/websocket.c index 758ee48e0e6..0df12c84bdc 100644 --- a/vendor/curl/docs/examples/websocket.c +++ b/vendor/curl/docs/examples/websocket.c @@ -37,51 +37,77 @@ #include -static int ping(CURL *curl, const char *send_payload) +static CURLcode ping(CURL *curl, const char *send_payload) { - size_t sent; - CURLcode result = - curl_ws_send(curl, send_payload, strlen(send_payload), &sent, 0, - CURLWS_PING); - return (int)result; + CURLcode res = CURLE_OK; + const char *buf = send_payload; + size_t sent, blen = strlen(send_payload); + + while(blen) { + res = curl_ws_send(curl, buf, blen, &sent, 0, CURLWS_PING); + if(!res) { + buf += sent; /* deduct what was sent */ + blen -= sent; + } + else if(res == CURLE_AGAIN) { /* blocked on sending */ + fprintf(stderr, "ws: sent PING blocked, waiting a second\n"); + sleep(1); /* either select() on socket or max timeout would + be good here. */ + } + else /* real error sending */ + break; + } + if(!res) + fprintf(stderr, "ws: sent PING with payload\n"); + return res; } -static int recv_pong(CURL *curl, const char *expected_payload) +static CURLcode recv_pong(CURL *curl, const char *expected_payload) { size_t rlen; const struct curl_ws_frame *meta; char buffer[256]; - CURLcode result = curl_ws_recv(curl, buffer, sizeof(buffer), &rlen, &meta); - if(!result) { + CURLcode res; + +retry: + res = curl_ws_recv(curl, buffer, sizeof(buffer), &rlen, &meta); + if(!res) { + /* on small PING content, this example assumes the complete + * PONG content arrives in one go. Larger frames will arrive + * in chunks, however. */ if(meta->flags & CURLWS_PONG) { int same = 0; - fprintf(stderr, "ws: got PONG back\n"); if(rlen == strlen(expected_payload)) { - if(!memcmp(expected_payload, buffer, rlen)) { - fprintf(stderr, "ws: got the same payload back\n"); + if(!memcmp(expected_payload, buffer, rlen)) same = 1; - } } - if(!same) - fprintf(stderr, "ws: did NOT get the same payload back\n"); + fprintf(stderr, "ws: received PONG with %s payload back\n", + same ? "same" : "different"); + } + else if(meta->flags & CURLWS_TEXT) { + fprintf(stderr, "ws: received TEXT frame '%.*s'\n", (int)rlen, + buffer); + } + else if(meta->flags & CURLWS_BINARY) { + fprintf(stderr, "ws: received BINARY frame of %u bytes\n", (int)rlen); } else { - fprintf(stderr, "recv_pong: got %u bytes rflags %x\n", (int)rlen, + /* some other frame arrived. */ + fprintf(stderr, "ws: received frame of %u bytes rflags %x\n", (int)rlen, meta->flags); + goto retry; } } - fprintf(stderr, "ws: curl_ws_recv returned %u, received %u\n", - (unsigned int)result, (unsigned int)rlen); - return (int)result; -} - -static CURLcode recv_any(CURL *curl) -{ - size_t rlen; - const struct curl_ws_frame *meta; - char buffer[256]; - - return curl_ws_recv(curl, buffer, sizeof(buffer), &rlen, &meta); + else if(res == CURLE_AGAIN) { /* blocked on receiving */ + fprintf(stderr, "ws: PONG not there yet, waiting a second\n"); + sleep(1); /* either select() on socket or max timeout would + be good here. */ + goto retry; + } + if(res) + fprintf(stderr, "ws: curl_ws_recv returned %u, received %u\n", + (unsigned int)res, (unsigned int)rlen); + return res; } /* close the connection */ @@ -91,45 +117,51 @@ static void websocket_close(CURL *curl) (void)curl_ws_send(curl, "", 0, &sent, 0, CURLWS_CLOSE); } -static void websocket(CURL *curl) +static CURLcode websocket(CURL *curl) { + CURLcode res; int i = 0; do { - recv_any(curl); - if(ping(curl, "foobar")) - return; - if(recv_pong(curl, "foobar")) { - return; - } - sleep(2); + res = ping(curl, "foobar"); + if(res) + break; + res = recv_pong(curl, "foobar"); + if(res) + break; + sleep(1); } while(i++ < 10); websocket_close(curl); + return res; } -int main(void) +int main(int argc, const char *argv[]) { CURL *curl; CURLcode res; curl = curl_easy_init(); - if(curl) { + if(!curl) { + return 1; /* memory failure */ + } + if(argc == 2) + curl_easy_setopt(curl, CURLOPT_URL, argv[1]); + else curl_easy_setopt(curl, CURLOPT_URL, "wss://example.com"); - curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 2L); /* websocket style */ - - /* Perform the request, res gets the return code */ - res = curl_easy_perform(curl); - /* Check for errors */ - if(res != CURLE_OK) - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(res)); - else { - /* connected and ready */ - websocket(curl); - } + curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 2L); /* websocket style */ - /* always cleanup */ - curl_easy_cleanup(curl); + /* Perform the request, res gets the return code */ + res = curl_easy_perform(curl); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + else { + /* connected and ready */ + res = websocket(curl); } - return 0; + + /* always cleanup */ + curl_easy_cleanup(curl); + return (int)res; } diff --git a/vendor/curl/docs/examples/xmlstream.c b/vendor/curl/docs/examples/xmlstream.c index 208682ef0dc..91c5387888c 100644 --- a/vendor/curl/docs/examples/xmlstream.c +++ b/vendor/curl/docs/examples/xmlstream.c @@ -122,7 +122,7 @@ int main(void) struct ParserStruct state; /* Initialize the state structure for parsing. */ - memset(&state, 0, sizeof(struct ParserStruct)); + memset(&state, 0, sizeof(state)); state.ok = 1; /* Initialize a namespace-aware parser. */ diff --git a/vendor/curl/docs/libcurl/.gitignore b/vendor/curl/docs/libcurl/.gitignore new file mode 100644 index 00000000000..d520903f798 --- /dev/null +++ b/vendor/curl/docs/libcurl/.gitignore @@ -0,0 +1,5 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +libcurl-symbols.md diff --git a/vendor/curl/include/curl/curl.h b/vendor/curl/include/curl/curl.h index fb225c7903c..6f4aa90f134 100644 --- a/vendor/curl/include/curl/curl.h +++ b/vendor/curl/include/curl/curl.h @@ -102,7 +102,7 @@ #include #endif -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -124,7 +124,7 @@ typedef void CURLSH; #elif defined(_WIN32) || \ (CURL_HAS_DECLSPEC_ATTRIBUTE(dllexport) && \ CURL_HAS_DECLSPEC_ATTRIBUTE(dllimport)) -# if defined(BUILDING_LIBCURL) +# ifdef BUILDING_LIBCURL # define CURL_EXTERN __declspec(dllexport) # else # define CURL_EXTERN __declspec(dllimport) @@ -158,11 +158,11 @@ typedef enum { CURLSSLBACKEND_POLARSSL CURL_DEPRECATED(7.69.0, "") = 6, CURLSSLBACKEND_WOLFSSL = 7, CURLSSLBACKEND_SCHANNEL = 8, - CURLSSLBACKEND_SECURETRANSPORT = 9, + CURLSSLBACKEND_SECURETRANSPORT CURL_DEPRECATED(8.15.0, "") = 9, CURLSSLBACKEND_AXTLS CURL_DEPRECATED(7.61.0, "") = 10, CURLSSLBACKEND_MBEDTLS = 11, CURLSSLBACKEND_MESALINK CURL_DEPRECATED(7.82.0, "") = 12, - CURLSSLBACKEND_BEARSSL = 13, + CURLSSLBACKEND_BEARSSL CURL_DEPRECATED(8.15.0, "") = 13, CURLSSLBACKEND_RUSTLS = 14 } curl_sslbackend; @@ -645,20 +645,7 @@ typedef enum { CURLE_UNRECOVERABLE_POLL, /* 99 - poll/select returned fatal error */ CURLE_TOO_LARGE, /* 100 - a value/data met its maximum */ CURLE_ECH_REQUIRED, /* 101 - ECH tried but failed */ - CURL_LAST, /* never use! */ - - CURLE_RESERVED115 = 115, /* 115-126 - used in tests */ - CURLE_RESERVED116 = 116, - CURLE_RESERVED117 = 117, - CURLE_RESERVED118 = 118, - CURLE_RESERVED119 = 119, - CURLE_RESERVED120 = 120, - CURLE_RESERVED121 = 121, - CURLE_RESERVED122 = 122, - CURLE_RESERVED123 = 123, - CURLE_RESERVED124 = 124, - CURLE_RESERVED125 = 125, - CURLE_RESERVED126 = 126 + CURL_LAST /* never use! */ } CURLcode; #ifndef CURL_NO_OLDIES /* define this to test if your app builds with all @@ -801,20 +788,24 @@ typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ mbedtls_ssl_config */ void *userptr); +#define CURLPROXY_HTTP 0L /* added in 7.10, new in 7.19.4 default is + to use CONNECT HTTP/1.1 */ +#define CURLPROXY_HTTP_1_0 1L /* force to use CONNECT HTTP/1.0 + added in 7.19.4 */ +#define CURLPROXY_HTTPS 2L /* HTTPS but stick to HTTP/1 + added in 7.52.0 */ +#define CURLPROXY_HTTPS2 3L /* HTTPS and attempt HTTP/2 + added in 8.2.0 */ +#define CURLPROXY_SOCKS4 4L /* support added in 7.15.2, enum existed + already in 7.10 */ +#define CURLPROXY_SOCKS5 5L /* added in 7.10 */ +#define CURLPROXY_SOCKS4A 6L /* added in 7.18.0 */ +#define CURLPROXY_SOCKS5_HOSTNAME 7L /* Use the SOCKS5 protocol but pass along + the hostname rather than the IP + address. added in 7.18.0 */ + 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 - hostname rather than the IP address. added - in 7.18.0 */ + CURLPROXY_LAST = 8 /* never use */ } curl_proxytype; /* this enum was added in 7.10 */ /* @@ -855,19 +846,19 @@ typedef enum { #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_ANY ~0L /* all types supported by the server */ +#define CURLSSH_AUTH_NONE 0L /* none allowed, silly but complete */ +#define CURLSSH_AUTH_PUBLICKEY (1L<<0) /* public/private key files */ +#define CURLSSH_AUTH_PASSWORD (1L<<1) /* password */ +#define CURLSSH_AUTH_HOST (1L<<2) /* host key files */ +#define CURLSSH_AUTH_KEYBOARD (1L<<3) /* keyboard interactive */ +#define CURLSSH_AUTH_AGENT (1L<<4) /* agent (ssh-agent, pageant...) */ +#define CURLSSH_AUTH_GSSAPI (1L<<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 CURLGSSAPI_DELEGATION_NONE 0L /* no delegation (default) */ +#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1L<<0) /* if permitted by policy */ +#define CURLGSSAPI_DELEGATION_FLAG (1L<<1) /* delegate always */ #define CURL_ERROR_SIZE 256 @@ -943,31 +934,31 @@ typedef enum { 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) +#define CURLSSLOPT_ALLOW_BEAST (1L<<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) +#define CURLSSLOPT_NO_REVOKE (1L<<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) +#define CURLSSLOPT_NO_PARTIALCHAIN (1L<<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) +#define CURLSSLOPT_REVOKE_BEST_EFFORT (1L<<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) +#define CURLSSLOPT_NATIVE_CA (1L<<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) +#define CURLSSLOPT_AUTO_CLIENT_CERT (1L<<5) /* If possible, send data using TLS 1.3 early data */ -#define CURLSSLOPT_EARLYDATA (1<<6) +#define CURLSSLOPT_EARLYDATA (1L<<6) /* The default connection attempt delay in milliseconds for happy eyeballs. CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document @@ -992,50 +983,55 @@ typedef enum { #endif /* !CURL_NO_OLDIES */ /* parameter for the CURLOPT_FTP_SSL_CCC option */ +#define CURLFTPSSL_CCC_NONE 0L /* do not send CCC */ +#define CURLFTPSSL_CCC_PASSIVE 1L /* Let the server initiate the shutdown */ +#define CURLFTPSSL_CCC_ACTIVE 2L /* Initiate the shutdown */ + 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 */ + CURLFTPSSL_CCC_LAST = 3 /* not an option, never use */ } curl_ftpccc; /* parameter for the CURLOPT_FTPSSLAUTH option */ +#define CURLFTPAUTH_DEFAULT 0L /* let libcurl decide */ +#define CURLFTPAUTH_SSL 1L /* use "AUTH SSL" */ +#define CURLFTPAUTH_TLS 2L /* use "AUTH TLS" */ + typedef enum { - CURLFTPAUTH_DEFAULT, /* let libcurl decide */ - CURLFTPAUTH_SSL, /* use "AUTH SSL" */ - CURLFTPAUTH_TLS, /* use "AUTH TLS" */ - CURLFTPAUTH_LAST /* not an option, never use */ + CURLFTPAUTH_LAST = 3 /* not an option, never use */ } curl_ftpauth; /* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ +#define CURLFTP_CREATE_DIR_NONE 0L /* do NOT create missing dirs! */ +#define CURLFTP_CREATE_DIR 1L /* (FTP/SFTP) if CWD fails, try MKD and + then CWD again if MKD succeeded, for + SFTP this does similar magic */ +#define CURLFTP_CREATE_DIR_RETRY 2L /* (FTP only) if CWD fails, try MKD and + then CWD again even if MKD failed! */ + 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 */ + CURLFTP_CREATE_DIR_LAST = 3 /* not an option, never use */ } curl_ftpcreatedir; /* parameter for the CURLOPT_FTP_FILEMETHOD option */ +#define CURLFTPMETHOD_DEFAULT 0L /* let libcurl pick */ +#define CURLFTPMETHOD_MULTICWD 1L /* single CWD operation for each path + part */ +#define CURLFTPMETHOD_NOCWD 2L /* no CWD at all */ +#define CURLFTPMETHOD_SINGLECWD 3L /* one CWD to full dir, then work on file */ + 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 */ + CURLFTPMETHOD_LAST = 4 /* not an option, never use */ } curl_ftpmethod; /* bitmask defines for CURLOPT_HEADEROPT */ -#define CURLHEADER_UNIFIED 0 -#define CURLHEADER_SEPARATE (1<<0) +#define CURLHEADER_UNIFIED 0L +#define CURLHEADER_SEPARATE (1L<<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) +#define CURLALTSVC_READONLYFILE (1L<<2) +#define CURLALTSVC_H1 (1L<<3) +#define CURLALTSVC_H2 (1L<<4) +#define CURLALTSVC_H3 (1L<<5) /* bitmask values for CURLOPT_UPLOAD_FLAGS */ #define CURLULFLAG_ANSWERED (1L<<0) @@ -1071,42 +1067,42 @@ typedef CURLSTScode (*curl_hstswrite_callback)(CURL *easy, void *userp); /* CURLHSTS_* are bits for the CURLOPT_HSTS option */ -#define CURLHSTS_ENABLE (long)(1<<0) -#define CURLHSTS_READONLYFILE (long)(1<<1) +#define CURLHSTS_ENABLE (1L<<0) +#define CURLHSTS_READONLYFILE (1L<<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 */ +#define CURLPROTO_HTTP (1L<<0) +#define CURLPROTO_HTTPS (1L<<1) +#define CURLPROTO_FTP (1L<<2) +#define CURLPROTO_FTPS (1L<<3) +#define CURLPROTO_SCP (1L<<4) +#define CURLPROTO_SFTP (1L<<5) +#define CURLPROTO_TELNET (1L<<6) +#define CURLPROTO_LDAP (1L<<7) +#define CURLPROTO_LDAPS (1L<<8) +#define CURLPROTO_DICT (1L<<9) +#define CURLPROTO_FILE (1L<<10) +#define CURLPROTO_TFTP (1L<<11) +#define CURLPROTO_IMAP (1L<<12) +#define CURLPROTO_IMAPS (1L<<13) +#define CURLPROTO_POP3 (1L<<14) +#define CURLPROTO_POP3S (1L<<15) +#define CURLPROTO_SMTP (1L<<16) +#define CURLPROTO_SMTPS (1L<<17) +#define CURLPROTO_RTSP (1L<<18) +#define CURLPROTO_RTMP (1L<<19) +#define CURLPROTO_RTMPT (1L<<20) +#define CURLPROTO_RTMPE (1L<<21) +#define CURLPROTO_RTMPTE (1L<<22) +#define CURLPROTO_RTMPS (1L<<23) +#define CURLPROTO_RTMPTS (1L<<24) +#define CURLPROTO_GOPHER (1L<<25) +#define CURLPROTO_SMB (1L<<26) +#define CURLPROTO_SMBS (1L<<27) +#define CURLPROTO_MQTT (1L<<28) +#define CURLPROTO_GOPHERS (1L<<29) +#define CURLPROTO_ALL (~0L) /* enable everything */ /* long may be 32 or 64 bits, but we should never depend on anything else but 32 */ @@ -1967,7 +1963,8 @@ typedef enum { CURLOPT(CURLOPT_SSL_VERIFYSTATUS, CURLOPTTYPE_LONG, 232), /* Set if we should enable TLS false start. */ - CURLOPT(CURLOPT_SSL_FALSESTART, CURLOPTTYPE_LONG, 233), + CURLOPTDEPRECATED(CURLOPT_SSL_FALSESTART, CURLOPTTYPE_LONG, 233, + 8.15.0, "Has no function"), /* Do not squash dot-dot sequences */ CURLOPT(CURLOPT_PATH_AS_IS, CURLOPTTYPE_LONG, 234), @@ -2301,10 +2298,10 @@ typedef enum { /* 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 +#define CURL_IPRESOLVE_WHATEVER 0L /* 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 */ +#define CURL_IPRESOLVE_V4 1L /* uses only IPv4 addresses/connections */ +#define CURL_IPRESOLVE_V6 2L /* uses only IPv6 addresses/connections */ /* Convenient "aliases" */ #define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER @@ -2366,18 +2363,18 @@ enum CURL_NETRC_OPTION { CURL_NETRC_LAST = 3 }; -#define CURL_SSLVERSION_DEFAULT 0 -#define CURL_SSLVERSION_TLSv1 1 /* TLS 1.x */ -#define CURL_SSLVERSION_SSLv2 2 -#define CURL_SSLVERSION_SSLv3 3 -#define CURL_SSLVERSION_TLSv1_0 4 -#define CURL_SSLVERSION_TLSv1_1 5 -#define CURL_SSLVERSION_TLSv1_2 6 -#define CURL_SSLVERSION_TLSv1_3 7 +#define CURL_SSLVERSION_DEFAULT 0L +#define CURL_SSLVERSION_TLSv1 1L /* TLS 1.x */ +#define CURL_SSLVERSION_SSLv2 2L +#define CURL_SSLVERSION_SSLv3 3L +#define CURL_SSLVERSION_TLSv1_0 4L +#define CURL_SSLVERSION_TLSv1_1 5L +#define CURL_SSLVERSION_TLSv1_2 6L +#define CURL_SSLVERSION_TLSv1_3 7L -#define CURL_SSLVERSION_LAST 8 /* never use, keep last */ +#define CURL_SSLVERSION_LAST 8L /* never use, keep last */ -#define CURL_SSLVERSION_MAX_NONE 0 +#define CURL_SSLVERSION_MAX_NONE 0L #define CURL_SSLVERSION_MAX_DEFAULT (CURL_SSLVERSION_TLSv1 << 16) #define CURL_SSLVERSION_MAX_TLSv1_0 (CURL_SSLVERSION_TLSv1_0 << 16) #define CURL_SSLVERSION_MAX_TLSv1_1 (CURL_SSLVERSION_TLSv1_1 << 16) @@ -2401,10 +2398,10 @@ enum CURL_TLSAUTH { 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_GET_ALL 0L +#define CURL_REDIR_POST_301 1L +#define CURL_REDIR_POST_302 2L +#define CURL_REDIR_POST_303 4L #define CURL_REDIR_POST_ALL \ (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303) @@ -2433,7 +2430,7 @@ 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. */ +#define CURLMIMEOPT_FORMESCAPE (1L<<0) /* Use backslash-escaping for forms. */ /* * NAME curl_mime_init() @@ -2762,7 +2759,7 @@ CURL_EXTERN CURLcode curl_global_init(long flags); * 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 + * memory leaks, check for misuse 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. */ @@ -3314,7 +3311,7 @@ CURL_EXTERN CURLcode curl_easy_ssls_export(CURL *handle, void *userptr); -#ifdef __cplusplus +#ifdef __cplusplus } /* end of extern "C" */ #endif @@ -3329,8 +3326,9 @@ CURL_EXTERN CURLcode curl_easy_ssls_export(CURL *handle, #include "mprintf.h" /* the typechecker does not work in C++ (yet) */ -#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ - ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \ +#if ((defined(__GNUC__) && defined(__GNUC_MINOR__) && \ + ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || \ + (defined(__clang__) && __clang_major__ >= 14)) && \ !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK) #include "typecheck-gcc.h" #else diff --git a/vendor/curl/include/curl/curlver.h b/vendor/curl/include/curl/curlver.h index 2e794e63ab0..48fb81df813 100644 --- a/vendor/curl/include/curl/curlver.h +++ b/vendor/curl/include/curl/curlver.h @@ -32,14 +32,13 @@ /* This is the version number of the libcurl package from which this header file origins: */ -#define LIBCURL_VERSION "8.14.1" +#define LIBCURL_VERSION "8.16.0-DEV" /* The numeric version number is also available "in parts" by using these defines: */ #define LIBCURL_VERSION_MAJOR 8 -#define LIBCURL_VERSION_MINOR 14 -#define LIBCURL_VERSION_PATCH 1 - +#define LIBCURL_VERSION_MINOR 16 +#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: @@ -59,7 +58,7 @@ 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 0x080e01 +#define LIBCURL_VERSION_NUM 0x081000 /* * This is the date and time when the full source package was created. The @@ -70,7 +69,7 @@ * * "2007-11-23" */ -#define LIBCURL_TIMESTAMP "2025-06-04" +#define LIBCURL_TIMESTAMP "[unreleased]" #define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z)) #define CURL_AT_LEAST_VERSION(x,y,z) \ diff --git a/vendor/curl/include/curl/easy.h b/vendor/curl/include/curl/easy.h index 56f8060e045..fa135649379 100644 --- a/vendor/curl/include/curl/easy.h +++ b/vendor/curl/include/curl/easy.h @@ -23,7 +23,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -118,7 +118,7 @@ CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, */ CURL_EXTERN CURLcode curl_easy_upkeep(CURL *curl); -#ifdef __cplusplus +#ifdef __cplusplus } /* end of extern "C" */ #endif diff --git a/vendor/curl/include/curl/header.h b/vendor/curl/include/curl/header.h index 8df11e1e424..7465274b9c4 100644 --- a/vendor/curl/include/curl/header.h +++ b/vendor/curl/include/curl/header.h @@ -24,7 +24,7 @@ * ***************************************************************************/ -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif diff --git a/vendor/curl/include/curl/mprintf.h b/vendor/curl/include/curl/mprintf.h index 88059c851fb..9272e748919 100644 --- a/vendor/curl/include/curl/mprintf.h +++ b/vendor/curl/include/curl/mprintf.h @@ -28,7 +28,7 @@ #include /* needed for FILE */ #include "curl.h" /* for CURL_EXTERN */ -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -38,7 +38,7 @@ extern "C" { defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ !defined(CURL_NO_FMT_CHECKS) #if defined(__MINGW32__) && !defined(__clang__) -#if defined(__MINGW_PRINTF_FORMAT) /* mingw-w64 3.0.0+. Needs stdio.h. */ +#ifdef __MINGW_PRINTF_FORMAT /* mingw-w64 3.0.0+. Needs stdio.h. */ #define CURL_TEMP_PRINTF(fmt, arg) \ __attribute__((format(__MINGW_PRINTF_FORMAT, fmt, arg))) #else @@ -78,7 +78,7 @@ CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args) #undef CURL_TEMP_PRINTF -#ifdef __cplusplus +#ifdef __cplusplus } /* end of extern "C" */ #endif diff --git a/vendor/curl/include/curl/multi.h b/vendor/curl/include/curl/multi.h index 42469bb5657..782541f1abb 100644 --- a/vendor/curl/include/curl/multi.h +++ b/vendor/curl/include/curl/multi.h @@ -50,7 +50,7 @@ */ #include "curl.h" -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -395,9 +395,23 @@ typedef enum { /* maximum number of concurrent streams to support on a connection */ CURLOPT(CURLMOPT_MAX_CONCURRENT_STREAMS, CURLOPTTYPE_LONG, 16), + /* network has changed, adjust caches/connection reuse */ + CURLOPT(CURLMOPT_NETWORK_CHANGED, CURLOPTTYPE_LONG, 17), + CURLMOPT_LASTENTRY /* the last unused */ } CURLMoption; +/* Definition of bits for the CURLMOPT_NETWORK_CHANGED argument: */ + +/* - CURLMNWC_CLEAR_CONNS tells libcurl to prevent further reuse of existing + connections. Connections that are idle will be closed. Ongoing transfers + will continue with the connection they have. */ +#define CURLMNWC_CLEAR_CONNS (1L<<0) + +/* - CURLMNWC_CLEAR_DNS tells libcurl to prevent further reuse of existing + connections. Connections that are idle will be closed. Ongoing transfers + will continue with the connection they have. */ +#define CURLMNWC_CLEAR_DNS (1L<<0) /* * Name: curl_multi_setopt() @@ -434,6 +448,36 @@ CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, */ CURL_EXTERN CURL **curl_multi_get_handles(CURLM *multi_handle); + +typedef enum { + CURLMINFO_NONE, /* first, never use this */ + /* The number of easy handles currently managed by the multi handle, + * e.g. have been added but not yet removed. */ + CURLMINFO_XFERS_CURRENT = 1, + /* The number of easy handles running, e.g. not done and not queueing. */ + CURLMINFO_XFERS_RUNNING = 2, + /* The number of easy handles waiting to start, e.g. for a connection + * to become available due to limits on parallelism, max connections + * or other factors. */ + CURLMINFO_XFERS_PENDING = 3, + /* The number of easy handles finished, waiting for their results to + * be read via `curl_multi_info_read()`. */ + CURLMINFO_XFERS_DONE = 4, + /* The total number of easy handles added to the multi handle, ever. */ + CURLMINFO_XFERS_ADDED = 5 +} CURLMinfo_offt; + +/* + * Name: curl_multi_get_offt() + * + * Desc: Retrieves a numeric value for the `CURLMINFO_*` enums. + * + * Returns: CULRM_OK or error when value could not be obtained. + */ +CURL_EXTERN CURLMcode curl_multi_get_offt(CURLM *multi_handle, + CURLMinfo_offt info, + curl_off_t *pvalue); + /* * Name: curl_push_callback * diff --git a/vendor/curl/include/curl/options.h b/vendor/curl/include/curl/options.h index 1ed76a95c68..77cab7768f2 100644 --- a/vendor/curl/include/curl/options.h +++ b/vendor/curl/include/curl/options.h @@ -24,7 +24,7 @@ * ***************************************************************************/ -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif diff --git a/vendor/curl/include/curl/system.h b/vendor/curl/include/curl/system.h index f1c2719cfe5..62ed2b0f43a 100644 --- a/vendor/curl/include/curl/system.h +++ b/vendor/curl/include/curl/system.h @@ -66,7 +66,7 @@ # define CURL_TYPEOF_CURL_SOCKLEN_T int #elif defined(__POCC__) -# if defined(_MSC_VER) +# ifdef _MSC_VER # define CURL_TYPEOF_CURL_OFF_T __int64 # define CURL_FORMAT_CURL_OFF_T "I64d" # define CURL_FORMAT_CURL_OFF_TU "I64u" @@ -82,7 +82,7 @@ # define CURL_TYPEOF_CURL_SOCKLEN_T int #elif defined(__LCC__) -# if defined(__MCST__) /* MCST eLbrus Compiler Collection */ +# ifdef __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" @@ -118,7 +118,7 @@ # define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int #elif defined(__TANDEM) -# if !defined(__LP64) +# ifndef __LP64 # define CURL_TYPEOF_CURL_OFF_T long long # define CURL_FORMAT_CURL_OFF_T "lld" # define CURL_FORMAT_CURL_OFF_TU "llu" @@ -135,7 +135,7 @@ # endif #elif defined(UNDER_CE) -# if defined(__MINGW32CE__) +# ifdef __MINGW32CE__ # define CURL_TYPEOF_CURL_OFF_T long long # define CURL_FORMAT_CURL_OFF_T "lld" # define CURL_FORMAT_CURL_OFF_TU "llu" @@ -162,7 +162,7 @@ # define CURL_PULL_SYS_TYPES_H 1 #elif defined(__VMS) -# if defined(__VAX) +# ifdef __VAX # define CURL_TYPEOF_CURL_OFF_T long # define CURL_FORMAT_CURL_OFF_T "ld" # define CURL_FORMAT_CURL_OFF_TU "lu" @@ -188,7 +188,7 @@ # define CURL_PULL_SYS_SOCKET_H 1 #elif defined(__MVS__) -# if defined(_LONG_LONG) +# ifdef _LONG_LONG # define CURL_TYPEOF_CURL_OFF_T long long # define CURL_FORMAT_CURL_OFF_T "lld" # define CURL_FORMAT_CURL_OFF_TU "llu" @@ -207,7 +207,7 @@ #elif defined(__370__) # if defined(__IBMC__) || defined(__IBMCPP__) -# if defined(_LONG_LONG) +# ifdef _LONG_LONG # define CURL_TYPEOF_CURL_OFF_T long long # define CURL_FORMAT_CURL_OFF_T "lld" # define CURL_FORMAT_CURL_OFF_TU "llu" @@ -266,7 +266,7 @@ # define CURL_PULL_SYS_SOCKET_H 1 #elif defined(__xlc__) /* IBM xlc compiler */ -# if !defined(_LP64) +# ifndef _LP64 # define CURL_TYPEOF_CURL_OFF_T long long # define CURL_FORMAT_CURL_OFF_T "lld" # define CURL_FORMAT_CURL_OFF_TU "llu" @@ -284,7 +284,7 @@ # define CURL_PULL_SYS_SOCKET_H 1 #elif defined(__hpux) /* HP aCC compiler */ -# if !defined(_LP64) +# ifndef _LP64 # define CURL_TYPEOF_CURL_OFF_T long long # define CURL_FORMAT_CURL_OFF_T "lld" # define CURL_FORMAT_CURL_OFF_TU "llu" @@ -329,15 +329,18 @@ defined(__ppc__) || defined(__powerpc__) || defined(__arm__) || \ defined(__sparc__) || defined(__mips__) || defined(__sh__) || \ defined(__XTENSA__) || \ - (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 4) || \ + (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 -# define CURL_POPCOUNT64(x) __builtin_popcountll(x) -# define CURL_CTZ64(x) __builtin_ctzll(x) +# if (__GNUC__ >= 4) || \ + ((__GNUC__ == 3) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 4)) +# define CURL_POPCOUNT64(x) __builtin_popcountll(x) +# define CURL_CTZ64(x) __builtin_ctzll(x) +# endif # elif defined(__LP64__) || \ defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \ defined(__e2k__) || \ @@ -348,8 +351,11 @@ # define CURL_FORMAT_CURL_OFF_TU "lu" # define CURL_SUFFIX_CURL_OFF_T L # define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_POPCOUNT64(x) __builtin_popcountl(x) -# define CURL_CTZ64(x) __builtin_ctzl(x) +# if (__GNUC__ >= 4) || \ + ((__GNUC__ == 3) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 4)) +# define CURL_POPCOUNT64(x) __builtin_popcountl(x) +# define CURL_CTZ64(x) __builtin_ctzl(x) +# endif # endif # define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t # define CURL_PULL_SYS_TYPES_H 1 @@ -357,11 +363,11 @@ #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_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 @@ -399,52 +405,4 @@ 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(__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/vendor/curl/include/curl/typecheck-gcc.h b/vendor/curl/include/curl/typecheck-gcc.h index ca0c0ef9d69..d053332032d 100644 --- a/vendor/curl/include/curl/typecheck-gcc.h +++ b/vendor/curl/include/curl/typecheck-gcc.h @@ -135,7 +135,7 @@ _curl_easy_setopt_err_error_buffer(); \ if((option) == CURLOPT_CURLU) \ if(!curlcheck_ptr((value), CURLU)) \ - _curl_easy_setopt_err_curlu(); \ + _curl_easy_setopt_err_curlu(); \ if((option) == CURLOPT_STDERR) \ if(!curlcheck_FILE(value)) \ _curl_easy_setopt_err_FILE(); \ @@ -178,7 +178,7 @@ _curl_easy_getinfo_err_curl_slist(); \ if(curlcheck_tlssessioninfo_info(info)) \ if(!curlcheck_arr((arg), struct curl_tlssessioninfo *)) \ - _curl_easy_getinfo_err_curl_tlssessioninfo(); \ + _curl_easy_getinfo_err_curl_tlssessioninfo(); \ if(curlcheck_certinfo_info(info)) \ if(!curlcheck_arr((arg), struct curl_certinfo *)) \ _curl_easy_getinfo_err_curl_certinfo(); \ @@ -546,7 +546,7 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t, curlcheck_arr((expr), unsigned char)) /* evaluates to true if expr is a CURL * */ -#define curlcheck_curl(expr) \ +#define curlcheck_curl(expr) \ (curlcheck_NULL(expr) || \ __builtin_types_compatible_p(__typeof__(expr), CURL *)) @@ -840,8 +840,8 @@ typedef long (*_curl_chunk_bgn_callback2)(void *, void *, int); curlcheck_cb_compatible((expr), curl_sshhostkeycallback)) /* evaluates to true if expr is of type curl_sshkeycallback */ -#define curlcheck_ssh_key_cb(expr) \ - (curlcheck_NULL(expr) || \ +#define curlcheck_ssh_key_cb(expr) \ + (curlcheck_NULL(expr) || \ curlcheck_cb_compatible((expr), curl_sshkeycallback)) /* evaluates to true if expr is of type curl_interleave_callback */ @@ -855,13 +855,13 @@ typedef size_t (*_curl_interleave_callback2)(char *p, size_t s, size_t n, void *u); /* evaluates to true if expr is of type curl_prereq_callback */ -#define curlcheck_prereq_cb(expr) \ - (curlcheck_NULL(expr) || \ +#define curlcheck_prereq_cb(expr) \ + (curlcheck_NULL(expr) || \ curlcheck_cb_compatible((expr), curl_prereq_callback)) /* evaluates to true if expr is of type curl_trailer_callback */ -#define curlcheck_trailer_cb(expr) \ - (curlcheck_NULL(expr) || \ +#define curlcheck_trailer_cb(expr) \ + (curlcheck_NULL(expr) || \ curlcheck_cb_compatible((expr), curl_trailer_callback)) #endif /* CURLINC_TYPECHECK_GCC_H */ diff --git a/vendor/curl/include/curl/urlapi.h b/vendor/curl/include/curl/urlapi.h index b4a6e5d5670..34c11a6bb7f 100644 --- a/vendor/curl/include/curl/urlapi.h +++ b/vendor/curl/include/curl/urlapi.h @@ -26,7 +26,7 @@ #include "curl.h" -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif diff --git a/vendor/curl/include/curl/websockets.h b/vendor/curl/include/curl/websockets.h index afb86b4ebcf..df8590f399d 100644 --- a/vendor/curl/include/curl/websockets.h +++ b/vendor/curl/include/curl/websockets.h @@ -24,7 +24,7 @@ * ***************************************************************************/ -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -72,13 +72,26 @@ CURL_EXTERN CURLcode curl_ws_send(CURL *curl, const void *buffer, curl_off_t fragsize, unsigned int flags); +/* + * NAME curl_ws_start_frame() + * + * DESCRIPTION + * + * Buffers a websocket frame header with the given flags and length. + * Errors when a previous frame is not complete, e.g. not all its + * payload has been added. + */ +CURL_EXTERN CURLcode curl_ws_start_frame(CURL *curl, + unsigned int flags, + curl_off_t frame_len); + /* bits for the CURLOPT_WS_OPTIONS bitmask: */ -#define CURLWS_RAW_MODE (1<<0) -#define CURLWS_NOAUTOPONG (1<<1) +#define CURLWS_RAW_MODE (1L<<0) +#define CURLWS_NOAUTOPONG (1L<<1) CURL_EXTERN const struct curl_ws_frame *curl_ws_meta(CURL *curl); -#ifdef __cplusplus +#ifdef __cplusplus } #endif diff --git a/vendor/curl/lib/.gitignore b/vendor/curl/lib/.gitignore new file mode 100644 index 00000000000..0f0bcd64653 --- /dev/null +++ b/vendor/curl/lib/.gitignore @@ -0,0 +1,10 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +Makefile.soname.cmake +curl_config.h +curl_config.h.in +libcurl.vers +libcurl_unity.c +unitprotos.h diff --git a/vendor/curl/lib/altsvc.c b/vendor/curl/lib/altsvc.c index 602ef61deff..a06f40bc2a2 100644 --- a/vendor/curl/lib/altsvc.c +++ b/vendor/curl/lib/altsvc.c @@ -32,7 +32,6 @@ #include "urldata.h" #include "altsvc.h" #include "curl_get_line.h" -#include "strcase.h" #include "parsedate.h" #include "sendf.h" #include "curlx/warnless.h" @@ -261,11 +260,11 @@ static CURLcode altsvc_out(struct altsvc *as, FILE *fp) #ifdef USE_IPV6 else { char ipv6_unused[16]; - if(1 == curlx_inet_pton(AF_INET6, as->dst.host, ipv6_unused)) { + if(curlx_inet_pton(AF_INET6, as->dst.host, ipv6_unused) == 1) { dst6_pre = "["; dst6_post = "]"; } - if(1 == curlx_inet_pton(AF_INET6, as->src.host, ipv6_unused)) { + if(curlx_inet_pton(AF_INET6, as->src.host, ipv6_unused) == 1) { src6_pre = "["; src6_post = "]"; } @@ -416,7 +415,7 @@ static bool hostcompare(const char *host, const char *check) if(hlen != clen) /* they cannot match if they have different lengths */ return FALSE; - return strncasecompare(host, check, hlen); + return curl_strnequal(host, check, hlen); } /* altsvc_flush() removes all alternatives for this source origin from the @@ -487,8 +486,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data, DEBUGASSERT(asi); /* initial check for "clear" */ - if(!curlx_str_until(&p, &alpn, MAX_ALTSVC_LINE, ';') && - !curlx_str_single(&p, ';')) { + if(!curlx_str_cspn(&p, &alpn, ";\n\r")) { curlx_str_trimblanks(&alpn); /* "clear" is a magic keyword */ if(curlx_str_casecompare(&alpn, "clear")) { @@ -666,4 +664,8 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi, return FALSE; } +#if defined(DEBUGBUILD) || defined(UNITTESTS) +#undef time +#endif + #endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_ALTSVC */ diff --git a/vendor/curl/lib/asyn-ares.c b/vendor/curl/lib/asyn-ares.c index 10f870a15af..bb3f4af0b9d 100644 --- a/vendor/curl/lib/asyn-ares.c +++ b/vendor/curl/lib/asyn-ares.c @@ -48,6 +48,7 @@ #endif #include "urldata.h" +#include "cfilters.h" #include "sendf.h" #include "hostip.h" #include "hash.h" @@ -236,26 +237,6 @@ CURLcode Curl_async_get_impl(struct Curl_easy *data, void **impl) return result; } -static void async_ares_cleanup(struct Curl_easy *data); - -void Curl_async_ares_shutdown(struct Curl_easy *data) -{ - struct async_ares_ctx *ares = &data->state.async.ares; - if(ares->channel) - ares_cancel(ares->channel); - async_ares_cleanup(data); -} - -void Curl_async_ares_destroy(struct Curl_easy *data) -{ - struct async_ares_ctx *ares = &data->state.async.ares; - Curl_async_ares_shutdown(data); - if(ares->channel) { - ares_destroy(ares->channel); - ares->channel = NULL; - } -} - /* * async_ares_cleanup() cleans up async resolver data. */ @@ -271,16 +252,36 @@ static void async_ares_cleanup(struct Curl_easy *data) #endif } +void Curl_async_ares_shutdown(struct Curl_easy *data) +{ + /* c-ares has a method to "cancel" operations on a channel, but + * as reported in #18216, this does not totally reset the channel + * and ares may get stuck. + * We need to destroy the channel and on demand create a new + * one to avoid that. */ + Curl_async_ares_destroy(data); +} + +void Curl_async_ares_destroy(struct Curl_easy *data) +{ + struct async_ares_ctx *ares = &data->state.async.ares; + if(ares->channel) { + ares_destroy(ares->channel); + ares->channel = NULL; + } + async_ares_cleanup(data); +} + /* - * Curl_async_getsock() is called when someone from the outside world + * Curl_async_pollset() is called when someone from the outside world * (using curl_multi_fdset()) wants to get our fd_set setup. */ -int Curl_async_getsock(struct Curl_easy *data, curl_socket_t *socks) +CURLcode Curl_async_pollset(struct Curl_easy *data, struct easy_pollset *ps) { struct async_ares_ctx *ares = &data->state.async.ares; DEBUGASSERT(ares->channel); - return Curl_ares_getsock(data, ares->channel, socks); + return Curl_ares_pollset(data, ares->channel, ps); } /* @@ -336,28 +337,55 @@ CURLcode Curl_async_is_resolved(struct Curl_easy *data, Curl_resolv_unlink(data, &data->state.async.dns); data->state.async.done = TRUE; result = ares->result; - if(ares->last_status == CURL_ASYNC_SUCCESS && !result) { + if(ares->ares_status == ARES_SUCCESS && !result) { data->state.async.dns = Curl_dnscache_mk_entry(data, ares->temp_ai, data->state.async.hostname, 0, data->state.async.port, FALSE); ares->temp_ai = NULL; /* temp_ai now owned by entry */ #ifdef HTTPSRR_WORKS - if(data->state.async.dns) { - struct Curl_https_rrinfo *lhrr = Curl_httpsrr_dup_move(&ares->hinfo); - if(!lhrr) - result = CURLE_OUT_OF_MEMORY; - else - data->state.async.dns->hinfo = lhrr; - } + if(data->state.async.dns) { + struct Curl_https_rrinfo *lhrr = Curl_httpsrr_dup_move(&ares->hinfo); + if(!lhrr) + result = CURLE_OUT_OF_MEMORY; + else + data->state.async.dns->hinfo = lhrr; + } #endif if(!result && data->state.async.dns) result = Curl_dnscache_add(data, data->state.async.dns); } /* if we have not found anything, report the proper * CURLE_COULDNT_RESOLVE_* code */ - if(!result && !data->state.async.dns) + if(!result && !data->state.async.dns) { result = Curl_resolver_error(data); + if(ares->ares_status != ARES_SUCCESS) { + const char *msg; + switch(ares->ares_status) { + case ARES_ECONNREFUSED: + msg = "connection to DNS server refused"; + break; + case ARES_ETIMEOUT: + msg = "query to DNS server timed out"; + break; + case ARES_ENOTFOUND: + msg = "DNS server did not find the address"; + break; + case ARES_EREFUSED: + msg = "DNS server refused query"; + break; + default: + msg = "resolve failed"; + break; + } + CURL_TRC_DNS(data, "asyn-ares: %s (error %d)", msg, ares->ares_status); +#if ARES_VERSION >= 0x011800 /* >= v1.24.0 */ + CURL_TRC_DNS(data, "asyn-ares config: %s", + ares_get_servers_csv(ares->channel)); +#endif + } + } + if(result) Curl_resolv_unlink(data, &data->state.async.dns); *dns = data->state.async.dns; @@ -451,8 +479,7 @@ CURLcode Curl_async_await(struct Curl_easy *data, /* Operation complete, if the lookup was successful we now have the entry in the cache. */ data->state.async.done = TRUE; - if(entry) - *entry = data->state.async.dns; + *entry = data->state.async.dns; if(result) ares_cancel(ares->channel); @@ -511,14 +538,14 @@ static void async_ares_hostbyname_cb(void *user_data, be valid so only defer it when we know the 'status' says its fine! */ return; - if(CURL_ASYNC_SUCCESS == status) { - ares->last_status = status; /* one success overrules any error */ + if(ARES_SUCCESS == status) { + ares->ares_status = status; /* one success overrules any error */ async_addr_concat(&ares->temp_ai, Curl_he2ai(hostent, data->state.async.port)); } - else if(ares->last_status != ARES_SUCCESS) { - /* no success so far, remember error */ - ares->last_status = status; + else if(ares->ares_status != ARES_SUCCESS) { + /* no success so far, remember last error */ + ares->ares_status = status; } ares->num_pending--; @@ -666,21 +693,22 @@ async_ares_node2addr(struct ares_addrinfo_node *node) } static void async_ares_addrinfo_cb(void *user_data, int status, int timeouts, - struct ares_addrinfo *result) + struct ares_addrinfo *ares_ai) { struct Curl_easy *data = (struct Curl_easy *)user_data; struct async_ares_ctx *ares = &data->state.async.ares; (void)timeouts; - CURL_TRC_DNS(data, "asyn-ares: addrinfo callback, status=%d", status); - if(ARES_SUCCESS == status) { - ares->temp_ai = async_ares_node2addr(result->nodes); - ares->last_status = CURL_ASYNC_SUCCESS; - ares_freeaddrinfo(result); + if(ares->ares_status != ARES_SUCCESS) /* do not overwrite success */ + ares->ares_status = status; + if(status == ARES_SUCCESS) { + ares->temp_ai = async_ares_node2addr(ares_ai->nodes); + ares_freeaddrinfo(ares_ai); } ares->num_pending--; - CURL_TRC_DNS(data, "ares: addrinfo done, status=%d, pending=%d, " - "addr=%sfound", - status, ares->num_pending, ares->temp_ai ? "" : "not "); + CURL_TRC_DNS(data, "ares: addrinfo done, query status=%d, " + "overall status=%d, pending=%d, addr=%sfound", + status, ares->ares_status, ares->num_pending, + ares->temp_ai ? "" : "not "); } #endif @@ -736,7 +764,8 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data, return NULL; /* initial status - failed */ - ares->last_status = ARES_ENOTFOUND; + ares->ares_status = ARES_ENOTFOUND; + ares->result = CURLE_OK; #ifdef HAVE_CARES_GETADDRINFO { @@ -758,7 +787,8 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data, (pf == PF_UNSPEC) ? "A+AAAA" : ((pf == PF_INET) ? "A" : "AAAA")); hints.ai_family = pf; - hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP) ? + hints.ai_socktype = + (Curl_conn_get_transport(data, data->conn) == 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 diff --git a/vendor/curl/lib/asyn-base.c b/vendor/curl/lib/asyn-base.c index ea89fba15c3..c0df7aac5e0 100644 --- a/vendor/curl/lib/asyn-base.c +++ b/vendor/curl/lib/asyn-base.c @@ -70,7 +70,7 @@ #endif /* - * Curl_ares_getsock() is called when the outside world (using + * Curl_ares_pollset() is called when the outside world (using * curl_multi_fdset()) wants to get our fd_set setup and we are talking with * ares. The caller must make sure that this function is only called when we * have a working ares channel. @@ -78,18 +78,38 @@ * Returns: sockets-in-use-bitmap */ -int Curl_ares_getsock(struct Curl_easy *data, - ares_channel channel, - curl_socket_t *socks) + +CURLcode Curl_ares_pollset(struct Curl_easy *data, + ares_channel channel, + struct easy_pollset *ps) { struct timeval maxtime = { CURL_TIMEOUT_RESOLVE, 0 }; struct timeval timebuf; - int max = ares_getsock(channel, - (ares_socket_t *)socks, MAX_SOCKSPEREASYHANDLE); - struct timeval *timeout = ares_timeout(channel, &maxtime, &timebuf); - timediff_t milli = curlx_tvtoms(timeout); + curl_socket_t sockets[16]; /* ARES documented limit */ + unsigned int bitmap, i; + struct timeval *timeout; + timediff_t milli; + CURLcode result = CURLE_OK; + + bitmap = ares_getsock(channel, (ares_socket_t *)sockets, + CURL_ARRAYSIZE(sockets)); + for(i = 0; i < CURL_ARRAYSIZE(sockets); ++i) { + int flags = 0; + if(ARES_GETSOCK_READABLE(bitmap, i)) + flags |= CURL_POLL_IN; + if(ARES_GETSOCK_WRITABLE(bitmap, i)) + flags |= CURL_POLL_OUT; + if(!flags) + break; + result = Curl_pollset_change(data, ps, sockets[i], flags, 0); + if(result) + return result; + } + + timeout = ares_timeout(channel, &maxtime, &timebuf); + milli = curlx_tvtoms(timeout); Curl_expire(data, milli, EXPIRE_ASYNC_NAME); - return max; + return result; } /* diff --git a/vendor/curl/lib/asyn-thrdd.c b/vendor/curl/lib/asyn-thrdd.c index 9cd25dcd209..509ec427a87 100644 --- a/vendor/curl/lib/asyn-thrdd.c +++ b/vendor/curl/lib/asyn-thrdd.c @@ -55,14 +55,15 @@ #endif #include "urldata.h" +#include "cfilters.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 "select.h" #include "strdup.h" #ifdef USE_ARES @@ -159,7 +160,7 @@ addr_ctx_create(const char *hostname, int port, DEBUGASSERT(hints); addr_ctx->hints = *hints; #else - (void) hints; + (void)hints; #endif Curl_mutex_init(&addr_ctx->mutx); @@ -172,7 +173,7 @@ addr_ctx_create(const char *hostname, int port, goto err_exit; } #endif - addr_ctx->sock_error = CURL_ASYNC_SUCCESS; + addr_ctx->sock_error = 0; /* Copying hostname string because original can be destroyed by parent * thread during gethostbyname execution. @@ -203,13 +204,7 @@ addr_ctx_create(const char *hostname, int port, * For builds without ARES, but with USE_IPV6, create a resolver thread * and wait on it. */ -static -#if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE) -DWORD -#else -unsigned int -#endif -CURL_STDCALL getaddrinfo_thread(void *arg) +static CURL_THREAD_RETURN_T CURL_STDCALL getaddrinfo_thread(void *arg) { struct async_thrdd_addr_ctx *addr_ctx = arg; char service[12]; @@ -242,7 +237,7 @@ CURL_STDCALL getaddrinfo_thread(void *arg) #endif /* DNS has been resolved, signal client task */ if(wakeup_write(addr_ctx->sock_pair[1], buf, sizeof(buf)) < 0) { - /* update sock_erro to errno */ + /* update sock_error to errno */ addr_ctx->sock_error = SOCKERRNO; } } @@ -263,13 +258,7 @@ CURL_STDCALL getaddrinfo_thread(void *arg) /* * gethostbyname_thread() resolves a name and then exits. */ -static -#if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE) -DWORD -#else -unsigned int -#endif -CURL_STDCALL gethostbyname_thread(void *arg) +static CURL_THREAD_RETURN_T CURL_STDCALL gethostbyname_thread(void *arg) { struct async_thrdd_addr_ctx *addr_ctx = arg; bool all_gone; @@ -379,6 +368,14 @@ static CURLcode async_rr_start(struct Curl_easy *data) thrdd->rr.channel = NULL; return CURLE_FAILED_INIT; } +#ifdef CURLDEBUG + if(getenv("CURL_DNS_SERVER")) { + const char *servers = getenv("CURL_DNS_SERVER"); + status = ares_set_servers_ports_csv(thrdd->rr.channel, servers); + if(status) + return CURLE_FAILED_INIT; + } +#endif memset(&thrdd->rr.hinfo, 0, sizeof(thrdd->rr.hinfo)); thrdd->rr.hinfo.port = -1; @@ -386,6 +383,7 @@ static CURLcode async_rr_start(struct Curl_easy *data) data->conn->host.name, ARES_CLASS_IN, ARES_REC_TYPE_HTTPS, async_thrdd_rr_done, data, NULL); + CURL_TRC_DNS(data, "Issued HTTPS-RR request for %s", data->conn->host.name); return CURLE_OK; } #endif @@ -423,6 +421,7 @@ static bool async_thrdd_init(struct Curl_easy *data, data->state.async.done = FALSE; data->state.async.port = port; data->state.async.ip_version = ip_version; + free(data->state.async.hostname); data->state.async.hostname = strdup(hostname); if(!data->state.async.hostname) goto err_exit; @@ -640,33 +639,25 @@ CURLcode Curl_async_is_resolved(struct Curl_easy *data, } } -int Curl_async_getsock(struct Curl_easy *data, curl_socket_t *socks) +CURLcode Curl_async_pollset(struct Curl_easy *data, struct easy_pollset *ps) { struct async_thrdd_ctx *thrdd = &data->state.async.thrdd; - int ret_val = 0; -#if !defined(CURL_DISABLE_SOCKETPAIR) || defined(USE_HTTPSRR_ARES) - int socketi = 0; -#else - (void)socks; -#endif + CURLcode result = CURLE_OK; #ifdef USE_HTTPSRR_ARES if(thrdd->rr.channel) { - ret_val = Curl_ares_getsock(data, thrdd->rr.channel, socks); - for(socketi = 0; socketi < (MAX_SOCKSPEREASYHANDLE - 1); socketi++) - if(!ARES_GETSOCK_READABLE(ret_val, socketi) && - !ARES_GETSOCK_WRITABLE(ret_val, socketi)) - break; + result = Curl_ares_pollset(data, thrdd->rr.channel, ps); + if(result) + return result; } #endif if(!thrdd->addr) - return ret_val; + return result; #ifndef CURL_DISABLE_SOCKETPAIR if(thrdd->addr) { /* return read fd to client for polling the DNS resolution status */ - socks[socketi] = thrdd->addr->sock_pair[0]; - ret_val |= GETSOCK_READSOCK(socketi); + result = Curl_pollset_add_in(data, ps, thrdd->addr->sock_pair[0]); } else #endif @@ -684,7 +675,7 @@ int Curl_async_getsock(struct Curl_easy *data, curl_socket_t *socks) Curl_expire(data, milli, EXPIRE_ASYNC_NAME); } - return ret_val; + return result; } #ifndef HAVE_GETADDRINFO @@ -741,7 +732,8 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data, memset(&hints, 0, sizeof(hints)); hints.ai_family = pf; - hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP) ? + hints.ai_socktype = + (Curl_conn_get_transport(data, data->conn) == TRNSPRT_TCP) ? SOCK_STREAM : SOCK_DGRAM; /* fire up a new resolver thread! */ diff --git a/vendor/curl/lib/asyn.h b/vendor/curl/lib/asyn.h index 1cc7175bebc..de7cd8406bb 100644 --- a/vendor/curl/lib/asyn.h +++ b/vendor/curl/lib/asyn.h @@ -37,6 +37,7 @@ struct Curl_dns_entry; struct addrinfo; struct hostent; struct connectdata; +struct easy_pollset; #if defined(CURLRES_ARES) && defined(CURLRES_THREADED) #error cannot have both CURLRES_ARES and CURLRES_THREADED defined @@ -70,15 +71,15 @@ void Curl_async_global_cleanup(void); */ CURLcode Curl_async_get_impl(struct Curl_easy *easy, void **impl); -/* Curl_async_getsock() +/* Curl_async_pollset() * - * This function is called from the Curl_multi_getsock() function. 'sock' is a + * This function is called from the Curl_multi_pollset() 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_async_getsock(struct Curl_easy *data, curl_socket_t *sock); +CURLcode Curl_async_pollset(struct Curl_easy *data, struct easy_pollset *ps); /* * Curl_async_is_resolved() @@ -127,9 +128,10 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data, /* common functions for c-ares and threaded resolver with HTTPSRR */ #include -int Curl_ares_getsock(struct Curl_easy *data, - ares_channel channel, - curl_socket_t *socks); +CURLcode Curl_ares_pollset(struct Curl_easy *data, + ares_channel channel, + struct easy_pollset *ps); + int Curl_ares_perform(ares_channel channel, timediff_t timeout_ms); #endif @@ -141,7 +143,7 @@ struct async_ares_ctx { int num_pending; /* number of outstanding c-ares requests */ struct Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares parts */ - int last_status; + int ares_status; /* ARES_SUCCESS, ARES_ENOTFOUND, etc. */ CURLcode result; /* CURLE_OK or error handling response */ #ifndef HAVE_CARES_GETADDRINFO struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */ @@ -236,7 +238,7 @@ struct doh_probes; #ifdef USE_CURL_ASYNC struct Curl_async { -#ifdef CURLRES_ARES /* */ +#ifdef CURLRES_ARES struct async_ares_ctx ares; #elif defined(CURLRES_THREADED) struct async_thrdd_ctx thrdd; diff --git a/vendor/curl/lib/bufq.c b/vendor/curl/lib/bufq.c index 724d62f31cd..9919707b4c5 100644 --- a/vendor/curl/lib/bufq.c +++ b/vendor/curl/lib/bufq.c @@ -86,44 +86,26 @@ static size_t chunk_read(struct buf_chunk *chunk, } } -static size_t chunk_unwrite(struct buf_chunk *chunk, size_t len) -{ - size_t n = chunk->w_offset - chunk->r_offset; - DEBUGASSERT(chunk->w_offset >= chunk->r_offset); - if(!n) { - return 0; - } - else if(n <= len) { - chunk->r_offset = chunk->w_offset = 0; - return n; - } - else { - chunk->w_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) +static CURLcode chunk_slurpn(struct buf_chunk *chunk, size_t max_len, + Curl_bufq_reader *reader, + void *reader_ctx, size_t *pnread) { unsigned char *p = &chunk->x.data[chunk->w_offset]; size_t n = chunk->dlen - chunk->w_offset; /* free amount */ - ssize_t nread; + CURLcode result; + *pnread = 0; DEBUGASSERT(chunk->dlen >= chunk->w_offset); - if(!n) { - *err = CURLE_AGAIN; - return -1; - } + if(!n) + return CURLE_AGAIN; 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; + result = reader(reader_ctx, p, n, pnread); + if(!result) { + DEBUGASSERT(*pnread <= n); + chunk->w_offset += *pnread; } - return nread; + return result; } static void chunk_peek(const struct buf_chunk *chunk, @@ -192,6 +174,12 @@ static CURLcode bufcp_take(struct bufc_pool *pool, return CURLE_OK; } + /* Check for integer overflow before allocation */ + if(pool->chunk_size > SIZE_MAX - sizeof(*chunk)) { + *pchunk = NULL; + return CURLE_OUT_OF_MEMORY; + } + chunk = calloc(1, sizeof(*chunk) + pool->chunk_size); if(!chunk) { *pchunk = NULL; @@ -320,6 +308,11 @@ static struct buf_chunk *get_spare(struct bufq *q) return chunk; } else { + /* Check for integer overflow before allocation */ + if(q->chunk_size > SIZE_MAX - sizeof(*chunk)) { + return NULL; + } + chunk = calloc(1, sizeof(*chunk) + q->chunk_size); if(!chunk) return NULL; @@ -357,49 +350,6 @@ static void prune_head(struct bufq *q) } } -static struct buf_chunk *chunk_prev(struct buf_chunk *head, - struct buf_chunk *chunk) -{ - while(head) { - if(head == chunk) - return NULL; - if(head->next == chunk) - return head; - head = head->next; - } - return NULL; -} - -static void prune_tail(struct bufq *q) -{ - struct buf_chunk *chunk; - - while(q->tail && chunk_is_empty(q->tail)) { - chunk = q->tail; - q->tail = chunk_prev(q->head, chunk); - if(q->tail) - q->tail->next = NULL; - if(q->head == chunk) - q->head = q->tail; - 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; @@ -421,90 +371,60 @@ static struct buf_chunk *get_non_full_tail(struct bufq *q) return chunk; } -ssize_t Curl_bufq_write(struct bufq *q, - const unsigned char *buf, size_t len, - CURLcode *err) +CURLcode Curl_bufq_write(struct bufq *q, + const unsigned char *buf, size_t len, + size_t *pnwritten) { struct buf_chunk *tail; - ssize_t nwritten = 0; size_t n; DEBUGASSERT(q->max_chunks > 0); + *pnwritten = 0; while(len) { tail = get_non_full_tail(q); if(!tail) { - if((q->chunk_count < q->max_chunks) || (q->opts & BUFQ_OPT_SOFT_LIMIT)) { - *err = CURLE_OUT_OF_MEMORY; - return -1; - } + if((q->chunk_count < q->max_chunks) || (q->opts & BUFQ_OPT_SOFT_LIMIT)) + /* should have gotten a tail, but did not */ + return CURLE_OUT_OF_MEMORY; break; } n = chunk_append(tail, buf, len); if(!n) break; - nwritten += n; + *pnwritten += n; buf += n; len -= n; } - if(nwritten == 0 && len) { - *err = CURLE_AGAIN; - return -1; - } - *err = CURLE_OK; - return nwritten; + return (!*pnwritten && len) ? CURLE_AGAIN : CURLE_OK; } CURLcode Curl_bufq_cwrite(struct bufq *q, const char *buf, size_t len, size_t *pnwritten) { - ssize_t n; - CURLcode result; - n = Curl_bufq_write(q, (const unsigned char *)buf, len, &result); - *pnwritten = (n < 0) ? 0 : (size_t)n; - return result; + return Curl_bufq_write(q, (const unsigned char *)buf, len, pnwritten); } -CURLcode Curl_bufq_unwrite(struct bufq *q, size_t len) +CURLcode Curl_bufq_read(struct bufq *q, unsigned char *buf, size_t len, + size_t *pnread) { - while(len && q->tail) { - len -= chunk_unwrite(q->tail, len); - prune_tail(q); - } - return len ? CURLE_AGAIN : CURLE_OK; -} - -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; + *pnread = 0; while(len && q->head) { - n = chunk_read(q->head, buf, len); + size_t n = chunk_read(q->head, buf, len); if(n) { - nread += n; + *pnread += n; buf += n; len -= n; } prune_head(q); } - if(nread == 0) { - *err = CURLE_AGAIN; - return -1; - } - return nread; + return (!*pnread) ? CURLE_AGAIN : CURLE_OK; } CURLcode Curl_bufq_cread(struct bufq *q, char *buf, size_t len, size_t *pnread) { - ssize_t n; - CURLcode result; - n = Curl_bufq_read(q, (unsigned char *)buf, len, &result); - *pnread = (n < 0) ? 0 : (size_t)n; - return result; + return Curl_bufq_read(q, (unsigned char *)buf, len, pnread); } bool Curl_bufq_peek(struct bufq *q, @@ -556,156 +476,139 @@ void Curl_bufq_skip(struct bufq *q, size_t amount) } } -ssize_t Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer, - void *writer_ctx, CURLcode *err) +CURLcode Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer, + void *writer_ctx, size_t *pwritten) { const unsigned char *buf; size_t blen; - ssize_t nwritten = 0; + CURLcode result = CURLE_OK; + *pwritten = 0; while(Curl_bufq_peek(q, &buf, &blen)) { - ssize_t chunk_written; + size_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; + result = writer(writer_ctx, buf, blen, &chunk_written); + if(result) { + if((result == CURLE_AGAIN) && *pwritten) { + /* blocked on subsequent write, report success */ + result = CURLE_OK; } break; } if(!chunk_written) { - if(!nwritten) { + if(!*pwritten) { /* treat as blocked */ - *err = CURLE_AGAIN; - nwritten = -1; + result = CURLE_AGAIN; } break; } - Curl_bufq_skip(q, (size_t)chunk_written); - nwritten += chunk_written; + *pwritten += chunk_written; + Curl_bufq_skip(q, chunk_written); } - return nwritten; + return result; } -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) +CURLcode Curl_bufq_write_pass(struct bufq *q, + const unsigned char *buf, size_t len, + Curl_bufq_writer *writer, void *writer_ctx, + size_t *pwritten) { - ssize_t nwritten = 0, n; + CURLcode result = CURLE_OK; + size_t n; - *err = CURLE_OK; + *pwritten = 0; 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) { + result = Curl_bufq_pass(q, writer, writer_ctx, &n); + if(result) { + if(result != CURLE_AGAIN) { /* real error, fail */ - return -1; + return result; } /* 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) { + /* Add to bufq as much as there is room for */ + result = Curl_bufq_write(q, buf, len, &n); + if(result) { + if(result != CURLE_AGAIN) /* real error, fail */ - return -1; - } - /* no room in bufq */ - break; + return result; + if((result == CURLE_AGAIN) && *pwritten) + /* we did write successfully before */ + result = CURLE_OK; + return result; } - /* edge case of writer returning 0 (and len is >0) - * break or we might enter an infinite loop here */ - if(n == 0) + else if(n == 0) + /* edge case of writer returning 0 (and len is >0) + * break or we might enter an infinite loop here */ break; - /* Maybe only part of `data` has been added, continue to loop */ - buf += (size_t)n; - len -= (size_t)n; - nwritten += (size_t)n; + /* Track what we added to bufq */ + buf += n; + len -= n; + *pwritten += n; } - if(!nwritten && len) { - *err = CURLE_AGAIN; - return -1; - } - *err = CURLE_OK; - return nwritten; + return (!*pwritten && len) ? CURLE_AGAIN : CURLE_OK; } -ssize_t Curl_bufq_sipn(struct bufq *q, size_t max_len, - Curl_bufq_reader *reader, void *reader_ctx, - CURLcode *err) +CURLcode Curl_bufq_sipn(struct bufq *q, size_t max_len, + Curl_bufq_reader *reader, void *reader_ctx, + size_t *pnread) { struct buf_chunk *tail = NULL; - ssize_t nread; - *err = CURLE_AGAIN; + *pnread = 0; tail = get_non_full_tail(q); if(!tail) { - if(q->chunk_count < q->max_chunks) { - *err = CURLE_OUT_OF_MEMORY; - return -1; - } + if(q->chunk_count < q->max_chunks) + return CURLE_OUT_OF_MEMORY; /* full, blocked */ - *err = CURLE_AGAIN; - return -1; + return CURLE_AGAIN; } - 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; + return chunk_slurpn(tail, max_len, reader, reader_ctx, pnread); } /** * 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 + * Returns the total amount of buf read (may be 0) in `pnread` or error + * Note that even in case of an error 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) +static CURLcode bufq_slurpn(struct bufq *q, size_t max_len, + Curl_bufq_reader *reader, void *reader_ctx, + size_t *pnread) { - ssize_t nread = 0, n; + CURLcode result; - *err = CURLE_AGAIN; + *pnread = 0; while(1) { - - n = Curl_bufq_sipn(q, max_len, reader, reader_ctx, err); - if(n < 0) { - if(!nread || *err != CURLE_AGAIN) { + size_t n; + result = Curl_bufq_sipn(q, max_len, reader, reader_ctx, &n); + if(result) { + if(!*pnread || result != CURLE_AGAIN) { /* blocked on first read or real error, fail */ - nread = -1; + return result; } - else - *err = CURLE_OK; + result = CURLE_OK; break; } else if(n == 0) { /* eof */ - *err = CURLE_OK; + result = CURLE_OK; break; } - nread += (size_t)n; + *pnread += n; if(max_len) { - DEBUGASSERT((size_t)n <= max_len); - max_len -= (size_t)n; + DEBUGASSERT(n <= max_len); + max_len -= n; if(!max_len) break; } @@ -713,11 +616,11 @@ static ssize_t bufq_slurpn(struct bufq *q, size_t max_len, if(q->tail && !chunk_is_full(q->tail)) break; } - return nread; + return result; } -ssize_t Curl_bufq_slurp(struct bufq *q, Curl_bufq_reader *reader, - void *reader_ctx, CURLcode *err) +CURLcode Curl_bufq_slurp(struct bufq *q, Curl_bufq_reader *reader, + void *reader_ctx, size_t *pnread) { - return bufq_slurpn(q, 0, reader, reader_ctx, err); + return bufq_slurpn(q, 0, reader, reader_ctx, pnread); } diff --git a/vendor/curl/lib/bufq.h b/vendor/curl/lib/bufq.h index 60059deb30f..7cd1826a955 100644 --- a/vendor/curl/lib/bufq.h +++ b/vendor/curl/lib/bufq.h @@ -163,31 +163,22 @@ 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. + * 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); - -CURLcode Curl_bufq_cwrite(struct bufq *q, - const char *buf, size_t len, +CURLcode Curl_bufq_write(struct bufq *q, + const unsigned char *buf, size_t len, size_t *pnwritten); -/** - * Remove `len` bytes from the end of the buffer queue again. - * Returns CURLE_AGAIN if less than `len` bytes were in the queue. - */ -CURLcode Curl_bufq_unwrite(struct bufq *q, size_t len); +CURLcode Curl_bufq_cwrite(struct bufq *q, + const char *buf, size_t len, + size_t *pnwritten); /** * 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); +CURLcode Curl_bufq_read(struct bufq *q, unsigned char *buf, size_t len, + size_t *pnread); CURLcode Curl_bufq_cread(struct bufq *q, char *buf, size_t len, size_t *pnread); @@ -214,9 +205,9 @@ bool Curl_bufq_peek_at(struct bufq *q, size_t offset, */ 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); +typedef CURLcode Curl_bufq_writer(void *writer_ctx, + const unsigned char *buf, size_t len, + size_t *pwritten); /** * 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 @@ -226,24 +217,23 @@ typedef ssize_t Curl_bufq_writer(void *writer_ctx, * 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); +CURLcode Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer, + void *writer_ctx, size_t *pwritten); -typedef ssize_t Curl_bufq_reader(void *reader_ctx, - unsigned char *buf, size_t len, - CURLcode *err); +typedef CURLcode Curl_bufq_reader(void *reader_ctx, + unsigned char *buf, size_t len, + size_t *pnread); /** * 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 + * CURLE_AGAIN to indicate blocking. + * Returns the total amount of buf read (may be 0) in `pnread` on success. + * Note that in case of an error 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); +CURLcode Curl_bufq_slurp(struct bufq *q, Curl_bufq_reader *reader, + void *reader_ctx, size_t *pnread); /** * Read *once* up to `max_len` bytes and append it to the buffer. @@ -251,9 +241,9 @@ ssize_t Curl_bufq_slurp(struct bufq *q, Curl_bufq_reader *reader, * 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); +CURLcode Curl_bufq_sipn(struct bufq *q, size_t max_len, + Curl_bufq_reader *reader, void *reader_ctx, + size_t *pnread); /** * Write buf to the end of the buffer queue. @@ -262,9 +252,9 @@ ssize_t Curl_bufq_sipn(struct bufq *q, size_t max_len, * 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); +CURLcode Curl_bufq_write_pass(struct bufq *q, + const unsigned char *buf, size_t len, + Curl_bufq_writer *writer, void *writer_ctx, + size_t *pwritten); #endif /* HEADER_CURL_BUFQ_H */ diff --git a/vendor/curl/lib/cf-h1-proxy.c b/vendor/curl/lib/cf-h1-proxy.c index df6f575454a..798d6e9f668 100644 --- a/vendor/curl/lib/cf-h1-proxy.c +++ b/vendor/curl/lib/cf-h1-proxy.c @@ -252,7 +252,7 @@ static CURLcode send_CONNECT(struct Curl_cfilter *cf, size_t request_len = curlx_dyn_len(&ts->request_data); size_t blen = request_len; CURLcode result = CURLE_OK; - ssize_t nwritten; + size_t nwritten; if(blen <= ts->nsent) goto out; /* we are done */ @@ -260,16 +260,15 @@ static CURLcode send_CONNECT(struct Curl_cfilter *cf, blen -= ts->nsent; buf += ts->nsent; - nwritten = cf->next->cft->do_send(cf->next, data, buf, blen, FALSE, &result); - if(nwritten < 0) { - if(result == CURLE_AGAIN) { + result = cf->next->cft->do_send(cf->next, data, buf, blen, FALSE, &nwritten); + if(result) { + if(result == CURLE_AGAIN) result = CURLE_OK; - } goto out; } - DEBUGASSERT(blen >= (size_t)nwritten); - ts->nsent += (size_t)nwritten; + DEBUGASSERT(blen >= nwritten); + ts->nsent += nwritten; Curl_debug(data, CURLINFO_HEADER_OUT, buf, (size_t)nwritten); out: @@ -375,11 +374,8 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf, error = SELECT_OK; *done = FALSE; - if(!Curl_conn_data_pending(data, cf->sockindex)) - return CURLE_OK; - while(ts->keepon) { - ssize_t nread; + size_t nread; char byte; /* Read one byte at a time to avoid a race condition. Wait at most one @@ -397,7 +393,7 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf, break; } - if(nread <= 0) { + if(!nread) { if(data->set.proxyauth && data->state.authproxy.avail && data->state.aptr.proxyuserpwd) { /* proxy auth was requested and there was proxy auth available, @@ -686,11 +682,12 @@ static CURLcode cf_h1_proxy_connect(struct Curl_cfilter *cf, return result; } -static void cf_h1_proxy_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) +static CURLcode cf_h1_proxy_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { struct h1_tunnel_state *ts = cf->ctx; + CURLcode result = CURLE_OK; if(!cf->connected) { /* If we are not connected, but the filter "below" is @@ -702,13 +699,14 @@ static void cf_h1_proxy_adjust_pollset(struct Curl_cfilter *cf, response headers or if we are still sending the request, wait for write. */ if(tunnel_want_send(ts)) - Curl_pollset_set_out_only(data, ps, sock); + result = Curl_pollset_set_out_only(data, ps, sock); else - Curl_pollset_set_in_only(data, ps, sock); + result = Curl_pollset_set_in_only(data, ps, sock); } else - Curl_pollset_set_out_only(data, ps, sock); + result = Curl_pollset_set_out_only(data, ps, sock); } + return result; } static void cf_h1_proxy_destroy(struct Curl_cfilter *cf, @@ -741,7 +739,6 @@ struct Curl_cftype Curl_cft_h1_proxy = { cf_h1_proxy_connect, cf_h1_proxy_close, Curl_cf_def_shutdown, - Curl_cf_http_proxy_get_host, cf_h1_proxy_adjust_pollset, Curl_cf_def_data_pending, Curl_cf_def_send, @@ -749,7 +746,7 @@ struct Curl_cftype Curl_cft_h1_proxy = { Curl_cf_def_cntrl, Curl_cf_def_conn_is_alive, Curl_cf_def_conn_keep_alive, - Curl_cf_def_query, + Curl_cf_http_proxy_query, }; CURLcode Curl_cf_h1_proxy_insert_after(struct Curl_cfilter *cf_at, diff --git a/vendor/curl/lib/cf-h2-proxy.c b/vendor/curl/lib/cf-h2-proxy.c index d3bc4b07680..18803ed50b4 100644 --- a/vendor/curl/lib/cf-h2-proxy.c +++ b/vendor/curl/lib/cf-h2-proxy.c @@ -24,10 +24,12 @@ #include "curl_setup.h" -#if defined(USE_NGHTTP2) && !defined(CURL_DISABLE_PROXY) +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_PROXY) && \ + defined(USE_NGHTTP2) #include #include "urldata.h" +#include "url.h" #include "cfilters.h" #include "connect.h" #include "curl_trc.h" @@ -39,6 +41,7 @@ #include "http_proxy.h" #include "multiif.h" #include "sendf.h" +#include "select.h" #include "cf-h2-proxy.h" /* The last 3 #include files should be in this order */ @@ -80,7 +83,7 @@ struct tunnel_stream { }; static CURLcode tunnel_stream_init(struct Curl_cfilter *cf, - struct tunnel_stream *ts) + struct tunnel_stream *ts) { const char *hostname; int port; @@ -218,58 +221,28 @@ static void drain_tunnel(struct Curl_cfilter *cf, struct tunnel_stream *tunnel) { struct cf_h2_proxy_ctx *ctx = cf->ctx; - unsigned char bits; - (void)cf; - bits = CURL_CSELECT_IN; if(!tunnel->closed && !tunnel->reset && !Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) - bits |= CURL_CSELECT_OUT; - if(data->state.select_bits != bits) { - CURL_TRC_CF(data, cf, "[%d] DRAIN select_bits=%x", - tunnel->stream_id, bits); - data->state.select_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; + Curl_multi_mark_dirty(data); } -static ssize_t proxy_h2_nw_out_writer(void *writer_ctx, - const unsigned char *buf, size_t buflen, - CURLcode *err) +static CURLcode proxy_h2_nw_out_writer(void *writer_ctx, + const unsigned char *buf, size_t buflen, + size_t *pnwritten) { struct Curl_cfilter *cf = writer_ctx; - ssize_t nwritten; - + *pnwritten = 0; if(cf) { struct Curl_easy *data = CF_DATA_CURRENT(cf); - nwritten = Curl_conn_cf_send(cf->next, data, (const char *)buf, buflen, - FALSE, err); - CURL_TRC_CF(data, cf, "[0] nw_out_writer(len=%zu) -> %zd, %d", - buflen, nwritten, *err); - } - else { - nwritten = 0; + CURLcode result; + result = Curl_conn_cf_send(cf->next, data, (const char *)buf, buflen, + FALSE, pnwritten); + CURL_TRC_CF(data, cf, "[0] nw_out_writer(len=%zu) -> %d, %zu", + buflen, result, *pnwritten); + return result; } - return nwritten; + return CURLE_FAILED_INIT; } static int proxy_h2_client_new(struct Curl_cfilter *cf, @@ -297,8 +270,8 @@ static int proxy_h2_client_new(struct Curl_cfilter *cf, } static ssize_t on_session_send(nghttp2_session *h2, - const uint8_t *buf, size_t blen, - int flags, void *userp); + 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); @@ -414,16 +387,16 @@ 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; + size_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) { + result = Curl_bufq_pass(&ctx->outbufq, proxy_h2_nw_out_writer, cf, + &nwritten); + if(result) { if(result == CURLE_AGAIN) { CURL_TRC_CF(data, cf, "[0] flush nw send buffer(%zu) -> EAGAIN", Curl_bufq_len(&ctx->outbufq)); @@ -479,7 +452,7 @@ static CURLcode proxy_h2_progress_ingress(struct Curl_cfilter *cf, { struct cf_h2_proxy_ctx *ctx = cf->ctx; CURLcode result = CURLE_OK; - ssize_t nread; + size_t nread; /* Process network input buffer fist */ if(!Curl_bufq_is_empty(&ctx->inbufq)) { @@ -496,10 +469,10 @@ static CURLcode proxy_h2_progress_ingress(struct Curl_cfilter *cf, 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) { + result = Curl_cf_recv_bufq(cf->next, data, &ctx->inbufq, 0, &nread); + CURL_TRC_CF(data, cf, "[0] read %zu bytes nw data -> %d, %zu", + Curl_bufq_len(&ctx->inbufq), result, nread); + if(result) { if(result != CURLE_AGAIN) { failf(data, "Failed receiving HTTP2 data"); return result; @@ -547,17 +520,18 @@ static ssize_t on_session_send(nghttp2_session *h2, struct Curl_cfilter *cf = userp; struct cf_h2_proxy_ctx *ctx = cf->ctx; struct Curl_easy *data = CF_DATA_CURRENT(cf); - ssize_t nwritten; + size_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) { + result = Curl_bufq_write_pass(&ctx->outbufq, buf, blen, + proxy_h2_nw_out_writer, cf, &nwritten); + if(result) { if(result == CURLE_AGAIN) { + ctx->nw_out_blocked = 1; return NGHTTP2_ERR_WOULDBLOCK; } failf(data, "Failed sending HTTP2 data"); @@ -567,7 +541,8 @@ static ssize_t on_session_send(nghttp2_session *h2, if(!nwritten) return NGHTTP2_ERR_WOULDBLOCK; - return nwritten; + return (nwritten > SSIZE_T_MAX) ? + NGHTTP2_ERR_CALLBACK_FAILURE : (ssize_t)nwritten; } #ifndef CURL_DISABLE_VERBOSE_STRINGS @@ -817,7 +792,7 @@ static ssize_t tunnel_send_callback(nghttp2_session *session, struct Curl_easy *data = CF_DATA_CURRENT(cf); struct tunnel_stream *ts; CURLcode result; - ssize_t nread; + size_t nread; (void)source; (void)data; @@ -831,8 +806,8 @@ static ssize_t tunnel_send_callback(nghttp2_session *session, return NGHTTP2_ERR_CALLBACK_FAILURE; DEBUGASSERT(ts == &ctx->tunnel); - nread = Curl_bufq_read(&ts->sendbuf, buf, length, &result); - if(nread < 0) { + result = Curl_bufq_read(&ts->sendbuf, buf, length, &nread); + if(result) { if(result != CURLE_AGAIN) return NGHTTP2_ERR_CALLBACK_FAILURE; return NGHTTP2_ERR_DEFERRED; @@ -842,7 +817,8 @@ static ssize_t tunnel_send_callback(nghttp2_session *session, CURL_TRC_CF(data, cf, "[%d] tunnel_send_callback -> %zd", ts->stream_id, nread); - return nread; + return (nread > SSIZE_T_MAX) ? + NGHTTP2_ERR_CALLBACK_FAILURE : (ssize_t)nread; } static int tunnel_recv_callback(nghttp2_session *session, uint8_t flags, @@ -851,7 +827,7 @@ static int tunnel_recv_callback(nghttp2_session *session, uint8_t flags, { struct Curl_cfilter *cf = userp; struct cf_h2_proxy_ctx *ctx = cf->ctx; - ssize_t nwritten; + size_t nwritten; CURLcode result; (void)flags; @@ -861,14 +837,15 @@ static int tunnel_recv_callback(nghttp2_session *session, uint8_t flags, 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) { + result = Curl_bufq_write(&ctx->tunnel.recvbuf, mem, len, &nwritten); + if(result) { if(result != CURLE_AGAIN) return NGHTTP2_ERR_CALLBACK_FAILURE; #ifdef DEBUGBUILD nwritten = 0; #endif } + /* tunnel.recbuf has soft limit, any success MUST add all data */ DEBUGASSERT((size_t)nwritten == len); return 0; } @@ -1226,14 +1203,15 @@ static bool cf_h2_proxy_data_pending(struct Curl_cfilter *cf, return cf->next ? cf->next->cft->has_data_pending(cf->next, data) : FALSE; } -static void cf_h2_proxy_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) +static CURLcode cf_h2_proxy_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { struct cf_h2_proxy_ctx *ctx = cf->ctx; struct cf_call_data save; curl_socket_t sock = Curl_conn_cf_get_socket(cf, data); bool want_recv, want_send; + CURLcode result = CURLE_OK; if(!cf->connected && ctx->h2) { want_send = nghttp2_session_want_write(ctx->h2) || @@ -1258,9 +1236,9 @@ static void cf_h2_proxy_adjust_pollset(struct Curl_cfilter *cf, !Curl_bufq_is_empty(&ctx->outbufq) || !Curl_bufq_is_empty(&ctx->tunnel.sendbuf); - Curl_pollset_set(data, ps, sock, want_recv, want_send); - CURL_TRC_CF(data, cf, "adjust_pollset, want_recv=%d want_send=%d", - want_recv, want_send); + result = Curl_pollset_set(data, ps, sock, want_recv, want_send); + CURL_TRC_CF(data, cf, "adjust_pollset, want_recv=%d want_send=%d -> %d", + want_recv, want_send, result); CF_DATA_RESTORE(cf, save); } else if(ctx->sent_goaway && !cf->shutdown) { @@ -1270,219 +1248,187 @@ static void cf_h2_proxy_adjust_pollset(struct Curl_cfilter *cf, !Curl_bufq_is_empty(&ctx->outbufq) || !Curl_bufq_is_empty(&ctx->tunnel.sendbuf); want_recv = nghttp2_session_want_read(ctx->h2); - Curl_pollset_set(data, ps, sock, want_recv, want_send); - CURL_TRC_CF(data, cf, "adjust_pollset, want_recv=%d want_send=%d", - want_recv, want_send); + result = Curl_pollset_set(data, ps, sock, want_recv, want_send); + CURL_TRC_CF(data, cf, "adjust_pollset, want_recv=%d want_send=%d -> %d", + want_recv, want_send, result); CF_DATA_RESTORE(cf, save); } + return result; } -static ssize_t h2_handle_tunnel_close(struct Curl_cfilter *cf, - struct Curl_easy *data, - CURLcode *err) +static CURLcode h2_handle_tunnel_close(struct Curl_cfilter *cf, + struct Curl_easy *data, + size_t *pnread) { struct cf_h2_proxy_ctx *ctx = cf->ctx; - ssize_t rv = 0; + *pnread = 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"); /* do not use this anymore */ - *err = CURLE_RECV_ERROR; /* trigger Curl_retry_request() later */ - return -1; + return CURLE_RECV_ERROR; /* trigger Curl_retry_request() later */ } 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; + return CURLE_HTTP2_STREAM; } else if(ctx->tunnel.reset) { failf(data, "HTTP/2 stream %u was reset", ctx->tunnel.stream_id); - *err = CURLE_RECV_ERROR; - return -1; + return CURLE_RECV_ERROR; } - *err = CURLE_OK; - rv = 0; - CURL_TRC_CF(data, cf, "[%d] handle_tunnel_close -> %zd, %d", - ctx->tunnel.stream_id, rv, *err); - return rv; + CURL_TRC_CF(data, cf, "[%d] handle_tunnel_close -> 0", + ctx->tunnel.stream_id); + return CURLE_OK; } -static ssize_t tunnel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t len, CURLcode *err) +static CURLcode tunnel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, + char *buf, size_t len, size_t *pnread) { 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); - } + CURLcode result = CURLE_AGAIN; - if(nread < 0) { + *pnread = 0; + if(!Curl_bufq_is_empty(&ctx->tunnel.recvbuf)) + result = Curl_bufq_cread(&ctx->tunnel.recvbuf, buf, len, pnread); + else { if(ctx->tunnel.closed) { - nread = h2_handle_tunnel_close(cf, data, err); + result = h2_handle_tunnel_close(cf, data, pnread); } else if(ctx->tunnel.reset || (ctx->conn_closed && Curl_bufq_is_empty(&ctx->inbufq)) || (ctx->rcvd_goaway && ctx->last_stream_id < ctx->tunnel.stream_id)) { - *err = CURLE_RECV_ERROR; - nread = -1; + result = CURLE_RECV_ERROR; } - } - else if(nread == 0) { - *err = CURLE_AGAIN; - nread = -1; + else + result = CURLE_AGAIN; } -out: - CURL_TRC_CF(data, cf, "[%d] tunnel_recv(len=%zu) -> %zd, %d", - ctx->tunnel.stream_id, len, nread, *err); - return nread; + CURL_TRC_CF(data, cf, "[%d] tunnel_recv(len=%zu) -> %d, %zu", + ctx->tunnel.stream_id, len, result, *pnread); + return result; } -static ssize_t cf_h2_proxy_recv(struct Curl_cfilter *cf, - struct Curl_easy *data, - char *buf, size_t len, CURLcode *err) +static CURLcode cf_h2_proxy_recv(struct Curl_cfilter *cf, + struct Curl_easy *data, + char *buf, size_t len, + size_t *pnread) { struct cf_h2_proxy_ctx *ctx = cf->ctx; - ssize_t nread = -1; struct cf_call_data save; CURLcode result; + *pnread = 0; + CF_DATA_SAVE(save, cf, data); + if(ctx->tunnel.state != H2_TUNNEL_ESTABLISHED) { - *err = CURLE_RECV_ERROR; - return -1; + result = CURLE_RECV_ERROR; + goto out; } - CF_DATA_SAVE(save, cf, data); if(Curl_bufq_is_empty(&ctx->tunnel.recvbuf)) { - *err = proxy_h2_progress_ingress(cf, data); - if(*err) + result = proxy_h2_progress_ingress(cf, data); + if(result) goto out; } - nread = tunnel_recv(cf, data, buf, len, err); + result = tunnel_recv(cf, data, buf, len, pnread); - 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); + if(!result) { + CURL_TRC_CF(data, cf, "[%d] increase window by %zu", + ctx->tunnel.stream_id, *pnread); + nghttp2_session_consume(ctx->h2, ctx->tunnel.stream_id, *pnread); } - result = proxy_h2_progress_egress(cf, data); - if(result && (result != CURLE_AGAIN)) { - *err = result; - nread = -1; - } + result = Curl_1st_fatal(result, proxy_h2_progress_egress(cf, data)); out: if(!Curl_bufq_is_empty(&ctx->tunnel.recvbuf) && - (nread >= 0 || *err == CURLE_AGAIN)) { + (!result || (result == 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); + CURL_TRC_CF(data, cf, "[%d] cf_recv(len=%zu) -> %d, %zu", + ctx->tunnel.stream_id, len, result, *pnread); CF_DATA_RESTORE(cf, save); - return nread; + return result; } -static ssize_t cf_h2_proxy_send(struct Curl_cfilter *cf, - struct Curl_easy *data, - const void *buf, size_t len, bool eos, - CURLcode *err) +static CURLcode cf_h2_proxy_send(struct Curl_cfilter *cf, + struct Curl_easy *data, + const void *buf, size_t len, bool eos, + size_t *pnwritten) { struct cf_h2_proxy_ctx *ctx = cf->ctx; struct cf_call_data save; int rv; - ssize_t nwritten; CURLcode result; (void)eos; + *pnwritten = 0; + CF_DATA_SAVE(save, cf, data); + if(ctx->tunnel.state != H2_TUNNEL_ESTABLISHED) { - *err = CURLE_SEND_ERROR; - return -1; + result = CURLE_SEND_ERROR; + goto out; } - CF_DATA_SAVE(save, cf, data); if(ctx->tunnel.closed) { - nwritten = -1; - *err = CURLE_SEND_ERROR; + result = CURLE_SEND_ERROR; goto out; } - else { - nwritten = Curl_bufq_write(&ctx->tunnel.sendbuf, buf, len, err); - if(nwritten < 0 && (*err != CURLE_AGAIN)) - goto out; - } + + result = Curl_bufq_write(&ctx->tunnel.sendbuf, buf, len, pnwritten); + CURL_TRC_CF(data, cf, "cf_send(), bufq_write %d, %zd", result, *pnwritten); + if(result && (result != CURLE_AGAIN)) + goto out; 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; + result = CURLE_SEND_ERROR; 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 && (result != CURLE_AGAIN)) { - *err = result; - nwritten = -1; - goto out; - } + result = Curl_1st_fatal(result, proxy_h2_progress_ingress(cf, data)); + result = Curl_1st_fatal(result, proxy_h2_progress_egress(cf, data)); - if(proxy_h2_should_close_session(ctx)) { + if(!result && 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; + result = CURLE_SEND_ERROR; } else { CURL_TRC_CF(data, cf, "[0] send: nothing to do in this session"); - *err = CURLE_HTTP2; - nwritten = -1; + result = CURLE_HTTP2; } } out: if(!Curl_bufq_is_empty(&ctx->tunnel.recvbuf) && - (nwritten >= 0 || *err == CURLE_AGAIN)) { + (!result || (result == 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, " + CURL_TRC_CF(data, cf, "[%d] cf_send(len=%zu) -> %d, %zu, " "h2 windows %d-%d (stream-conn), buffers %zu-%zu (stream-conn)", - ctx->tunnel.stream_id, len, nwritten, *err, + ctx->tunnel.stream_id, len, result, *pnwritten, 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; + return result; } static CURLcode cf_h2_proxy_flush(struct Curl_cfilter *cf, @@ -1533,11 +1479,11 @@ static bool proxy_h2_connisalive(struct Curl_cfilter *cf, not in use by any other transfer, there should not be any data here, only "protocol frames" */ CURLcode result; - ssize_t nread = -1; + size_t nread; *input_pending = FALSE; - nread = Curl_bufq_slurp(&ctx->inbufq, proxy_nw_in_reader, cf, &result); - if(nread != -1) { + result = Curl_cf_recv_bufq(cf->next, data, &ctx->inbufq, 0, &nread); + if(!result) { if(proxy_h2_process_pending_input(cf, data, &result) < 0) /* immediate error, considered dead */ alive = FALSE; @@ -1559,15 +1505,16 @@ static bool cf_h2_proxy_is_alive(struct Curl_cfilter *cf, bool *input_pending) { struct cf_h2_proxy_ctx *ctx = cf->ctx; - CURLcode result; + bool alive; struct cf_call_data save; + *input_pending = FALSE; CF_DATA_SAVE(save, cf, data); - result = (ctx && ctx->h2 && proxy_h2_connisalive(cf, data, input_pending)); + alive = (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); + alive, *input_pending); CF_DATA_RESTORE(cf, save); - return result; + return alive; } static CURLcode cf_h2_proxy_query(struct Curl_cfilter *cf, @@ -1577,6 +1524,10 @@ static CURLcode cf_h2_proxy_query(struct Curl_cfilter *cf, struct cf_h2_proxy_ctx *ctx = cf->ctx; switch(query) { + case CF_QUERY_HOST_PORT: + *pres1 = (int)cf->conn->http_proxy.port; + *((const char **)pres2) = cf->conn->http_proxy.host.name; + return CURLE_OK; case CF_QUERY_NEED_FLUSH: { if(!Curl_bufq_is_empty(&ctx->outbufq) || !Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) { @@ -1586,6 +1537,12 @@ static CURLcode cf_h2_proxy_query(struct Curl_cfilter *cf, } break; } + case CF_QUERY_ALPN_NEGOTIATED: { + const char **palpn = pres2; + DEBUGASSERT(palpn); + *palpn = NULL; + return CURLE_OK; + } default: break; } @@ -1624,7 +1581,6 @@ struct Curl_cftype Curl_cft_h2_proxy = { cf_h2_proxy_connect, cf_h2_proxy_close, cf_h2_proxy_shutdown, - Curl_cf_http_proxy_get_host, cf_h2_proxy_adjust_pollset, cf_h2_proxy_data_pending, cf_h2_proxy_send, @@ -1660,4 +1616,4 @@ CURLcode Curl_cf_h2_proxy_insert_after(struct Curl_cfilter *cf, return result; } -#endif /* defined(USE_NGHTTP2) && !defined(CURL_DISABLE_PROXY) */ +#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY && USE_NGHTTP2 */ diff --git a/vendor/curl/lib/cf-h2-proxy.h b/vendor/curl/lib/cf-h2-proxy.h index c01bf62133b..1b3f85aaaff 100644 --- a/vendor/curl/lib/cf-h2-proxy.h +++ b/vendor/curl/lib/cf-h2-proxy.h @@ -33,7 +33,6 @@ CURLcode Curl_cf_h2_proxy_insert_after(struct Curl_cfilter *cf, extern struct Curl_cftype Curl_cft_h2_proxy; - -#endif /* defined(USE_NGHTTP2) && !defined(CURL_DISABLE_PROXY) */ +#endif /* USE_NGHTTP2 && !CURL_DISABLE_PROXY */ #endif /* HEADER_CURL_H2_PROXY_H */ diff --git a/vendor/curl/lib/cf-haproxy.c b/vendor/curl/lib/cf-haproxy.c index 7bc12dbbb15..2d66efea904 100644 --- a/vendor/curl/lib/cf-haproxy.c +++ b/vendor/curl/lib/cf-haproxy.c @@ -24,7 +24,7 @@ #include "curl_setup.h" -#if !defined(CURL_DISABLE_PROXY) +#ifndef CURL_DISABLE_PROXY #include #include "urldata.h" @@ -32,6 +32,7 @@ #include "cf-haproxy.h" #include "curl_trc.h" #include "multiif.h" +#include "select.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -72,7 +73,7 @@ static CURLcode cf_haproxy_date_out_set(struct Curl_cfilter*cf, CURLcode result; const char *client_ip; struct ip_quadruple ipquad; - int is_ipv6; + bool is_ipv6; DEBUGASSERT(ctx); DEBUGASSERT(ctx->state == HAPROXY_INIT); @@ -131,17 +132,17 @@ static CURLcode cf_haproxy_connect(struct Curl_cfilter *cf, case HAPROXY_SEND: len = curlx_dyn_len(&ctx->data_out); if(len > 0) { - ssize_t nwritten; - nwritten = Curl_conn_cf_send(cf->next, data, - curlx_dyn_ptr(&ctx->data_out), len, FALSE, - &result); - if(nwritten < 0) { + size_t nwritten; + result = Curl_conn_cf_send(cf->next, data, + curlx_dyn_ptr(&ctx->data_out), len, FALSE, + &nwritten); + if(result) { if(result != CURLE_AGAIN) goto out; result = CURLE_OK; nwritten = 0; } - curlx_dyn_tail(&ctx->data_out, len - (size_t)nwritten); + curlx_dyn_tail(&ctx->data_out, len - nwritten); if(curlx_dyn_len(&ctx->data_out) > 0) { result = CURLE_OK; goto out; @@ -178,15 +179,17 @@ static void cf_haproxy_close(struct Curl_cfilter *cf, cf->next->cft->do_close(cf->next, data); } -static void cf_haproxy_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) +static CURLcode cf_haproxy_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { if(cf->next->connected && !cf->connected) { /* If we are not connected, but the filter "below" is * and not waiting on something, we are sending. */ - Curl_pollset_set_out_only(data, ps, Curl_conn_cf_get_socket(cf, data)); + return Curl_pollset_set_out_only( + data, ps, Curl_conn_cf_get_socket(cf, data)); } + return CURLE_OK; } struct Curl_cftype Curl_cft_haproxy = { @@ -197,7 +200,6 @@ struct Curl_cftype Curl_cft_haproxy = { cf_haproxy_connect, cf_haproxy_close, Curl_cf_def_shutdown, - Curl_cf_def_get_host, cf_haproxy_adjust_pollset, Curl_cf_def_data_pending, Curl_cf_def_send, diff --git a/vendor/curl/lib/cf-haproxy.h b/vendor/curl/lib/cf-haproxy.h index d02c323e7b7..9190dd5b578 100644 --- a/vendor/curl/lib/cf-haproxy.h +++ b/vendor/curl/lib/cf-haproxy.h @@ -27,7 +27,7 @@ #include "curl_setup.h" #include "urldata.h" -#if !defined(CURL_DISABLE_PROXY) +#ifndef CURL_DISABLE_PROXY CURLcode Curl_cf_haproxy_insert_after(struct Curl_cfilter *cf_at, struct Curl_easy *data); diff --git a/vendor/curl/lib/cf-https-connect.c b/vendor/curl/lib/cf-https-connect.c index cd0d226efda..b4a46052950 100644 --- a/vendor/curl/lib/cf-https-connect.c +++ b/vendor/curl/lib/cf-https-connect.c @@ -24,7 +24,7 @@ #include "curl_setup.h" -#if !defined(CURL_DISABLE_HTTP) +#ifndef CURL_DISABLE_HTTP #include "urldata.h" #include @@ -35,6 +35,7 @@ #include "multiif.h" #include "cf-https-connect.h" #include "http2.h" +#include "select.h" #include "vquic/vquic.h" /* The last 3 #include files should be in this order */ @@ -55,6 +56,7 @@ struct cf_hc_baller { CURLcode result; struct curltime started; int reply_ms; + unsigned char transport; enum alpnid alpn_id; BIT(shutdown); }; @@ -117,17 +119,20 @@ struct cf_hc_ctx { CURLcode result; /* overall result */ struct cf_hc_baller ballers[2]; size_t baller_count; - unsigned int soft_eyeballs_timeout_ms; - unsigned int hard_eyeballs_timeout_ms; + timediff_t soft_eyeballs_timeout_ms; + timediff_t hard_eyeballs_timeout_ms; }; static void cf_hc_baller_assign(struct cf_hc_baller *b, - enum alpnid alpn_id) + enum alpnid alpn_id, + unsigned char def_transport) { b->alpn_id = alpn_id; + b->transport = def_transport; switch(b->alpn_id) { case ALPN_h3: b->name = "h3"; + b->transport = TRNSPRT_QUIC; break; case ALPN_h2: b->name = "h2"; @@ -218,27 +223,26 @@ static CURLcode baller_connected(struct Curl_cfilter *cf, winner->name, (int)curlx_timediff(curlx_now(), winner->started)); + /* install the winning filter below this one. */ cf->next = winner->cf; winner->cf = NULL; - switch(cf->conn->alpn) { - case CURL_HTTP_VERSION_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; + const char *alpn = Curl_conn_cf_get_alpn_negotiated(cf->next, data); + if(alpn && !strcmp("h2", alpn)) { + result = Curl_http2_switch_at(cf, data); + if(result) { + ctx->state = CF_HC_FAILURE; + ctx->result = result; + return result; + } } -#endif - break; - default: - break; } +#endif + ctx->state = CF_HC_SUCCESS; cf->connected = TRUE; return result; @@ -268,15 +272,16 @@ static bool time_to_start_next(struct Curl_cfilter *cf, } elapsed_ms = curlx_timediff(now, ctx->started); if(elapsed_ms >= ctx->hard_eyeballs_timeout_ms) { - CURL_TRC_CF(data, cf, "hard timeout of %dms reached, starting %s", + CURL_TRC_CF(data, cf, "hard timeout of %" FMT_TIMEDIFF_T "ms reached, " + "starting %s", ctx->hard_eyeballs_timeout_ms, ctx->ballers[idx].name); return TRUE; } if((idx > 0) && (elapsed_ms >= ctx->soft_eyeballs_timeout_ms)) { if(cf_hc_baller_reply_ms(&ctx->ballers[idx - 1], data) < 0) { - CURL_TRC_CF(data, cf, "soft timeout of %dms reached, %s has not " - "seen any data, starting %s", + CURL_TRC_CF(data, cf, "soft timeout of %" FMT_TIMEDIFF_T "ms reached, " + "%s has not seen any data, starting %s", ctx->soft_eyeballs_timeout_ms, ctx->ballers[idx - 1].name, ctx->ballers[idx].name); return TRUE; @@ -311,11 +316,11 @@ static CURLcode cf_hc_connect(struct Curl_cfilter *cf, DEBUGASSERT(!ctx->ballers[i].cf); CURL_TRC_CF(data, cf, "connect, init"); ctx->started = now; - cf_hc_baller_init(&ctx->ballers[0], cf, data, cf->conn->transport); + cf_hc_baller_init(&ctx->ballers[0], cf, data, ctx->ballers[0].transport); if(ctx->baller_count > 1) { Curl_expire(data, ctx->soft_eyeballs_timeout_ms, EXPIRE_ALPN_EYEBALLS); - CURL_TRC_CF(data, cf, "set next attempt to start in %ums", - ctx->soft_eyeballs_timeout_ms); + CURL_TRC_CF(data, cf, "set next attempt to start in %" FMT_TIMEDIFF_T + "ms", ctx->soft_eyeballs_timeout_ms); } ctx->state = CF_HC_CONNECT; FALLTHROUGH(); @@ -330,7 +335,7 @@ static CURLcode cf_hc_connect(struct Curl_cfilter *cf, } if(time_to_start_next(cf, data, 1, now)) { - cf_hc_baller_init(&ctx->ballers[1], cf, data, cf->conn->transport); + cf_hc_baller_init(&ctx->ballers[1], cf, data, ctx->ballers[1].transport); } if((ctx->baller_count > 1) && cf_hc_baller_is_active(&ctx->ballers[1])) { @@ -422,22 +427,24 @@ static CURLcode cf_hc_shutdown(struct Curl_cfilter *cf, return result; } -static void cf_hc_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) +static CURLcode cf_hc_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { + CURLcode result = CURLE_OK; if(!cf->connected) { struct cf_hc_ctx *ctx = cf->ctx; size_t i; - for(i = 0; i < ctx->baller_count; i++) { + for(i = 0; (i < ctx->baller_count) && !result; i++) { struct cf_hc_baller *b = &ctx->ballers[i]; if(!cf_hc_baller_is_active(b)) continue; - Curl_conn_cf_adjust_pollset(b->cf, data, ps); + result = Curl_conn_cf_adjust_pollset(b->cf, data, ps); } - CURL_TRC_CF(data, cf, "adjust_pollset -> %d socks", ps->num); + CURL_TRC_CF(data, cf, "adjust_pollset -> %d, %d socks", result, ps->n); } + return result; } static bool cf_hc_data_pending(struct Curl_cfilter *cf, @@ -561,7 +568,6 @@ struct Curl_cftype Curl_cft_http_connect = { cf_hc_connect, cf_hc_close, cf_hc_shutdown, - Curl_cf_def_get_host, cf_hc_adjust_pollset, cf_hc_data_pending, Curl_cf_def_send, @@ -574,7 +580,8 @@ struct Curl_cftype Curl_cft_http_connect = { static CURLcode cf_hc_create(struct Curl_cfilter **pcf, struct Curl_easy *data, - enum alpnid *alpnids, size_t alpn_count) + enum alpnid *alpnids, size_t alpn_count, + unsigned char def_transport) { struct Curl_cfilter *cf = NULL; struct cf_hc_ctx *ctx; @@ -596,7 +603,7 @@ static CURLcode cf_hc_create(struct Curl_cfilter **pcf, goto out; } for(i = 0; i < alpn_count; ++i) - cf_hc_baller_assign(&ctx->ballers[i], alpnids[i]); + cf_hc_baller_assign(&ctx->ballers[i], alpnids[i], def_transport); for(; i < CURL_ARRAYSIZE(ctx->ballers); ++i) ctx->ballers[i].alpn_id = ALPN_none; ctx->baller_count = alpn_count; @@ -616,13 +623,14 @@ static CURLcode cf_hc_create(struct Curl_cfilter **pcf, static CURLcode cf_http_connect_add(struct Curl_easy *data, struct connectdata *conn, int sockindex, - enum alpnid *alpn_ids, size_t alpn_count) + enum alpnid *alpn_ids, size_t alpn_count, + unsigned char def_transport) { struct Curl_cfilter *cf; CURLcode result = CURLE_OK; DEBUGASSERT(data); - result = cf_hc_create(&cf, data, alpn_ids, alpn_count); + result = cf_hc_create(&cf, data, alpn_ids, alpn_count, def_transport); if(result) goto out; Curl_conn_cf_add(data, conn, sockindex, cf); @@ -679,7 +687,7 @@ CURLcode Curl_cf_https_setup(struct Curl_easy *data, continue; switch(alpn) { case ALPN_h3: - if(Curl_conn_may_http3(data, conn)) + if(Curl_conn_may_http3(data, conn, conn->transport_wanted)) break; /* not possible */ if(data->state.http_neg.allowed & CURL_HTTP_V3x) { CURL_TRC_CF(data, cf, "adding h3 via HTTPS-RR"); @@ -708,7 +716,7 @@ CURLcode Curl_cf_https_setup(struct Curl_easy *data, if((alpn_count < CURL_ARRAYSIZE(alpn_ids)) && (data->state.http_neg.wanted & CURL_HTTP_V3x) && !cf_https_alpns_contain(ALPN_h3, alpn_ids, alpn_count)) { - result = Curl_conn_may_http3(data, conn); + result = Curl_conn_may_http3(data, conn, conn->transport_wanted); if(!result) { CURL_TRC_CF(data, cf, "adding wanted h3"); alpn_ids[alpn_count++] = ALPN_h3; @@ -733,11 +741,13 @@ CURLcode Curl_cf_https_setup(struct Curl_easy *data, /* If we identified ALPNs to use, install our filter. Otherwise, * install nothing, so our call will use a default connect setup. */ if(alpn_count) { - result = cf_http_connect_add(data, conn, sockindex, alpn_ids, alpn_count); + result = cf_http_connect_add(data, conn, sockindex, + alpn_ids, alpn_count, + conn->transport_wanted); } out: return result; } -#endif /* !defined(CURL_DISABLE_HTTP) */ +#endif /* !CURL_DISABLE_HTTP */ diff --git a/vendor/curl/lib/cf-https-connect.h b/vendor/curl/lib/cf-https-connect.h index c36726f0a22..df51b62479d 100644 --- a/vendor/curl/lib/cf-https-connect.h +++ b/vendor/curl/lib/cf-https-connect.h @@ -25,7 +25,7 @@ ***************************************************************************/ #include "curl_setup.h" -#if !defined(CURL_DISABLE_HTTP) +#ifndef CURL_DISABLE_HTTP struct Curl_cfilter; struct Curl_easy; @@ -40,16 +40,10 @@ CURLcode Curl_cf_http_connect_add(struct Curl_easy *data, int sockindex, bool try_h3, bool try_h21); -CURLcode -Curl_cf_http_connect_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data, - bool try_h3, bool try_h21); - - CURLcode Curl_cf_https_setup(struct Curl_easy *data, struct connectdata *conn, int sockindex); -#endif /* !defined(CURL_DISABLE_HTTP) */ +#endif /* !CURL_DISABLE_HTTP */ #endif /* HEADER_CURL_CF_HTTP_H */ diff --git a/vendor/curl/lib/cf-ip-happy.c b/vendor/curl/lib/cf-ip-happy.c new file mode 100644 index 00000000000..59b34ae46ff --- /dev/null +++ b/vendor/curl/lib/cf-ip-happy.c @@ -0,0 +1,950 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "connect.h" +#include "cfilters.h" +#include "cf-ip-happy.h" +#include "curl_trc.h" +#include "multiif.h" +#include "progress.h" +#include "select.h" +#include "vquic/vquic.h" /* for quic cfilters */ + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + + +struct transport_provider { + int transport; + cf_ip_connect_create *cf_create; +}; + +static +#ifndef UNITTESTS +const +#endif +struct transport_provider transport_providers[] = { + { TRNSPRT_TCP, Curl_cf_tcp_create }, +#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP3) + { TRNSPRT_QUIC, Curl_cf_quic_create }, +#endif +#ifndef CURL_DISABLE_TFTP + { TRNSPRT_UDP, Curl_cf_udp_create }, +#endif +#ifdef USE_UNIX_SOCKETS + { TRNSPRT_UNIX, Curl_cf_unix_create }, +#endif +}; + +static cf_ip_connect_create *get_cf_create(int transport) +{ + size_t i; + for(i = 0; i < CURL_ARRAYSIZE(transport_providers); ++i) { + if(transport == transport_providers[i].transport) + return transport_providers[i].cf_create; + } + return NULL; +} + +#ifdef UNITTESTS +/* used by unit2600.c */ +void Curl_debug_set_transport_provider(int transport, + cf_ip_connect_create *cf_create) +{ + size_t i; + for(i = 0; i < CURL_ARRAYSIZE(transport_providers); ++i) { + if(transport == transport_providers[i].transport) { + transport_providers[i].cf_create = cf_create; + return; + } + } +} +#endif /* UNITTESTS */ + + +struct cf_ai_iter { + const struct Curl_addrinfo *head; + const struct Curl_addrinfo *last; + int ai_family; + int n; +}; + +static void cf_ai_iter_init(struct cf_ai_iter *iter, + const struct Curl_addrinfo *list, + int ai_family) +{ + iter->head = list; + iter->ai_family = ai_family; + iter->last = NULL; + iter->n = -1; +} + +static const struct Curl_addrinfo *cf_ai_iter_next(struct cf_ai_iter *iter) +{ + const struct Curl_addrinfo *addr; + if(iter->n < 0) { + iter->n++; + for(addr = iter->head; addr; addr = addr->ai_next) { + if(addr->ai_family == iter->ai_family) + break; + } + iter->last = addr; + } + else if(iter->last) { + iter->n++; + for(addr = iter->last->ai_next; addr; addr = addr->ai_next) { + if(addr->ai_family == iter->ai_family) + break; + } + iter->last = addr; + } + return iter->last; +} + +#ifdef USE_IPV6 +static bool cf_ai_iter_done(struct cf_ai_iter *iter) +{ + return (iter->n >= 0) && !iter->last; +} +#endif + +struct cf_ip_attempt { + struct cf_ip_attempt *next; + const struct Curl_addrinfo *addr; /* List of addresses to try, not owned */ + struct Curl_cfilter *cf; /* current sub-cfilter connecting */ + cf_ip_connect_create *cf_create; + struct curltime started; /* start of current attempt */ + CURLcode result; + int ai_family; + int transport; + int error; + BIT(connected); /* cf has connected */ + BIT(shutdown); /* cf has shutdown */ + BIT(inconclusive); /* connect was not a hard failure, we + * might talk to a restarting server */ +}; + +static void cf_ip_attempt_free(struct cf_ip_attempt *a, + struct Curl_easy *data) +{ + if(a) { + if(a->cf) + Curl_conn_cf_discard_chain(&a->cf, data); + free(a); + } +} + +static CURLcode cf_ip_attempt_new(struct cf_ip_attempt **pa, + struct Curl_cfilter *cf, + struct Curl_easy *data, + const struct Curl_addrinfo *addr, + int ai_family, + int transport, + cf_ip_connect_create *cf_create) +{ + struct Curl_cfilter *wcf; + struct cf_ip_attempt *a; + CURLcode result = CURLE_OK; + + *pa = NULL; + a = calloc(1, sizeof(*a)); + if(!a) + return CURLE_OUT_OF_MEMORY; + + a->addr = addr; + a->ai_family = ai_family; + a->transport = transport; + a->result = CURLE_OK; + a->cf_create = cf_create; + *pa = a; + + result = a->cf_create(&a->cf, data, cf->conn, a->addr, transport); + if(result) + goto out; + + /* the new filter might have sub-filters */ + for(wcf = a->cf; wcf; wcf = wcf->next) { + wcf->conn = cf->conn; + wcf->sockindex = cf->sockindex; + } + +out: + if(result) { + cf_ip_attempt_free(a, data); + *pa = NULL; + } + return result; +} + +static CURLcode cf_ip_attempt_connect(struct cf_ip_attempt *a, + struct Curl_easy *data, + bool *connected) +{ + *connected = a->connected; + if(!a->result && !*connected) { + /* evaluate again */ + a->result = Curl_conn_cf_connect(a->cf, data, connected); + + if(!a->result) { + if(*connected) { + a->connected = TRUE; + } + } + else if(a->result == CURLE_WEIRD_SERVER_REPLY) + a->inconclusive = TRUE; + } + return a->result; +} + +struct cf_ip_ballers { + struct cf_ip_attempt *running; + struct cf_ip_attempt *winner; + struct cf_ai_iter addr_iter; +#ifdef USE_IPV6 + struct cf_ai_iter ipv6_iter; +#endif + cf_ip_connect_create *cf_create; /* for creating cf */ + struct curltime started; + struct curltime last_attempt_started; + timediff_t attempt_delay_ms; + int last_attempt_ai_family; + int transport; +}; + +static CURLcode cf_ip_attempt_restart(struct cf_ip_attempt *a, + struct Curl_cfilter *cf, + struct Curl_easy *data) +{ + struct Curl_cfilter *cf_prev = a->cf; + struct Curl_cfilter *wcf; + CURLcode result; + + /* When restarting, we tear down and existing filter *after* we + * started up the new one. This gives us a new socket number and + * probably a new local port. Which may prevent confusion. */ + a->result = CURLE_OK; + a->connected = FALSE; + a->inconclusive = FALSE; + a->cf = NULL; + + result = a->cf_create(&a->cf, data, cf->conn, a->addr, a->transport); + if(!result) { + bool dummy; + /* the new filter might have sub-filters */ + for(wcf = a->cf; wcf; wcf = wcf->next) { + wcf->conn = cf->conn; + wcf->sockindex = cf->sockindex; + } + a->result = cf_ip_attempt_connect(a, data, &dummy); + } + if(cf_prev) + Curl_conn_cf_discard_chain(&cf_prev, data); + return result; +} + +static void cf_ip_ballers_clear(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct cf_ip_ballers *bs) +{ + (void)cf; + while(bs->running) { + struct cf_ip_attempt *a = bs->running; + bs->running = a->next; + cf_ip_attempt_free(a, data); + } + cf_ip_attempt_free(bs->winner, data); + bs->winner = NULL; +} + +static CURLcode cf_ip_ballers_init(struct cf_ip_ballers *bs, int ip_version, + const struct Curl_addrinfo *addr_list, + cf_ip_connect_create *cf_create, + int transport, + timediff_t attempt_delay_ms) +{ + memset(bs, 0, sizeof(*bs)); + bs->cf_create = cf_create; + bs->transport = transport; + bs->attempt_delay_ms = attempt_delay_ms; + bs->last_attempt_ai_family = AF_INET; /* so AF_INET6 is next */ + + if(transport == TRNSPRT_UNIX) { +#ifdef USE_UNIX_SOCKETS + cf_ai_iter_init(&bs->addr_iter, addr_list, AF_UNIX); +#else + return CURLE_UNSUPPORTED_PROTOCOL; +#endif + } + else { /* TCP/UDP/QUIC */ +#ifdef USE_IPV6 + if(ip_version == CURL_IPRESOLVE_V6) + cf_ai_iter_init(&bs->addr_iter, NULL, AF_INET); + else + cf_ai_iter_init(&bs->addr_iter, addr_list, AF_INET); + + if(ip_version == CURL_IPRESOLVE_V4) + cf_ai_iter_init(&bs->ipv6_iter, NULL, AF_INET6); + else + cf_ai_iter_init(&bs->ipv6_iter, addr_list, AF_INET6); +#else + (void)ip_version; + cf_ai_iter_init(&bs->addr_iter, addr_list, AF_INET); +#endif + } + return CURLE_OK; +} + +static CURLcode cf_ip_ballers_run(struct cf_ip_ballers *bs, + struct Curl_cfilter *cf, + struct Curl_easy *data, + bool *connected) +{ + CURLcode result = CURLE_OK; + struct cf_ip_attempt *a = NULL, **panchor; + bool do_more, more_possible; + struct curltime now; + timediff_t next_expire_ms; + int i, inconclusive, ongoing; + + if(bs->winner) + return CURLE_OK; + +evaluate: + now = curlx_now(); + ongoing = inconclusive = 0; + more_possible = TRUE; + + /* check if a running baller connects now */ + i = -1; + for(panchor = &bs->running; *panchor; panchor = &((*panchor)->next)) { + ++i; + a = *panchor; + a->result = cf_ip_attempt_connect(a, data, connected); + if(!a->result) { + if(*connected) { + /* connected, declare the winner, remove from running, + * clear remaining running list. */ + CURL_TRC_CF(data, cf, "connect attempt #%d successful", i); + bs->winner = a; + *panchor = a->next; + a->next = NULL; + while(bs->running) { + a = bs->running; + bs->running = a->next; + cf_ip_attempt_free(a, data); + } + return CURLE_OK; + } + /* still running */ + ++ongoing; + } + else if(a->inconclusive) /* failed, but inconclusive */ + ++inconclusive; + } + if(bs->running) + CURL_TRC_CF(data, cf, "checked connect attempts: " + "%d ongoing, %d inconclusive", ongoing, inconclusive); + + /* no attempt connected yet, start another one? */ + if(!ongoing) { + if(!bs->started.tv_sec && !bs->started.tv_usec) + bs->started = now; + do_more = TRUE; + } + else { + do_more = (curlx_timediff(now, bs->last_attempt_started) >= + bs->attempt_delay_ms); + if(do_more) + CURL_TRC_CF(data, cf, "happy eyeballs timeout expired, " + "start next attempt"); + } + + if(do_more) { + /* start the next attempt if there is another ip address to try. + * Alternate between address families when possible. */ + const struct Curl_addrinfo *addr = NULL; + int ai_family = 0; +#ifdef USE_IPV6 + if((bs->last_attempt_ai_family == AF_INET) || + cf_ai_iter_done(&bs->addr_iter)) { + addr = cf_ai_iter_next(&bs->ipv6_iter); + ai_family = bs->ipv6_iter.ai_family; + } +#endif + if(!addr) { + addr = cf_ai_iter_next(&bs->addr_iter); + ai_family = bs->addr_iter.ai_family; + } + + if(addr) { /* try another address */ + result = cf_ip_attempt_new(&a, cf, data, addr, ai_family, + bs->transport, bs->cf_create); + CURL_TRC_CF(data, cf, "starting %s attempt for ipv%s -> %d", + bs->running ? "next" : "first", + (ai_family == AF_INET) ? "4" : "6", result); + if(result) + goto out; + DEBUGASSERT(a); + + /* append to running list */ + panchor = &bs->running; + while(*panchor) + panchor = &((*panchor)->next); + *panchor = a; + bs->last_attempt_started = now; + bs->last_attempt_ai_family = ai_family; + /* and run everything again */ + goto evaluate; + } + else if(inconclusive) { + /* tried all addresses, no success but some where inconclusive. + * Let's restart the inconclusive ones. */ + if(curlx_timediff(now, bs->last_attempt_started) >= + bs->attempt_delay_ms) { + CURL_TRC_CF(data, cf, "tried all addresses with inconclusive results" + ", restarting one"); + i = -1; + for(a = bs->running; a; a = a->next) { + ++i; + if(!a->inconclusive) + continue; + result = cf_ip_attempt_restart(a, cf, data); + CURL_TRC_CF(data, cf, "restarted baller %d -> %d", i, result); + if(result) /* serious failure */ + goto out; + bs->last_attempt_started = now; + goto evaluate; + } + DEBUGASSERT(0); /* should not come here */ + } + /* attempt timeout for restart has not expired yet */ + goto out; + } + else if(ongoing) { + /* no more addresses, no inconclusive attempts */ + more_possible = FALSE; + } + else { + CURL_TRC_CF(data, cf, "no more attempts to try"); + result = CURLE_COULDNT_CONNECT; + i = 0; + for(a = bs->running; a; a = a->next) { + CURL_TRC_CF(data, cf, "baller %d: result=%d", i, a->result); + if(a->result) + result = a->result; + } + } + } + +out: + if(!result) { + /* when do we need to be called again? */ + next_expire_ms = Curl_timeleft(data, &now, TRUE); + if(more_possible) { + timediff_t expire_ms, elapsed_ms; + elapsed_ms = curlx_timediff(now, bs->last_attempt_started); + expire_ms = CURLMAX(bs->attempt_delay_ms - elapsed_ms, 0); + next_expire_ms = CURLMIN(next_expire_ms, expire_ms); + } + + if(next_expire_ms <= 0) { + failf(data, "Connection timeout after %" FMT_OFF_T " ms", + curlx_timediff(now, data->progress.t_startsingle)); + return CURLE_OPERATION_TIMEDOUT; + } + Curl_expire(data, next_expire_ms, EXPIRE_HAPPY_EYEBALLS); + } + return result; +} + +static CURLcode cf_ip_ballers_shutdown(struct cf_ip_ballers *bs, + struct Curl_easy *data, + bool *done) +{ + struct cf_ip_attempt *a; + + /* shutdown all ballers that have not done so already. If one fails, + * continue shutting down others until all are shutdown. */ + *done = TRUE; + for(a = bs->running; a; a = a->next) { + bool bdone = FALSE; + if(a->shutdown) + continue; + a->result = a->cf->cft->do_shutdown(a->cf, data, &bdone); + if(a->result || bdone) + a->shutdown = TRUE; /* treat a failed shutdown as done */ + else + *done = FALSE; + } + return CURLE_OK; +} + +static CURLcode cf_ip_ballers_pollset(struct cf_ip_ballers *bs, + struct Curl_easy *data, + struct easy_pollset *ps) +{ + struct cf_ip_attempt *a; + CURLcode result = CURLE_OK; + for(a = bs->running; a && !result; a = a->next) { + if(a->result) + continue; + result = Curl_conn_cf_adjust_pollset(a->cf, data, ps); + } + return result; +} + +static bool cf_ip_ballers_pending(struct cf_ip_ballers *bs, + const struct Curl_easy *data) +{ + struct cf_ip_attempt *a; + + for(a = bs->running; a; a = a->next) { + if(a->result) + continue; + if(a->cf->cft->has_data_pending(a->cf, data)) + return TRUE; + } + return FALSE; +} + +static struct curltime cf_ip_ballers_max_time(struct cf_ip_ballers *bs, + struct Curl_easy *data, + int query) +{ + struct curltime t, tmax; + struct cf_ip_attempt *a; + + memset(&tmax, 0, sizeof(tmax)); + for(a = bs->running; a; a = a->next) { + memset(&t, 0, sizeof(t)); + if(!a->cf->cft->query(a->cf, data, query, NULL, &t)) { + if((t.tv_sec || t.tv_usec) && curlx_timediff_us(t, tmax) > 0) + tmax = t; + } + } + return tmax; +} + +static int cf_ip_ballers_min_reply_ms(struct cf_ip_ballers *bs, + struct Curl_easy *data) +{ + int reply_ms = -1, breply_ms; + struct cf_ip_attempt *a; + + for(a = bs->running; a; a = a->next) { + if(!a->cf->cft->query(a->cf, data, CF_QUERY_CONNECT_REPLY_MS, + &breply_ms, NULL)) { + if(breply_ms >= 0 && (reply_ms < 0 || breply_ms < reply_ms)) + reply_ms = breply_ms; + } + } + return reply_ms; +} + + +typedef enum { + SCFST_INIT, + SCFST_WAITING, + SCFST_DONE +} cf_connect_state; + +struct cf_ip_happy_ctx { + int transport; + cf_ip_connect_create *cf_create; + cf_connect_state state; + struct cf_ip_ballers ballers; + struct curltime started; +}; + + +static CURLcode is_connected(struct Curl_cfilter *cf, + struct Curl_easy *data, + bool *connected) +{ + struct cf_ip_happy_ctx *ctx = cf->ctx; + struct connectdata *conn = cf->conn; + CURLcode result; + + result = cf_ip_ballers_run(&ctx->ballers, cf, data, connected); + + if(!result) + return CURLE_OK; + + { + const char *hostname, *proxy_name = NULL; + int port; +#ifndef CURL_DISABLE_PROXY + if(conn->bits.socksproxy) + proxy_name = conn->socks_proxy.host.name; + else if(conn->bits.httpproxy) + proxy_name = conn->http_proxy.host.name; +#endif + hostname = conn->bits.conn_to_host ? + conn->conn_to_host.name : conn->host.name; + + if(cf->sockindex == SECONDARYSOCKET) + port = conn->secondary_port; + else if(cf->conn->bits.conn_to_port) + port = conn->conn_to_port; + else + port = conn->remote_port; + + failf(data, "Failed to connect to %s port %u %s%s%safter " + "%" FMT_TIMEDIFF_T " ms: %s", + hostname, port, + proxy_name ? "via " : "", + proxy_name ? proxy_name : "", + proxy_name ? " " : "", + curlx_timediff(curlx_now(), data->progress.t_startsingle), + curl_easy_strerror(result)); + } + +#ifdef SOCKETIMEDOUT + if(SOCKETIMEDOUT == data->state.os_errno) + result = CURLE_OPERATION_TIMEDOUT; +#endif + + return result; +} + +/* + * Connect to the given host with timeout, proxy or remote does not matter. + * There might be more than one IP address to try out. + */ +static CURLcode start_connect(struct Curl_cfilter *cf, + struct Curl_easy *data) +{ + struct cf_ip_happy_ctx *ctx = cf->ctx; + struct Curl_dns_entry *dns = data->state.dns[cf->sockindex]; + + if(!dns) + return CURLE_FAILED_INIT; + + if(Curl_timeleft(data, NULL, TRUE) < 0) { + /* a precaution, no need to continue if time already is up */ + failf(data, "Connection time-out"); + return CURLE_OPERATION_TIMEDOUT; + } + + CURL_TRC_CF(data, cf, "init ip ballers for transport %d", ctx->transport); + ctx->started = curlx_now(); + return cf_ip_ballers_init(&ctx->ballers, cf->conn->ip_version, + dns->addr, ctx->cf_create, ctx->transport, + data->set.happy_eyeballs_timeout); +} + +static void cf_ip_happy_ctx_clear(struct Curl_cfilter *cf, + struct Curl_easy *data) +{ + struct cf_ip_happy_ctx *ctx = cf->ctx; + + DEBUGASSERT(ctx); + DEBUGASSERT(data); + cf_ip_ballers_clear(cf, data, &ctx->ballers); +} + +static CURLcode cf_ip_happy_shutdown(struct Curl_cfilter *cf, + struct Curl_easy *data, + bool *done) +{ + struct cf_ip_happy_ctx *ctx = cf->ctx; + CURLcode result = CURLE_OK; + + DEBUGASSERT(data); + if(cf->connected) { + *done = TRUE; + return CURLE_OK; + } + + result = cf_ip_ballers_shutdown(&ctx->ballers, data, done); + CURL_TRC_CF(data, cf, "shutdown -> %d, done=%d", result, *done); + return result; +} + +static CURLcode cf_ip_happy_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) +{ + struct cf_ip_happy_ctx *ctx = cf->ctx; + CURLcode result = CURLE_OK; + + if(!cf->connected) { + result = cf_ip_ballers_pollset(&ctx->ballers, data, ps); + CURL_TRC_CF(data, cf, "adjust_pollset -> %d, %d socks", result, ps->n); + } + return result; +} + +static CURLcode cf_ip_happy_connect(struct Curl_cfilter *cf, + struct Curl_easy *data, + bool *done) +{ + struct cf_ip_happy_ctx *ctx = cf->ctx; + CURLcode result = CURLE_OK; + + if(cf->connected) { + *done = TRUE; + return CURLE_OK; + } + + DEBUGASSERT(ctx); + *done = FALSE; + + switch(ctx->state) { + case SCFST_INIT: + DEBUGASSERT(CURL_SOCKET_BAD == Curl_conn_cf_get_socket(cf, data)); + DEBUGASSERT(!cf->connected); + result = start_connect(cf, data); + if(result) + return result; + ctx->state = SCFST_WAITING; + FALLTHROUGH(); + case SCFST_WAITING: + result = is_connected(cf, data, done); + if(!result && *done) { + DEBUGASSERT(ctx->ballers.winner); + DEBUGASSERT(ctx->ballers.winner->cf); + DEBUGASSERT(ctx->ballers.winner->cf->connected); + /* we have a winner. Install and activate it. + * close/free all others. */ + ctx->state = SCFST_DONE; + cf->connected = TRUE; + cf->next = ctx->ballers.winner->cf; + ctx->ballers.winner->cf = NULL; + cf_ip_happy_ctx_clear(cf, data); + + if(cf->conn->handler->protocol & PROTO_FAMILY_SSH) + Curl_pgrsTime(data, TIMER_APPCONNECT); /* we are connected already */ +#ifndef CURL_DISABLE_VERBOSE_STRINGS + if(Curl_trc_cf_is_verbose(cf, data)) { + struct ip_quadruple ipquad; + bool is_ipv6; + if(!Curl_conn_cf_get_ip_info(cf->next, data, &is_ipv6, &ipquad)) { + const char *host; + int port; + Curl_conn_get_current_host(data, cf->sockindex, &host, &port); + CURL_TRC_CF(data, cf, "Connected to %s (%s) port %u", + host, ipquad.remote_ip, ipquad.remote_port); + } + } +#endif + data->info.numconnects++; /* to track the # of connections made */ + } + break; + case SCFST_DONE: + *done = TRUE; + break; + } + return result; +} + +static void cf_ip_happy_close(struct Curl_cfilter *cf, + struct Curl_easy *data) +{ + struct cf_ip_happy_ctx *ctx = cf->ctx; + + CURL_TRC_CF(data, cf, "close"); + cf_ip_happy_ctx_clear(cf, data); + cf->connected = FALSE; + ctx->state = SCFST_INIT; + + if(cf->next) { + cf->next->cft->do_close(cf->next, data); + Curl_conn_cf_discard_chain(&cf->next, data); + } +} + +static bool cf_ip_happy_data_pending(struct Curl_cfilter *cf, + const struct Curl_easy *data) +{ + struct cf_ip_happy_ctx *ctx = cf->ctx; + + if(!cf->connected) { + return cf_ip_ballers_pending(&ctx->ballers, data); + } + return cf->next->cft->has_data_pending(cf->next, data); +} + +static CURLcode cf_ip_happy_query(struct Curl_cfilter *cf, + struct Curl_easy *data, + int query, int *pres1, void *pres2) +{ + struct cf_ip_happy_ctx *ctx = cf->ctx; + + if(!cf->connected) { + switch(query) { + case CF_QUERY_CONNECT_REPLY_MS: { + *pres1 = cf_ip_ballers_min_reply_ms(&ctx->ballers, data); + CURL_TRC_CF(data, cf, "query connect reply: %dms", *pres1); + return CURLE_OK; + } + case CF_QUERY_TIMER_CONNECT: { + struct curltime *when = pres2; + *when = cf_ip_ballers_max_time(&ctx->ballers, data, + CF_QUERY_TIMER_CONNECT); + return CURLE_OK; + } + case CF_QUERY_TIMER_APPCONNECT: { + struct curltime *when = pres2; + *when = cf_ip_ballers_max_time(&ctx->ballers, 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_ip_happy_destroy(struct Curl_cfilter *cf, + struct Curl_easy *data) +{ + struct cf_ip_happy_ctx *ctx = cf->ctx; + + CURL_TRC_CF(data, cf, "destroy"); + if(ctx) { + cf_ip_happy_ctx_clear(cf, data); + } + /* release any resources held in state */ + Curl_safefree(ctx); +} + +struct Curl_cftype Curl_cft_ip_happy = { + "HAPPY-EYEBALLS", + 0, + CURL_LOG_LVL_NONE, + cf_ip_happy_destroy, + cf_ip_happy_connect, + cf_ip_happy_close, + cf_ip_happy_shutdown, + cf_ip_happy_adjust_pollset, + cf_ip_happy_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_ip_happy_query, +}; + +/** + * Create an IP happy eyeball connection filter that uses the, once resolved, + * address information to connect on ip families based on connection + * configuration. + * @param pcf output, the created cfilter + * @param data easy handle used in creation + * @param conn connection the filter is created for + * @param cf_create method to create the sub-filters performing the + * actual connects. + */ +static CURLcode cf_ip_happy_create(struct Curl_cfilter **pcf, + struct Curl_easy *data, + struct connectdata *conn, + cf_ip_connect_create *cf_create, + int transport) +{ + struct cf_ip_happy_ctx *ctx = NULL; + CURLcode result; + + (void)data; + (void)conn; + *pcf = NULL; + ctx = calloc(1, sizeof(*ctx)); + if(!ctx) { + result = CURLE_OUT_OF_MEMORY; + goto out; + } + ctx->transport = transport; + ctx->cf_create = cf_create; + + result = Curl_cf_create(pcf, &Curl_cft_ip_happy, ctx); + +out: + if(result) { + Curl_safefree(*pcf); + free(ctx); + } + return result; +} + +CURLcode cf_ip_happy_insert_after(struct Curl_cfilter *cf_at, + struct Curl_easy *data, + int transport) +{ + cf_ip_connect_create *cf_create; + struct Curl_cfilter *cf; + CURLcode result; + + /* Need to be first */ + DEBUGASSERT(cf_at); + cf_create = get_cf_create(transport); + if(!cf_create) { + CURL_TRC_CF(data, cf_at, "unsupported transport type %d", transport); + return CURLE_UNSUPPORTED_PROTOCOL; + } + result = cf_ip_happy_create(&cf, data, cf_at->conn, cf_create, transport); + if(result) + return result; + + Curl_conn_cf_insert_after(cf_at, cf); + return CURLE_OK; +} diff --git a/vendor/curl/lib/cf-ip-happy.h b/vendor/curl/lib/cf-ip-happy.h new file mode 100644 index 00000000000..96e619ae430 --- /dev/null +++ b/vendor/curl/lib/cf-ip-happy.h @@ -0,0 +1,59 @@ +#ifndef HEADER_CURL_IP_HAPPY_H +#define HEADER_CURL_IP_HAPPY_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 "curlx/nonblock.h" /* for curlx_nonblock() */ +#include "sockaddr.h" + +/** + * Create a cfilter for making an "ip" connection to the + * given address, using parameters from `conn`. The "ip" connection + * can be a TCP socket, a UDP socket or even a QUIC connection. + * + * It MUST use only the supplied `ai` for its connection attempt. + * + * Such a filter may be used in "happy eyeball" scenarios, and its + * `connect` implementation needs to support non-blocking. Once connected, + * it MAY be installed in the connection filter chain to serve transfers. + */ +typedef CURLcode cf_ip_connect_create(struct Curl_cfilter **pcf, + struct Curl_easy *data, + struct connectdata *conn, + const struct Curl_addrinfo *ai, + int transport); + +CURLcode cf_ip_happy_insert_after(struct Curl_cfilter *cf_at, + struct Curl_easy *data, + int transport); + +extern struct Curl_cftype Curl_cft_ip_happy; + +#ifdef UNITTESTS +void Curl_debug_set_transport_provider(int transport, + cf_ip_connect_create *cf_create); +#endif + +#endif /* HEADER_CURL_IP_HAPPY_H */ diff --git a/vendor/curl/lib/cf-socket.c b/vendor/curl/lib/cf-socket.c index e31977201c6..426caf82d50 100644 --- a/vendor/curl/lib/cf-socket.c +++ b/vendor/curl/lib/cf-socket.c @@ -73,7 +73,6 @@ #include "url.h" /* for Curl_safefree() */ #include "multiif.h" #include "sockaddr.h" /* required for Curl_sockaddr_storage */ -#include "inet_ntop.h" #include "curlx/inet_pton.h" #include "progress.h" #include "curlx/warnless.h" @@ -110,7 +109,7 @@ static void set_ipv6_v6only(curl_socket_t sockfd, int on) static void tcpnodelay(struct Curl_easy *data, curl_socket_t sockfd) { -#if defined(TCP_NODELAY) +#if defined(TCP_NODELAY) && defined(CURL_TCP_NODELAY_SUPPORTED) curl_socklen_t onoff = (curl_socklen_t) 1; int level = IPPROTO_TCP; char buffer[STRERROR_LEN]; @@ -137,7 +136,7 @@ static void nosigpipe(struct Curl_easy *data, (void)data; if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff, sizeof(onoff)) < 0) { -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) +#ifndef CURL_DISABLE_VERBOSE_STRINGS char buffer[STRERROR_LEN]; infof(data, "Could not set SO_NOSIGPIPE: %s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); @@ -165,6 +164,7 @@ static void nosigpipe(struct Curl_easy *data, #define KEEPALIVE_FACTOR(x) #endif +/* Offered by mingw-w64 and MS SDK. Latter only when targeting Win7+. */ #if defined(USE_WINSOCK) && !defined(SIO_KEEPALIVE_VALS) #define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4) @@ -189,9 +189,9 @@ tcpkeepalive(struct Curl_easy *data, sockfd, SOCKERRNO); } else { -#if defined(SIO_KEEPALIVE_VALS) /* Windows */ +#ifdef SIO_KEEPALIVE_VALS /* Windows */ /* Windows 10, version 1709 (10.0.16299) and later versions */ -#if defined(CURL_WINSOCK_KEEP_SSO) +#ifdef CURL_WINSOCK_KEEP_SSO optval = curlx_sltosi(data->set.tcp_keepidle); KEEPALIVE_FACTOR(optval); if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, @@ -308,9 +308,9 @@ tcpkeepalive(struct Curl_easy *data, * Assign the address `ai` to the Curl_sockaddr_ex `dest` and * set the transport used. */ -CURLcode Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest, - const struct Curl_addrinfo *ai, - int transport) +static CURLcode 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 @@ -395,10 +395,10 @@ static CURLcode socket_open(struct Curl_easy *data, * */ CURLcode Curl_socket_open(struct Curl_easy *data, - const struct Curl_addrinfo *ai, - struct Curl_sockaddr_ex *addr, - int transport, - curl_socket_t *sockfd) + const struct Curl_addrinfo *ai, + struct Curl_sockaddr_ex *addr, + int transport, + curl_socket_t *sockfd) { struct Curl_sockaddr_ex dummy; CURLcode result; @@ -407,7 +407,7 @@ CURLcode Curl_socket_open(struct Curl_easy *data, /* if the caller does not want info back, use a local temp copy */ addr = &dummy; - result = Curl_sock_assign_addr(addr, ai, transport); + result = sock_assign_addr(addr, ai, transport); if(result) return result; @@ -845,7 +845,7 @@ static bool verifyconnect(curl_socket_t sockfd, int *error) #endif - if(0 != getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *)&err, &errSize)) + if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *)&err, &errSize)) err = SOCKERRNO; #ifdef UNDER_CE /* Old Windows CE versions do not support SO_ERROR */ @@ -861,7 +861,7 @@ static bool verifyconnect(curl_socket_t sockfd, int *error) err = 0; } #endif - if((0 == err) || (SOCKEISCONN == err)) + if((err == 0) || (SOCKEISCONN == err)) /* we are connected, awesome! */ rc = TRUE; else @@ -886,7 +886,7 @@ static CURLcode socket_connect_result(struct Curl_easy *data, switch(error) { case SOCKEINPROGRESS: case SOCKEWOULDBLOCK: -#if defined(EAGAIN) +#ifdef EAGAIN #if (EAGAIN) != (SOCKEWOULDBLOCK) /* On some platforms EAGAIN and EWOULDBLOCK are the * same value, and on others they are different, hence @@ -950,7 +950,7 @@ static CURLcode cf_socket_ctx_init(struct cf_socket_ctx *ctx, ctx->sock = CURL_SOCKET_BAD; ctx->transport = transport; - result = Curl_sock_assign_addr(&ctx->addr, ai, transport); + result = sock_assign_addr(&ctx->addr, ai, transport); if(result) return result; @@ -996,8 +996,6 @@ static void cf_socket_close(struct Curl_cfilter *cf, struct Curl_easy *data) cf->conn->sock[cf->sockindex] = CURL_SOCKET_BAD; socket_close(data, cf->conn, !ctx->accepted, ctx->sock); ctx->sock = CURL_SOCKET_BAD; - if(ctx->active && cf->sockindex == FIRSTSOCKET) - cf->conn->remote_addr = NULL; ctx->active = FALSE; memset(&ctx->started_at, 0, sizeof(ctx->started_at)); memset(&ctx->connected_at, 0, sizeof(ctx->connected_at)); @@ -1095,7 +1093,7 @@ static CURLcode set_remote_ip(struct Curl_cfilter *cf, } static CURLcode cf_socket_open(struct Curl_cfilter *cf, - struct Curl_easy *data) + struct Curl_easy *data) { struct cf_socket_ctx *ctx = cf->ctx; int error = 0; @@ -1240,8 +1238,8 @@ static int do_connect(struct Curl_cfilter *cf, struct Curl_easy *data, (void)data; if(is_tcp_fastopen) { -#if defined(CONNECT_DATA_IDEMPOTENT) /* Darwin */ -# if defined(HAVE_BUILTIN_AVAILABLE) +#ifdef CONNECT_DATA_IDEMPOTENT /* Darwin */ +# ifdef 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 */ @@ -1378,24 +1376,12 @@ static CURLcode cf_tcp_connect(struct Curl_cfilter *cf, 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) -{ - struct cf_socket_ctx *ctx = cf->ctx; - (void)data; - *phost = cf->conn->host.name; - *pdisplay_host = cf->conn->host.dispname; - *pport = ctx->ip.remote_port; -} - -static void cf_socket_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) +static CURLcode cf_socket_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { struct cf_socket_ctx *ctx = cf->ctx; + CURLcode result = CURLE_OK; if(ctx->sock != CURL_SOCKET_BAD) { /* A listening socket filter needs to be connected before the accept @@ -1403,36 +1389,27 @@ static void cf_socket_adjust_pollset(struct Curl_cfilter *cf, * FTP no longer does the socket checks and accept calls and delegates * all that to the filter. */ if(ctx->listening) { - Curl_pollset_set_in_only(data, ps, ctx->sock); + result = Curl_pollset_set_in_only(data, ps, ctx->sock); CURL_TRC_CF(data, cf, "adjust_pollset, listening, POLLIN fd=%" FMT_SOCKET_T, ctx->sock); } else if(!cf->connected) { - Curl_pollset_set_out_only(data, ps, ctx->sock); + result = Curl_pollset_set_out_only(data, ps, ctx->sock); CURL_TRC_CF(data, cf, "adjust_pollset, !connected, POLLOUT fd=%" FMT_SOCKET_T, ctx->sock); } else if(!ctx->active) { - Curl_pollset_add_in(data, ps, ctx->sock); + result = Curl_pollset_add_in(data, ps, ctx->sock); CURL_TRC_CF(data, cf, "adjust_pollset, !active, POLLIN fd=%" FMT_SOCKET_T, ctx->sock); } } -} - -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; - readable = SOCKET_READABLE(ctx->sock, 0); - return readable > 0 && (readable & CURL_CSELECT_IN); + return result; } #ifdef USE_WINSOCK +/* Offered by mingw-w64 v13+. MS SDK 7.0A+. */ #ifndef SIO_IDEAL_SEND_BACKLOG_QUERY #define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747B #endif @@ -1457,17 +1434,18 @@ static void win_update_sndbuf_size(struct cf_socket_ctx *ctx) #endif /* USE_WINSOCK */ -static ssize_t cf_socket_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, bool eos, - CURLcode *err) +static CURLcode cf_socket_send(struct Curl_cfilter *cf, struct Curl_easy *data, + const void *buf, size_t len, bool eos, + size_t *pnwritten) { struct cf_socket_ctx *ctx = cf->ctx; curl_socket_t fdsave; ssize_t nwritten; size_t orig_len = len; + CURLcode result = CURLE_OK; (void)eos; /* unused */ - *err = CURLE_OK; + *pnwritten = 0; fdsave = cf->conn->sock[cf->sockindex]; cf->conn->sock[cf->sockindex] = ctx->sock; @@ -1478,10 +1456,8 @@ static ssize_t cf_socket_send(struct Curl_cfilter *cf, struct Curl_easy *data, Curl_rand_bytes(data, FALSE, &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; + return CURLE_AGAIN; } } if(cf->cft != &Curl_cft_udp && ctx->wpartial_percent > 0 && len > 8) { @@ -1496,15 +1472,14 @@ static ssize_t cf_socket_send(struct Curl_cfilter *cf, struct Curl_easy *data, #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->curl_sa_addr, - cf->conn->remote_addr->addrlen); + &ctx->addr.curl_sa_addr, ctx->addr.addrlen); cf->conn->bits.tcp_fastopen = FALSE; } else #endif nwritten = swrite(ctx->sock, buf, len); - if(-1 == nwritten) { + if(nwritten < 0) { int sockerr = SOCKERRNO; if( @@ -1521,36 +1496,38 @@ static ssize_t cf_socket_send(struct Curl_cfilter *cf, struct Curl_easy *data, #endif ) { /* this is just a case of EWOULDBLOCK */ - *err = CURLE_AGAIN; + result = 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; + result = CURLE_SEND_ERROR; } } + else + *pnwritten = (size_t)nwritten; -#if defined(USE_WINSOCK) - if(!*err) +#ifdef USE_WINSOCK + if(!result) win_update_sndbuf_size(ctx); #endif - CURL_TRC_CF(data, cf, "send(len=%zu) -> %d, err=%d", - orig_len, (int)nwritten, *err); + CURL_TRC_CF(data, cf, "send(len=%zu) -> %d, %zu", + orig_len, result, *pnwritten); cf->conn->sock[cf->sockindex] = fdsave; - return nwritten; + return result; } -static ssize_t cf_socket_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t len, CURLcode *err) +static CURLcode cf_socket_recv(struct Curl_cfilter *cf, struct Curl_easy *data, + char *buf, size_t len, size_t *pnread) { struct cf_socket_ctx *ctx = cf->ctx; + CURLcode result = CURLE_OK; ssize_t nread; - *err = CURLE_OK; - + *pnread = 0; #ifdef DEBUGBUILD /* simulate network blocking/partial reads */ if(cf->cft != &Curl_cft_udp && ctx->rblock_percent > 0) { @@ -1558,8 +1535,7 @@ static ssize_t cf_socket_recv(struct Curl_cfilter *cf, struct Curl_easy *data, 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; - return -1; + return CURLE_AGAIN; } } if(cf->cft != &Curl_cft_udp && ctx->recv_max && ctx->recv_max < len) { @@ -1570,10 +1546,9 @@ static ssize_t cf_socket_recv(struct Curl_cfilter *cf, struct Curl_easy *data, } #endif - *err = CURLE_OK; nread = sread(ctx->sock, buf, len); - if(-1 == nread) { + if(nread < 0) { int sockerr = SOCKERRNO; if( @@ -1589,25 +1564,25 @@ static ssize_t cf_socket_recv(struct Curl_cfilter *cf, struct Curl_easy *data, #endif ) { /* this is just a case of EWOULDBLOCK */ - *err = CURLE_AGAIN; + result = CURLE_AGAIN; } else { char buffer[STRERROR_LEN]; - failf(data, "Recv failure: %s", Curl_strerror(sockerr, buffer, sizeof(buffer))); data->state.os_errno = sockerr; - *err = CURLE_RECV_ERROR; + result = CURLE_RECV_ERROR; } } + else + *pnread = (size_t)nread; - CURL_TRC_CF(data, cf, "recv(len=%zu) -> %d, err=%d", len, (int)nread, - *err); - if(nread > 0 && !ctx->got_first_byte) { + CURL_TRC_CF(data, cf, "recv(len=%zu) -> %d, %zu", len, result, *pnread); + if(!result && !ctx->got_first_byte) { ctx->first_byte_at = curlx_now(); ctx->got_first_byte = TRUE; } - return nread; + return result; } static void cf_socket_update_data(struct Curl_cfilter *cf, @@ -1629,16 +1604,10 @@ static void cf_socket_active(struct Curl_cfilter *cf, struct Curl_easy *data) /* use this socket from now on */ cf->conn->sock[cf->sockindex] = ctx->sock; set_local_ip(cf, data); - if(cf->sockindex == FIRSTSOCKET) { - cf->conn->primary = ctx->ip; - cf->conn->remote_addr = &ctx->addr; - #ifdef USE_IPV6 +#ifdef USE_IPV6 + if(cf->sockindex == FIRSTSOCKET) cf->conn->bits.ipv6 = (ctx->addr.family == AF_INET6); - #endif - } - else { - cf->conn->secondary = ctx->ip; - } +#endif ctx->active = TRUE; } @@ -1713,6 +1682,15 @@ static CURLcode cf_socket_query(struct Curl_cfilter *cf, DEBUGASSERT(pres2); *((curl_socket_t *)pres2) = ctx->sock; return CURLE_OK; + case CF_QUERY_TRANSPORT: + DEBUGASSERT(pres1); + *pres1 = ctx->transport; + return CURLE_OK; + case CF_QUERY_REMOTE_ADDR: + DEBUGASSERT(pres2); + *((const struct Curl_sockaddr_ex **)pres2) = cf->connected ? + &ctx->addr : NULL; + return CURLE_OK; case CF_QUERY_CONNECT_REPLY_MS: if(ctx->got_first_byte) { timediff_t ms = curlx_timediff(ctx->first_byte_at, ctx->started_at); @@ -1763,9 +1741,8 @@ struct Curl_cftype Curl_cft_tcp = { cf_tcp_connect, cf_socket_close, cf_socket_shutdown, - cf_socket_get_host, cf_socket_adjust_pollset, - cf_socket_data_pending, + Curl_cf_def_data_pending, cf_socket_send, cf_socket_recv, cf_socket_cntrl, @@ -1918,9 +1895,8 @@ struct Curl_cftype Curl_cft_udp = { cf_udp_connect, cf_socket_close, cf_socket_shutdown, - cf_socket_get_host, cf_socket_adjust_pollset, - cf_socket_data_pending, + Curl_cf_def_data_pending, cf_socket_send, cf_socket_recv, cf_socket_cntrl, @@ -1973,9 +1949,8 @@ struct Curl_cftype Curl_cft_unix = { cf_tcp_connect, cf_socket_close, cf_socket_shutdown, - cf_socket_get_host, cf_socket_adjust_pollset, - cf_socket_data_pending, + Curl_cf_def_data_pending, cf_socket_send, cf_socket_recv, cf_socket_cntrl, @@ -2020,7 +1995,7 @@ CURLcode Curl_cf_unix_create(struct Curl_cfilter **pcf, } static timediff_t cf_tcp_accept_timeleft(struct Curl_cfilter *cf, - struct Curl_easy *data) + struct Curl_easy *data) { struct cf_socket_ctx *ctx = cf->ctx; timediff_t timeout_ms = DEFAULT_ACCEPT_TIMEOUT; @@ -2135,7 +2110,7 @@ static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf, return CURLE_OK; } - if(0 == getsockname(ctx->sock, (struct sockaddr *) &add, &size)) { + if(!getsockname(ctx->sock, (struct sockaddr *) &add, &size)) { size = sizeof(add); #ifdef HAVE_ACCEPT4 s_accepted = accept4(ctx->sock, (struct sockaddr *) &add, &size, @@ -2194,9 +2169,8 @@ struct Curl_cftype Curl_cft_tcp_accept = { cf_tcp_accept_connect, cf_socket_close, cf_socket_shutdown, - cf_socket_get_host, cf_socket_adjust_pollset, - cf_socket_data_pending, + Curl_cf_def_data_pending, cf_socket_send, cf_socket_recv, cf_socket_cntrl, @@ -2222,7 +2196,7 @@ CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data, result = CURLE_OUT_OF_MEMORY; goto out; } - ctx->transport = conn->transport; + ctx->transport = TRNSPRT_TCP; ctx->sock = *s; ctx->listening = TRUE; ctx->accepted = FALSE; diff --git a/vendor/curl/lib/cf-socket.h b/vendor/curl/lib/cf-socket.h index d3e35098421..88c08fe7c0c 100644 --- a/vendor/curl/lib/cf-socket.h +++ b/vendor/curl/lib/cf-socket.h @@ -68,10 +68,10 @@ CURLcode Curl_parse_interface(const char *input, * */ CURLcode Curl_socket_open(struct Curl_easy *data, - const struct Curl_addrinfo *ai, - struct Curl_sockaddr_ex *addr, - int transport, - curl_socket_t *sockfd); + 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); @@ -91,14 +91,6 @@ void Curl_sndbuf_init(curl_socket_t sockfd); #define Curl_sndbuf_init(y) Curl_nop_stmt #endif -/** - * Assign the address `ai` to the Curl_sockaddr_ex `dest` and - * set the transport used. - */ -CURLcode 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. diff --git a/vendor/curl/lib/cfilters.c b/vendor/curl/lib/cfilters.c index 00090f0c719..efd2ac6f63d 100644 --- a/vendor/curl/lib/cfilters.c +++ b/vendor/curl/lib/cfilters.c @@ -67,27 +67,15 @@ CURLcode Curl_cf_def_shutdown(struct Curl_cfilter *cf, 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->primary.remote_port; - } -} - -void Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) +CURLcode Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { /* NOP */ (void)cf; (void)data; (void)ps; + return CURLE_OK; } bool Curl_cf_def_data_pending(struct Curl_cfilter *cf, @@ -97,21 +85,23 @@ bool Curl_cf_def_data_pending(struct Curl_cfilter *cf, cf->next->cft->has_data_pending(cf->next, data) : FALSE; } -ssize_t Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data, +CURLcode Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data, const void *buf, size_t len, bool eos, - CURLcode *err) + size_t *pnwritten) { - return cf->next ? - cf->next->cft->do_send(cf->next, data, buf, len, eos, err) : - CURLE_RECV_ERROR; + if(cf->next) + return cf->next->cft->do_send(cf->next, data, buf, len, eos, pnwritten); + *pnwritten = 0; + return CURLE_RECV_ERROR; } -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_recv(struct Curl_cfilter *cf, struct Curl_easy *data, + char *buf, size_t len, size_t *pnread) { - return cf->next ? - cf->next->cft->do_recv(cf->next, data, buf, len, err) : - CURLE_SEND_ERROR; + if(cf->next) + return cf->next->cft->do_recv(cf->next, data, buf, len, pnread); + *pnread = 0; + return CURLE_SEND_ERROR; } bool Curl_cf_def_conn_is_alive(struct Curl_cfilter *cf, @@ -187,6 +177,10 @@ CURLcode Curl_conn_shutdown(struct Curl_easy *data, int sockindex, bool *done) struct curltime now; DEBUGASSERT(data->conn); + + if(!CONN_SOCK_IDX_VALID(sockindex)) + return CURLE_BAD_FUNCTION_ARGUMENT; + /* Get the first connected filter that is not shut down already. */ cf = data->conn->cfilter[sockindex]; while(cf && (!cf->connected || cf->shutdown)) @@ -234,52 +228,102 @@ CURLcode Curl_conn_shutdown(struct Curl_easy *data, int sockindex, bool *done) return result; } -ssize_t Curl_cf_recv(struct Curl_easy *data, int num, char *buf, - size_t len, CURLcode *code) +CURLcode Curl_cf_recv(struct Curl_easy *data, int num, char *buf, + size_t len, size_t *pnread) { struct Curl_cfilter *cf; DEBUGASSERT(data); DEBUGASSERT(data->conn); - *code = CURLE_OK; cf = data->conn->cfilter[num]; - while(cf && !cf->connected) { + while(cf && !cf->connected) cf = cf->next; - } - if(cf) { - ssize_t nread = cf->cft->do_recv(cf, data, buf, len, code); - DEBUGASSERT(nread >= 0 || *code); - DEBUGASSERT(nread < 0 || !*code); - return nread; - } + if(cf) + return cf->cft->do_recv(cf, data, buf, len, pnread); failf(data, "recv: no filter connected"); - *code = CURLE_FAILED_INIT; - return -1; + DEBUGASSERT(0); + *pnread = 0; + return CURLE_FAILED_INIT; } -ssize_t Curl_cf_send(struct Curl_easy *data, int num, - const void *mem, size_t len, bool eos, - CURLcode *code) +CURLcode Curl_cf_send(struct Curl_easy *data, int num, + const void *mem, size_t len, bool eos, + size_t *pnwritten) { struct Curl_cfilter *cf; DEBUGASSERT(data); DEBUGASSERT(data->conn); - *code = CURLE_OK; cf = data->conn->cfilter[num]; - while(cf && !cf->connected) { + while(cf && !cf->connected) cf = cf->next; - } if(cf) { - ssize_t nwritten = cf->cft->do_send(cf, data, mem, len, eos, code); - DEBUGASSERT(nwritten >= 0 || *code); - DEBUGASSERT(nwritten < 0 || !*code || !len); - return nwritten; + return cf->cft->do_send(cf, data, mem, len, eos, pnwritten); } failf(data, "send: no filter connected"); DEBUGASSERT(0); - *code = CURLE_FAILED_INIT; - return -1; + *pnwritten = 0; + return CURLE_FAILED_INIT; +} + +struct cf_io_ctx { + struct Curl_easy *data; + struct Curl_cfilter *cf; +}; + +static CURLcode cf_bufq_reader(void *writer_ctx, + unsigned char *buf, size_t blen, + size_t *pnread) +{ + struct cf_io_ctx *io = writer_ctx; + return Curl_conn_cf_recv(io->cf, io->data, (char *)buf, blen, pnread); +} + +CURLcode Curl_cf_recv_bufq(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct bufq *bufq, + size_t maxlen, + size_t *pnread) +{ + struct cf_io_ctx io; + + if(!cf || !data) { + *pnread = 0; + return CURLE_BAD_FUNCTION_ARGUMENT; + } + io.data = data; + io.cf = cf; + return Curl_bufq_sipn(bufq, maxlen, cf_bufq_reader, &io, pnread); +} + +static CURLcode cf_bufq_writer(void *writer_ctx, + const unsigned char *buf, size_t buflen, + size_t *pnwritten) +{ + struct cf_io_ctx *io = writer_ctx; + return Curl_conn_cf_send(io->cf, io->data, (const char *)buf, + buflen, FALSE, pnwritten); +} + +CURLcode Curl_cf_send_bufq(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct bufq *bufq, + const unsigned char *buf, size_t blen, + size_t *pnwritten) +{ + struct cf_io_ctx io; + + if(!cf || !data) { + *pnwritten = 0; + return CURLE_BAD_FUNCTION_ARGUMENT; + } + io.data = data; + io.cf = cf; + if(buf && blen) + return Curl_bufq_write_pass(bufq, buf, blen, cf_bufq_writer, &io, + pnwritten); + else + return Curl_bufq_pass(bufq, cf_bufq_writer, &io, pnwritten); } CURLcode Curl_cf_create(struct Curl_cfilter **pcf, @@ -381,25 +425,48 @@ void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data) cf->cft->do_close(cf, data); } -ssize_t Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, bool eos, - CURLcode *err) +CURLcode Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data, + const void *buf, size_t len, bool eos, + size_t *pnwritten) { if(cf) - return cf->cft->do_send(cf, data, buf, len, eos, err); - *err = CURLE_SEND_ERROR; - return -1; + return cf->cft->do_send(cf, data, buf, len, eos, pnwritten); + *pnwritten = 0; + return CURLE_SEND_ERROR; } -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_recv(struct Curl_cfilter *cf, struct Curl_easy *data, + char *buf, size_t len, size_t *pnread) { if(cf) - return cf->cft->do_recv(cf, data, buf, len, err); - *err = CURLE_RECV_ERROR; - return -1; + return cf->cft->do_recv(cf, data, buf, len, pnread); + *pnread = 0; + return CURLE_RECV_ERROR; } +#ifndef CURL_DISABLE_VERBOSE_STRINGS +static CURLcode cf_verboseconnect(struct Curl_easy *data, + struct Curl_cfilter *cf) +{ + if(Curl_trc_is_verbose(data)) { + struct ip_quadruple ipquad; + bool is_ipv6; + CURLcode result; + + result = Curl_conn_cf_get_ip_info(cf, data, &is_ipv6, &ipquad); + if(result) + return result; + + infof(data, "Established %sconnection to %s (%s port %u) from %s port %u ", + (cf->sockindex == SECONDARYSOCKET) ? "2nd " : "", + CURL_CONN_HOST_DISPNAME(data->conn), + ipquad.remote_ip, ipquad.remote_port, + ipquad.local_ip, ipquad.local_port); + } + return CURLE_OK; +} +#endif + CURLcode Curl_conn_connect(struct Curl_easy *data, int sockindex, bool blocking, @@ -407,12 +474,15 @@ CURLcode Curl_conn_connect(struct Curl_easy *data, { #define CF_CONN_NUM_POLLS_ON_STACK 5 struct pollfd a_few_on_stack[CF_CONN_NUM_POLLS_ON_STACK]; + struct easy_pollset ps; struct curl_pollfds cpfds; struct Curl_cfilter *cf; CURLcode result = CURLE_OK; DEBUGASSERT(data); DEBUGASSERT(data->conn); + if(!CONN_SOCK_IDX_VALID(sockindex)) + return CURLE_BAD_FUNCTION_ARGUMENT; cf = data->conn->cfilter[sockindex]; if(!cf) { @@ -424,6 +494,7 @@ CURLcode Curl_conn_connect(struct Curl_easy *data, if(*done) return CURLE_OK; + Curl_pollset_init(&ps); Curl_pollfds_init(&cpfds, a_few_on_stack, CF_CONN_NUM_POLLS_ON_STACK); while(!*done) { if(Curl_conn_needs_flush(data, sockindex)) { @@ -443,7 +514,9 @@ CURLcode Curl_conn_connect(struct Curl_easy *data, cf_cntrl_update_info(data, data->conn); conn_report_connect_stats(data, data->conn); data->conn->keepalive = curlx_now(); - Curl_verboseconnect(data, data->conn, sockindex); +#ifndef CURL_DISABLE_VERBOSE_STRINGS + result = cf_verboseconnect(data, cf); +#endif goto out; } else if(result) { @@ -459,7 +532,6 @@ CURLcode Curl_conn_connect(struct Curl_easy *data, /* check allowed time left */ const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data); - struct easy_pollset ps; int rc; if(timeout_ms < 0) { @@ -470,12 +542,14 @@ CURLcode Curl_conn_connect(struct Curl_easy *data, } CURL_TRC_CF(data, cf, "Curl_conn_connect(block=1), do poll"); + Curl_pollset_reset(&ps); Curl_pollfds_reset(&cpfds); - memset(&ps, 0, sizeof(ps)); /* In general, we want to send after connect, wait on that. */ if(sockfd != CURL_SOCKET_BAD) Curl_pollset_set_out_only(data, &ps, sockfd); - Curl_conn_adjust_pollset(data, data->conn, &ps); + result = Curl_conn_adjust_pollset(data, data->conn, &ps); + if(result) + goto out; result = Curl_pollfds_add_ps(&cpfds, &ps); if(result) goto out; @@ -493,12 +567,15 @@ CURLcode Curl_conn_connect(struct Curl_easy *data, } out: + Curl_pollset_cleanup(&ps); Curl_pollfds_cleanup(&cpfds); return result; } bool Curl_conn_is_setup(struct connectdata *conn, int sockindex) { + if(!CONN_SOCK_IDX_VALID(sockindex)) + return FALSE; return (conn->cfilter[sockindex] != NULL); } @@ -506,6 +583,8 @@ bool Curl_conn_is_connected(struct connectdata *conn, int sockindex) { struct Curl_cfilter *cf; + if(!CONN_SOCK_IDX_VALID(sockindex)) + return FALSE; cf = conn->cfilter[sockindex]; return cf && cf->connected; } @@ -514,6 +593,8 @@ bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex) { struct Curl_cfilter *cf; + if(!CONN_SOCK_IDX_VALID(sockindex)) + return FALSE; cf = data->conn->cfilter[sockindex]; while(cf) { if(cf->connected) @@ -525,7 +606,7 @@ bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex) return FALSE; } -bool Curl_conn_cf_is_ssl(struct Curl_cfilter *cf) +static bool cf_is_ssl(struct Curl_cfilter *cf) { for(; cf; cf = cf->next) { if(cf->cft->flags & CF_TYPE_SSL) @@ -538,12 +619,44 @@ bool Curl_conn_cf_is_ssl(struct Curl_cfilter *cf) bool Curl_conn_is_ssl(struct connectdata *conn, int sockindex) { - return conn ? Curl_conn_cf_is_ssl(conn->cfilter[sockindex]) : FALSE; + if(!CONN_SOCK_IDX_VALID(sockindex)) + return FALSE; + return conn ? cf_is_ssl(conn->cfilter[sockindex]) : FALSE; +} + +bool Curl_conn_get_ssl_info(struct Curl_easy *data, + struct connectdata *conn, int sockindex, + struct curl_tlssessioninfo *info) +{ + if(!CONN_SOCK_IDX_VALID(sockindex)) + return FALSE; + if(Curl_conn_is_ssl(conn, sockindex)) { + struct Curl_cfilter *cf = conn->cfilter[sockindex]; + CURLcode result = cf ? cf->cft->query(cf, data, CF_QUERY_SSL_INFO, + NULL, (void *)info) : CURLE_UNKNOWN_OPTION; + return !result; + } + return FALSE; +} + +CURLcode Curl_conn_get_ip_info(struct Curl_easy *data, + struct connectdata *conn, int sockindex, + bool *is_ipv6, struct ip_quadruple *ipquad) +{ + struct Curl_cfilter *cf; + if(!CONN_SOCK_IDX_VALID(sockindex)) + return CURLE_BAD_FUNCTION_ARGUMENT; + cf = conn ? conn->cfilter[sockindex] : NULL; + return Curl_conn_cf_get_ip_info(cf, data, is_ipv6, ipquad); } bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex) { - struct Curl_cfilter *cf = conn ? conn->cfilter[sockindex] : NULL; + struct Curl_cfilter *cf; + + if(!CONN_SOCK_IDX_VALID(sockindex)) + return FALSE; + cf = conn ? conn->cfilter[sockindex] : NULL; for(; cf; cf = cf->next) { if(cf->cft->flags & CF_TYPE_MULTIPLEX) @@ -554,6 +667,20 @@ bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex) return FALSE; } +unsigned char Curl_conn_get_transport(struct Curl_easy *data, + struct connectdata *conn) +{ + struct Curl_cfilter *cf = conn->cfilter[FIRSTSOCKET]; + return Curl_conn_cf_get_transport(cf, data); +} + +const char *Curl_conn_get_alpn_negotiated(struct Curl_easy *data, + struct connectdata *conn) +{ + struct Curl_cfilter *cf = conn->cfilter[FIRSTSOCKET]; + return Curl_conn_cf_get_alpn_negotiated(cf, data); +} + unsigned char Curl_conn_http_version(struct Curl_easy *data, struct connectdata *conn) { @@ -585,6 +712,8 @@ bool Curl_conn_data_pending(struct Curl_easy *data, int sockindex) (void)data; DEBUGASSERT(data); DEBUGASSERT(data->conn); + if(!CONN_SOCK_IDX_VALID(sockindex)) + return FALSE; cf = data->conn->cfilter[sockindex]; while(cf && !cf->connected) { @@ -608,13 +737,16 @@ bool Curl_conn_cf_needs_flush(struct Curl_cfilter *cf, bool Curl_conn_needs_flush(struct Curl_easy *data, int sockindex) { + if(!CONN_SOCK_IDX_VALID(sockindex)) + return FALSE; return Curl_conn_cf_needs_flush(data->conn->cfilter[sockindex], data); } -void Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) +CURLcode Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { + CURLcode result = CURLE_OK; /* Get the lowest not-connected filter, if there are any */ while(cf && !cf->connected && cf->next && !cf->next->connected) cf = cf->next; @@ -623,23 +755,26 @@ void Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf, cf = cf->next; /* From there on, give all filters a chance to adjust the pollset. * Lower filters are called later, so they may override */ - while(cf) { - cf->cft->adjust_pollset(cf, data, ps); + while(cf && !result) { + result = cf->cft->adjust_pollset(cf, data, ps); cf = cf->next; } + return result; } -void Curl_conn_adjust_pollset(struct Curl_easy *data, - struct connectdata *conn, - struct easy_pollset *ps) +CURLcode Curl_conn_adjust_pollset(struct Curl_easy *data, + struct connectdata *conn, + struct easy_pollset *ps) { + CURLcode result = CURLE_OK; int i; DEBUGASSERT(data); DEBUGASSERT(conn); - for(i = 0; i < 2; ++i) { - Curl_conn_cf_adjust_pollset(conn->cfilter[i], data, ps); + for(i = 0; (i < 2) && !result; ++i) { + result = Curl_conn_cf_adjust_pollset(conn->cfilter[i], data, ps); } + return result; } int Curl_conn_cf_poll(struct Curl_cfilter *cf, @@ -647,62 +782,55 @@ int Curl_conn_cf_poll(struct Curl_cfilter *cf, timediff_t timeout_ms) { struct easy_pollset ps; - struct pollfd pfds[MAX_SOCKSPEREASYHANDLE]; - unsigned int i, npfds = 0; + int result; DEBUGASSERT(cf); DEBUGASSERT(data); DEBUGASSERT(data->conn); - memset(&ps, 0, sizeof(ps)); - memset(pfds, 0, sizeof(pfds)); - - Curl_conn_cf_adjust_pollset(cf, data, &ps); - DEBUGASSERT(ps.num <= MAX_SOCKSPEREASYHANDLE); - for(i = 0; i < ps.num; ++i) { - short events = 0; - if(ps.actions[i] & CURL_POLL_IN) { - events |= POLLIN; - } - if(ps.actions[i] & CURL_POLL_OUT) { - events |= POLLOUT; - } - if(events) { - pfds[npfds].fd = ps.sockets[i]; - pfds[npfds].events = events; - ++npfds; - } - } + Curl_pollset_init(&ps); - if(!npfds) - DEBUGF(infof(data, "no sockets to poll!")); - return Curl_poll(pfds, npfds, timeout_ms); + result = Curl_conn_cf_adjust_pollset(cf, data, &ps); + if(!result) + result = Curl_pollset_poll(data, &ps, timeout_ms); + Curl_pollset_cleanup(&ps); + return result; } -void Curl_conn_get_host(struct Curl_easy *data, int sockindex, - const char **phost, const char **pdisplay_host, - int *pport) +void Curl_conn_get_current_host(struct Curl_easy *data, int sockindex, + const char **phost, int *pport) { - struct Curl_cfilter *cf; + struct Curl_cfilter *cf, *cf_proxy = NULL; - DEBUGASSERT(data->conn); - cf = data->conn->cfilter[sockindex]; - if(cf) { - cf->cft->get_host(cf, data, phost, pdisplay_host, pport); + if(!data->conn) { + DEBUGASSERT(0); + *phost = ""; + *pport = -1; + return; } - 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. */ + + cf = CONN_SOCK_IDX_VALID(sockindex) ? data->conn->cfilter[sockindex] : NULL; + /* Find the "lowest" tunneling proxy filter that has not connected yet. */ + while(cf && !cf->connected) { + if((cf->cft->flags & (CF_TYPE_IP_CONNECT|CF_TYPE_PROXY)) == + (CF_TYPE_IP_CONNECT|CF_TYPE_PROXY)) + cf_proxy = cf; + cf = cf->next; + } + /* cf_proxy (!= NULL) is not connected yet. It is talking + * to an interim host and any authentication or other things apply + * to this interim host and port. */ + if(!cf_proxy || cf_proxy->cft->query(cf_proxy, data, CF_QUERY_HOST_PORT, + pport, CURL_UNCONST(phost))) { + /* Everything connected or query unsuccessful, the overall + * connection's destination is the answer */ *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) + struct Curl_easy *data, + int event, int arg1, void *arg2) { (void)cf; (void)data; @@ -738,31 +866,77 @@ curl_socket_t Curl_conn_cf_get_socket(struct Curl_cfilter *cf, return CURL_SOCKET_BAD; } +unsigned char Curl_conn_cf_get_transport(struct Curl_cfilter *cf, + struct Curl_easy *data) +{ + int transport = 0; + if(cf && !cf->cft->query(cf, data, CF_QUERY_TRANSPORT, &transport, NULL)) + return (unsigned char)transport; + return (unsigned char)(data->conn ? data->conn->transport_wanted : 0); +} + +const char *Curl_conn_cf_get_alpn_negotiated(struct Curl_cfilter *cf, + struct Curl_easy *data) +{ + const char *alpn = NULL; + CURL_TRC_CF(data, cf, "query ALPN"); + if(cf && !cf->cft->query(cf, data, CF_QUERY_ALPN_NEGOTIATED, NULL, + CURL_UNCONST(&alpn))) + return alpn; + return NULL; +} + +static const struct Curl_sockaddr_ex * +cf_get_remote_addr(struct Curl_cfilter *cf, struct Curl_easy *data) +{ + const struct Curl_sockaddr_ex *remote_addr = NULL; + if(cf && + !cf->cft->query(cf, data, CF_QUERY_REMOTE_ADDR, NULL, + CURL_UNCONST(&remote_addr))) + return remote_addr; + return NULL; +} + CURLcode Curl_conn_cf_get_ip_info(struct Curl_cfilter *cf, struct Curl_easy *data, - int *is_ipv6, struct ip_quadruple *ipquad) + bool *is_ipv6, struct ip_quadruple *ipquad) { - if(cf) - return cf->cft->query(cf, data, CF_QUERY_IP_INFO, is_ipv6, ipquad); - return CURLE_UNKNOWN_OPTION; + CURLcode result = CURLE_UNKNOWN_OPTION; + if(cf) { + int ipv6 = 0; + result = cf->cft->query(cf, data, CF_QUERY_IP_INFO, &ipv6, ipquad); + *is_ipv6 = !!ipv6; + } + return result; } -curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex) +curl_socket_t Curl_conn_get_first_socket(struct Curl_easy *data) { struct Curl_cfilter *cf; - cf = data->conn ? data->conn->cfilter[sockindex] : NULL; + if(!data->conn) + return CURL_SOCKET_BAD; + + cf = data->conn->cfilter[FIRSTSOCKET]; /* if the top filter has not connected, ask it (and its sub-filters) - * for the socket. Otherwise conn->sock[sockindex] should have it. - */ + * 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; + return data->conn->sock[FIRSTSOCKET]; +} + +const struct Curl_sockaddr_ex * +Curl_conn_get_remote_addr(struct Curl_easy *data, int sockindex) +{ + struct Curl_cfilter *cf = + (data->conn && CONN_SOCK_IDX_VALID(sockindex)) ? + data->conn->cfilter[sockindex] : NULL; + return cf ? cf_get_remote_addr(cf, data) : NULL; } void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex) { - if(data->conn) { + if(data->conn && CONN_SOCK_IDX_VALID(sockindex)) { struct Curl_cfilter *cf = data->conn->cfilter[sockindex]; if(cf) (void)Curl_conn_cf_cntrl(cf, data, TRUE, @@ -804,6 +978,8 @@ CURLcode Curl_conn_ev_data_idle(struct Curl_easy *data) CURLcode Curl_conn_flush(struct Curl_easy *data, int sockindex) { + if(!CONN_SOCK_IDX_VALID(sockindex)) + return CURLE_BAD_FUNCTION_ARGUMENT; return Curl_conn_cf_cntrl(data->conn->cfilter[sockindex], data, FALSE, CF_CTRL_FLUSH, 0, NULL); } @@ -873,31 +1049,46 @@ CURLcode Curl_conn_keep_alive(struct Curl_easy *data, struct connectdata *conn, int sockindex) { - struct Curl_cfilter *cf = conn->cfilter[sockindex]; + struct Curl_cfilter *cf; + + if(!CONN_SOCK_IDX_VALID(sockindex)) + return CURLE_BAD_FUNCTION_ARGUMENT; + 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) + struct connectdata *conn, + int sockindex) { + struct Curl_cfilter *cf; CURLcode result; - int n = 0; + int n = -1; - struct Curl_cfilter *cf = conn->cfilter[sockindex]; + if(!CONN_SOCK_IDX_VALID(sockindex)) + return 0; + + 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; + /* If no filter answered the query, the default is a non-multiplexed + * connection with limit 1. Otherwise, the the query may return 0 + * for connections that are in shutdown, e.g. server HTTP/2 GOAWAY. */ + return (result || n < 0) ? 1 : (size_t)n; } int Curl_conn_get_stream_error(struct Curl_easy *data, struct connectdata *conn, int sockindex) { + struct Curl_cfilter *cf; CURLcode result; int n = 0; - struct Curl_cfilter *cf = conn->cfilter[sockindex]; + if(!CONN_SOCK_IDX_VALID(sockindex)) + return 0; + + cf = conn->cfilter[sockindex]; result = cf ? cf->cft->query(cf, data, CF_QUERY_STREAM_ERROR, &n, NULL) : CURLE_UNKNOWN_OPTION; return (result || n < 0) ? 0 : n; @@ -912,17 +1103,16 @@ int Curl_conn_sockindex(struct Curl_easy *data, curl_socket_t sockfd) } CURLcode Curl_conn_recv(struct Curl_easy *data, int sockindex, - char *buf, size_t blen, ssize_t *n) + char *buf, size_t blen, size_t *pnread) { - CURLcode result = CURLE_OK; - ssize_t nread; - + DEBUGASSERT(data); DEBUGASSERT(data->conn); - nread = data->conn->recv[sockindex](data, sockindex, buf, blen, &result); - DEBUGASSERT(nread >= 0 || result); - DEBUGASSERT(nread < 0 || !result); - *n = (nread >= 0) ? (size_t)nread : 0; - return result; + if(!CONN_SOCK_IDX_VALID(sockindex)) + return CURLE_BAD_FUNCTION_ARGUMENT; + if(data && data->conn && data->conn->recv[sockindex]) + return data->conn->recv[sockindex](data, sockindex, buf, blen, pnread); + *pnread = 0; + return CURLE_FAILED_INIT; } CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex, @@ -930,15 +1120,12 @@ CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex, size_t *pnwritten) { size_t write_len = blen; - ssize_t nwritten; - CURLcode result = CURLE_OK; - struct connectdata *conn; - DEBUGASSERT(sockindex >= 0 && sockindex < 2); - DEBUGASSERT(pnwritten); DEBUGASSERT(data); DEBUGASSERT(data->conn); - conn = data->conn; + DEBUGASSERT(CONN_SOCK_IDX_VALID(sockindex)); + if(!CONN_SOCK_IDX_VALID(sockindex)) + return CURLE_BAD_FUNCTION_ARGUMENT; #ifdef DEBUGBUILD if(write_len) { /* Allow debug builds to override this logic to force short sends @@ -953,135 +1140,9 @@ CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex, #endif if(write_len != blen) eos = FALSE; - nwritten = conn->send[sockindex](data, sockindex, buf, write_len, eos, - &result); - DEBUGASSERT((nwritten >= 0) || result); - *pnwritten = (nwritten < 0) ? 0 : (size_t)nwritten; - return result; -} - -void Curl_pollset_reset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - size_t i; - (void)data; - memset(ps, 0, sizeof(*ps)); - for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) - ps->sockets[i] = CURL_SOCKET_BAD; -} - -/** - * - */ -void Curl_pollset_change(struct Curl_easy *data, - struct easy_pollset *ps, curl_socket_t sock, - int add_flags, int remove_flags) -{ - unsigned int i; - - (void)data; - DEBUGASSERT(VALID_SOCK(sock)); - if(!VALID_SOCK(sock)) - return; - - DEBUGASSERT(add_flags <= (CURL_POLL_IN|CURL_POLL_OUT)); - DEBUGASSERT(remove_flags <= (CURL_POLL_IN|CURL_POLL_OUT)); - DEBUGASSERT((add_flags&remove_flags) == 0); /* no overlap */ - for(i = 0; i < ps->num; ++i) { - if(ps->sockets[i] == sock) { - ps->actions[i] &= (unsigned char)(~remove_flags); - ps->actions[i] |= (unsigned char)add_flags; - /* all gone? remove socket */ - if(!ps->actions[i]) { - if((i + 1) < ps->num) { - memmove(&ps->sockets[i], &ps->sockets[i + 1], - (ps->num - (i + 1)) * sizeof(ps->sockets[0])); - memmove(&ps->actions[i], &ps->actions[i + 1], - (ps->num - (i + 1)) * sizeof(ps->actions[0])); - } - --ps->num; - } - return; - } - } - /* not present */ - if(add_flags) { - /* Having more SOCKETS per easy handle than what is defined - * is a programming error. This indicates that we need - * to raise this limit, making easy_pollset larger. - * Since we use this in tight loops, we do not want to make - * the pollset dynamic unnecessarily. - * The current maximum in practise is HTTP/3 eyeballing where - * we have up to 4 sockets involved in connection setup. - */ - DEBUGASSERT(i < MAX_SOCKSPEREASYHANDLE); - if(i < MAX_SOCKSPEREASYHANDLE) { - ps->sockets[i] = sock; - ps->actions[i] = (unsigned char)add_flags; - ps->num = i + 1; - } - } -} - -void Curl_pollset_set(struct Curl_easy *data, - struct easy_pollset *ps, curl_socket_t sock, - bool do_in, bool do_out) -{ - Curl_pollset_change(data, ps, sock, - (do_in ? CURL_POLL_IN : 0)| - (do_out ? CURL_POLL_OUT : 0), - (!do_in ? CURL_POLL_IN : 0)| - (!do_out ? CURL_POLL_OUT : 0)); -} - -static void ps_add(struct Curl_easy *data, struct easy_pollset *ps, - int bitmap, curl_socket_t *socks) -{ - if(bitmap) { - int i; - for(i = 0; i < MAX_SOCKSPEREASYHANDLE; ++i) { - if(!(bitmap & GETSOCK_MASK_RW(i)) || !VALID_SOCK((socks[i]))) { - break; - } - if(bitmap & GETSOCK_READSOCK(i)) { - if(bitmap & GETSOCK_WRITESOCK(i)) - Curl_pollset_add_inout(data, ps, socks[i]); - else - /* is READ, since we checked MASK_RW above */ - Curl_pollset_add_in(data, ps, socks[i]); - } - else - Curl_pollset_add_out(data, ps, socks[i]); - } - } -} - -void Curl_pollset_add_socks(struct Curl_easy *data, - struct easy_pollset *ps, - int (*get_socks_cb)(struct Curl_easy *data, - curl_socket_t *socks)) -{ - curl_socket_t socks[MAX_SOCKSPEREASYHANDLE]; - int bitmap; - - bitmap = get_socks_cb(data, socks); - ps_add(data, ps, bitmap, socks); -} - -void Curl_pollset_check(struct Curl_easy *data, - struct easy_pollset *ps, curl_socket_t sock, - bool *pwant_read, bool *pwant_write) -{ - unsigned int i; - - (void)data; - DEBUGASSERT(VALID_SOCK(sock)); - for(i = 0; i < ps->num; ++i) { - if(ps->sockets[i] == sock) { - *pwant_read = !!(ps->actions[i] & CURL_POLL_IN); - *pwant_write = !!(ps->actions[i] & CURL_POLL_OUT); - return; - } - } - *pwant_read = *pwant_write = FALSE; + if(data && data->conn && data->conn->send[sockindex]) + return data->conn->send[sockindex](data, sockindex, buf, write_len, eos, + pnwritten); + *pnwritten = 0; + return CURLE_FAILED_INIT; } diff --git a/vendor/curl/lib/cfilters.h b/vendor/curl/lib/cfilters.h index 4c604db38f7..815b72a6e80 100644 --- a/vendor/curl/lib/cfilters.h +++ b/vendor/curl/lib/cfilters.h @@ -26,11 +26,13 @@ #include "curlx/timediff.h" +struct bufq; struct Curl_cfilter; struct Curl_easy; struct Curl_dns_entry; struct connectdata; struct ip_quadruple; +struct curl_tlssessioninfo; /* Callback to destroy resources held by this filter instance. * Implementations MUST NOT chain calls to cf->next. @@ -53,23 +55,6 @@ typedef CURLcode Curl_cft_connect(struct Curl_cfilter *cf, struct Curl_easy *data, 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); - struct easy_pollset; /* Passing in an easy_pollset for monitoring of sockets, let @@ -95,25 +80,25 @@ struct easy_pollset; * @param data the easy handle the pollset is about * @param ps the pollset (inout) for the easy handle */ -typedef void Curl_cft_adjust_pollset(struct Curl_cfilter *cf, +typedef CURLcode Curl_cft_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data, struct easy_pollset *ps); 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, +typedef CURLcode Curl_cft_send(struct Curl_cfilter *cf, struct Curl_easy *data, /* transfer */ const void *buf, /* data to write */ size_t len, /* amount to write */ bool eos, /* last chunk */ - CURLcode *err); /* error to return */ + size_t *pnwritten); /* how much sent */ -typedef ssize_t Curl_cft_recv(struct Curl_cfilter *cf, +typedef CURLcode 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 */ + size_t *pnread); /* how much received */ typedef bool Curl_cft_conn_is_alive(struct Curl_cfilter *cf, struct Curl_easy *data, @@ -166,6 +151,17 @@ typedef CURLcode Curl_cft_cntrl(struct Curl_cfilter *cf, * - CF_QUERY_NEED_FLUSH: TRUE iff any of the filters have unsent data * - CF_QUERY_IP_INFO: res1 says if connection used IPv6, res2 is the * ip quadruple + * - CF_QUERY_HOST_PORT: the remote hostname and port a filter talks to + * - CF_QUERY_SSL_INFO: fill out the passed curl_tlssessioninfo with the + * internal from the SSL secured connection when + * available. + * - CF_QUERY_SSL_CTX_INFO: same as CF_QUERY_SSL_INFO, but give the SSL_CTX + * when available, or the same internal pointer + * when the TLS stack does not differentiate. + * - CF_QUERY_ALPN_NEGOTIATED: The ALPN selected by the server as + null-terminated string or NULL if none + selected/handshake not done. Implemented by filter + types CF_TYPE_SSL or CF_TYPE_IP_CONNECT. */ /* query res1 res2 */ #define CF_QUERY_MAX_CONCURRENT 1 /* number - */ @@ -177,6 +173,14 @@ typedef CURLcode Curl_cft_cntrl(struct Curl_cfilter *cf, #define CF_QUERY_NEED_FLUSH 7 /* TRUE/FALSE - */ #define CF_QUERY_IP_INFO 8 /* TRUE/FALSE struct ip_quadruple */ #define CF_QUERY_HTTP_VERSION 9 /* number (10/11/20/30) - */ +/* pass in a `const struct Curl_sockaddr_ex **` as `pres2`. Gets set + * to NULL when not connected. */ +#define CF_QUERY_REMOTE_ADDR 10 /* - `Curl_sockaddr_ex *` */ +#define CF_QUERY_HOST_PORT 11 /* port const char * */ +#define CF_QUERY_SSL_INFO 12 /* - struct curl_tlssessioninfo * */ +#define CF_QUERY_SSL_CTX_INFO 13 /* - struct curl_tlssessioninfo * */ +#define CF_QUERY_TRANSPORT 14 /* TRNSPRT_* - * */ +#define CF_QUERY_ALPN_NEGOTIATED 15 /* - const char * */ /** * Query the cfilter for properties. Filters ignorant of a query will @@ -213,7 +217,6 @@ struct Curl_cftype { Curl_cft_connect *do_connect; /* establish connection */ Curl_cft_close *do_close; /* close conn */ Curl_cft_shutdown *do_shutdown; /* shutdown conn */ - Curl_cft_get_host *get_host; /* host filter talks to */ Curl_cft_adjust_pollset *adjust_pollset; /* adjust transfer poll set */ Curl_cft_data_pending *has_data_pending;/* conn has data pending */ Curl_cft_send *do_send; /* send data */ @@ -241,19 +244,16 @@ void Curl_cf_def_destroy_this(struct Curl_cfilter *cf, /* 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); -void Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf, +CURLcode Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data, struct easy_pollset *ps); 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, +CURLcode Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data, const void *buf, size_t len, bool eos, - CURLcode *err); -ssize_t Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t len, CURLcode *err); + size_t *pnwritten); +CURLcode Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data, + char *buf, size_t len, size_t *pnread); CURLcode Curl_cf_def_cntrl(struct Curl_cfilter *cf, struct Curl_easy *data, int event, int arg1, void *arg2); @@ -326,22 +326,16 @@ CURLcode Curl_conn_cf_connect(struct Curl_cfilter *cf, struct Curl_easy *data, bool *done); void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data); -ssize_t Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, bool eos, - 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_send(struct Curl_cfilter *cf, struct Curl_easy *data, + const void *buf, size_t len, bool eos, + size_t *pnwritten); +CURLcode Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data, + char *buf, size_t len, size_t *pnread); 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. @@ -351,11 +345,17 @@ curl_socket_t Curl_conn_cf_get_socket(struct Curl_cfilter *cf, CURLcode Curl_conn_cf_get_ip_info(struct Curl_cfilter *cf, struct Curl_easy *data, - int *is_ipv6, struct ip_quadruple *ipquad); + bool *is_ipv6, struct ip_quadruple *ipquad); bool Curl_conn_cf_needs_flush(struct Curl_cfilter *cf, struct Curl_easy *data); +unsigned char Curl_conn_cf_get_transport(struct Curl_cfilter *cf, + struct Curl_easy *data); + +const char *Curl_conn_cf_get_alpn_negotiated(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 @@ -395,6 +395,19 @@ bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex); */ bool Curl_conn_is_ssl(struct connectdata *conn, int sockindex); +/* + * Fill `info` with information about the TLS instance securing + * the connection when available, otherwise e.g. when + * Curl_conn_is_ssl() is FALSE, return FALSE. + */ +bool Curl_conn_get_ssl_info(struct Curl_easy *data, + struct connectdata *conn, int sockindex, + struct curl_tlssessioninfo *info); + +CURLcode Curl_conn_get_ip_info(struct Curl_easy *data, + struct connectdata *conn, int sockindex, + bool *is_ipv6, struct ip_quadruple *ipquad); + /** * Connection provides multiplexing of easy handles at `socketindex`. */ @@ -407,6 +420,14 @@ bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex); unsigned char Curl_conn_http_version(struct Curl_easy *data, struct connectdata *conn); +/* Get the TRNSPRT_* the connection is using */ +unsigned char Curl_conn_get_transport(struct Curl_easy *data, + struct connectdata *conn); + +/* Get the negotiated ALPN protocol or NULL if none in play */ +const char *Curl_conn_get_alpn_negotiated(struct Curl_easy *data, + struct connectdata *conn); + /** * Close the filter chain at `sockindex` for connection `data->conn`. * Filters remain in place and may be connected again afterwards. @@ -439,10 +460,15 @@ bool Curl_conn_needs_flush(struct Curl_easy *data, int sockindex); CURLcode Curl_conn_flush(struct Curl_easy *data, int sockindex); /** - * Return the socket used on data's connection for the index. + * Return the socket used on data's connection for FIRSTSOCKET, + * querying filters if the whole chain has not connected yet. * Returns CURL_SOCKET_BAD if not available. */ -curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex); +curl_socket_t Curl_conn_get_first_socket(struct Curl_easy *data); + +/* Return a pointer to the connected socket address or NULL. */ +const struct Curl_sockaddr_ex * +Curl_conn_get_remote_addr(struct Curl_easy *data, int sockindex); /** * Tell filters to forget about the socket at sockindex. @@ -450,18 +476,18 @@ curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex); void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex); /** - * Adjust the pollset for the filter chain startgin at `cf`. + * Adjust the pollset for the filter chain starting at `cf`. */ -void Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps); +CURLcode Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps); /** * Adjust pollset from filters installed at transfer's connection. */ -void Curl_conn_adjust_pollset(struct Curl_easy *data, - struct connectdata *conn, - struct easy_pollset *ps); +CURLcode Curl_conn_adjust_pollset(struct Curl_easy *data, + struct connectdata *conn, + struct easy_pollset *ps); /** * Curl_poll() the filter chain at `cf` with timeout `timeout_ms`. @@ -475,20 +501,41 @@ int Curl_conn_cf_poll(struct Curl_cfilter *cf, /** * Receive data through the filter chain at `sockindex` for connection * `data->conn`. Copy at most `len` bytes into `buf`. Return the - * actual number of bytes copied or a negative value on error. - * The error code is placed into `*code`. + * actual number of bytes copied in `*pnread`or an error. */ -ssize_t Curl_cf_recv(struct Curl_easy *data, int sockindex, char *buf, - size_t len, CURLcode *code); +CURLcode Curl_cf_recv(struct Curl_easy *data, int sockindex, char *buf, + size_t len, size_t *pnread); /** * 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`. + * in `*pnwritten` or on error. + */ +CURLcode Curl_cf_send(struct Curl_easy *data, int sockindex, + const void *buf, size_t len, bool eos, + size_t *pnwritten); + +/** + * Receive bytes from connection filter `cf` into `bufq`. + * Convenience wrappter around `Curl_bufq_sipn()`, + * so users do not have to implement a callback. + */ +CURLcode Curl_cf_recv_bufq(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct bufq *bufq, + size_t maxlen, + size_t *pnread); + +/** + * Send bytes in `bufq` using connection filter `cf`. + * A convenience wrapper around `Curl_bufq_write_pass()`, + * so users do not have to implement a callback. */ -ssize_t Curl_cf_send(struct Curl_easy *data, int sockindex, - const void *buf, size_t len, bool eos, CURLcode *code); +CURLcode Curl_cf_send_bufq(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct bufq *bufq, + const unsigned char *buf, size_t blen, + size_t *pnwritten); /** * Notify connection filters that they need to setup data for @@ -535,9 +582,17 @@ CURLcode Curl_conn_keep_alive(struct Curl_easy *data, #ifdef UNITTESTS void Curl_cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data); #endif -void Curl_conn_get_host(struct Curl_easy *data, int sockindex, - const char **phost, const char **pdisplay_host, - int *pport); + +/** + * Get the remote hostname and port that the connection is currently + * talking to (or will talk to). + * Once connected or before connect starts, + * it is `conn->host.name` and `conn->remote_port`. + * During connect, when tunneling proxies are involved (http or socks), + * it will be the name and port the proxy currently negotiates with. + */ +void Curl_conn_get_current_host(struct Curl_easy *data, int sockindex, + const char **phost, int *pport); /** * Get the maximum number of parallel transfers the connection @@ -567,7 +622,7 @@ int Curl_conn_sockindex(struct Curl_easy *data, curl_socket_t sockfd); */ CURLcode Curl_conn_recv(struct Curl_easy *data, int sockindex, char *buf, size_t buffersize, - ssize_t *pnread); + size_t *pnread); /* * Send data on the connection, using FIRSTSOCKET/SECONDARYSOCKET. @@ -578,49 +633,6 @@ CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex, size_t *pnwritten); -void Curl_pollset_reset(struct Curl_easy *data, - struct easy_pollset *ps); - -/* Change the poll flags (CURL_POLL_IN/CURL_POLL_OUT) to the poll set for - * socket `sock`. If the socket is not already part of the poll set, it - * will be added. - * If the socket is present and all poll flags are cleared, it will be removed. - */ -void Curl_pollset_change(struct Curl_easy *data, - struct easy_pollset *ps, curl_socket_t sock, - int add_flags, int remove_flags); - -void Curl_pollset_set(struct Curl_easy *data, - struct easy_pollset *ps, curl_socket_t sock, - bool do_in, bool do_out); - -#define Curl_pollset_add_in(data, ps, sock) \ - Curl_pollset_change((data), (ps), (sock), CURL_POLL_IN, 0) -#define Curl_pollset_add_out(data, ps, sock) \ - Curl_pollset_change((data), (ps), (sock), CURL_POLL_OUT, 0) -#define Curl_pollset_add_inout(data, ps, sock) \ - Curl_pollset_change((data), (ps), (sock), \ - CURL_POLL_IN|CURL_POLL_OUT, 0) -#define Curl_pollset_set_in_only(data, ps, sock) \ - Curl_pollset_change((data), (ps), (sock), \ - CURL_POLL_IN, CURL_POLL_OUT) -#define Curl_pollset_set_out_only(data, ps, sock) \ - Curl_pollset_change((data), (ps), (sock), \ - CURL_POLL_OUT, CURL_POLL_IN) - -void Curl_pollset_add_socks(struct Curl_easy *data, - struct easy_pollset *ps, - int (*get_socks_cb)(struct Curl_easy *data, - curl_socket_t *socks)); - -/** - * Check if the pollset, as is, wants to read and/or write regarding - * the given socket. - */ -void Curl_pollset_check(struct Curl_easy *data, - struct easy_pollset *ps, curl_socket_t sock, - bool *pwant_read, bool *pwant_write); - /** * Types and macros used to keep the current easy handle in filter calls, * allowing for nested invocations. See #10336. diff --git a/vendor/curl/lib/config-mac.h b/vendor/curl/lib/config-mac.h index 1a902b89f5f..6da544fe8fa 100644 --- a/vendor/curl/lib/config-mac.h +++ b/vendor/curl/lib/config-mac.h @@ -43,7 +43,6 @@ #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 @@ -51,9 +50,7 @@ #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 diff --git a/vendor/curl/lib/config-os400.h b/vendor/curl/lib/config-os400.h index 4316c58acd9..bccdb4a8974 100644 --- a/vendor/curl/lib/config-os400.h +++ b/vendor/curl/lib/config-os400.h @@ -158,18 +158,9 @@ /* 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 @@ -212,10 +203,6 @@ /* Define if you have the ANSI C header files. */ #define STDC_HEADERS -/* Define to enable HTTP3 support (experimental, requires NGTCP2, quiche or - MSH3) */ -#undef USE_HTTP3 - /* Version number of package */ #undef VERSION diff --git a/vendor/curl/lib/config-plan9.h b/vendor/curl/lib/config-plan9.h index 857b7866489..68d0cf7f569 100644 --- a/vendor/curl/lib/config-plan9.h +++ b/vendor/curl/lib/config-plan9.h @@ -113,9 +113,6 @@ #define HAVE_SYS_IOCTL_H 1 #define HAVE_SYS_PARAM_H 1 #define HAVE_SYS_RESOURCE_H 1 -#define HAVE_SYS_SOCKET_H 1 -#define HAVE_SYS_STAT_H 1 -#define HAVE_SYS_TIME_H 1 #define HAVE_SYS_TYPES_H 1 #define HAVE_SYS_UN_H 1 #define HAVE_TERMIOS_H 1 diff --git a/vendor/curl/lib/config-riscos.h b/vendor/curl/lib/config-riscos.h index b8aaa5d413b..3158c984ee3 100644 --- a/vendor/curl/lib/config-riscos.h +++ b/vendor/curl/lib/config-riscos.h @@ -144,18 +144,9 @@ /* 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. */ -#undef 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 @@ -186,9 +177,6 @@ /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS -/* Define for large files, on AIX-style hosts. */ -#undef _LARGE_FILES - /* Define to empty if `const' does not conform to ANSI C. */ #undef const diff --git a/vendor/curl/lib/config-win32.h b/vendor/curl/lib/config-win32.h index c9ba42762d6..b7f83927a43 100644 --- a/vendor/curl/lib/config-win32.h +++ b/vendor/curl/lib/config-win32.h @@ -28,6 +28,58 @@ /* Hand crafted config file for Windows */ /* ================================================================ */ +#ifndef UNDER_CE + +/* Define some minimum and default build targets for Visual Studio */ +#ifdef _MSC_VER + /* VS2012 default target settings and minimum build target check. */ +# if _MSC_VER >= 1700 + /* The minimum and default build targets for VS2012 are Vista and 8, + respectively, unless Update 1 is installed and the v110_xp toolset + is chosen. */ +# ifdef _USING_V110_SDK71_ +# define VS2012_MIN_TARGET 0x0501 /* XP */ +# define VS2012_DEF_TARGET 0x0501 /* XP */ +# else +# define VS2012_MIN_TARGET 0x0600 /* Vista */ +# define VS2012_DEF_TARGET 0x0602 /* 8 */ +# endif + +# ifndef _WIN32_WINNT +# define _WIN32_WINNT VS2012_DEF_TARGET +# endif +# ifndef WINVER +# define WINVER VS2012_DEF_TARGET +# endif +# if (_WIN32_WINNT < VS2012_MIN_TARGET) || (WINVER < VS2012_MIN_TARGET) +# ifdef _USING_V110_SDK71_ +# error VS2012 does not support build targets prior to Windows XP +# else +# error VS2012 does not support build targets prior to Windows Vista +# endif +# endif + /* Default target settings and minimum build target check for + VS2008 and VS2010 */ +# else +# define VS2008_MIN_TARGET 0x0501 /* XP */ + /* VS2008 default build target is Windows Vista (0x0600). + We override default target to be Windows XP. */ +# define VS2008_DEF_TARGET 0x0501 /* XP */ + +# ifndef _WIN32_WINNT +# define _WIN32_WINNT VS2008_DEF_TARGET +# endif +# ifndef WINVER +# define WINVER VS2008_DEF_TARGET +# endif +# if (_WIN32_WINNT < VS2008_MIN_TARGET) || (WINVER < VS2008_MIN_TARGET) +# error VS2008 does not support build targets prior to Windows XP +# endif +# endif +#endif /* _MSC_VER */ + +#endif /* UNDER_CE */ + /* ---------------------------------------------------------------- */ /* HEADER FILES */ /* ---------------------------------------------------------------- */ @@ -74,20 +126,9 @@ /* Define if you have the header file. */ /* #define HAVE_SYS_SELECT_H 1 */ -/* Define if you have the header file. */ -/* #define HAVE_SYS_SOCKET_H 1 */ - /* Define if you have the header file. */ /* #define HAVE_SYS_SOCKIO_H 1 */ -/* Define if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define if you have the header file. */ -#ifdef __MINGW32__ -#define HAVE_SYS_TIME_H 1 -#endif - /* Define if you have the header file. */ #define HAVE_SYS_TYPES_H 1 @@ -223,13 +264,11 @@ #define HAVE_SNPRINTF 1 #endif -/* Vista */ -#if (defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x600) && !defined(UNDER_CE) +/* Must always use local implementations on Windows. */ /* Define to 1 if you have an IPv6 capable working inet_ntop function. */ -#define HAVE_INET_NTOP 1 +/* #undef HAVE_INET_NTOP */ /* Define to 1 if you have an IPv6 capable working inet_pton function. */ -#define HAVE_INET_PTON 1 -#endif +/* #undef HAVE_INET_PTON */ /* Define to 1 if you have the `basename' function. */ #ifdef __MINGW32__ @@ -307,72 +346,6 @@ # endif #endif -#ifndef UNDER_CE - -/* Define some minimum and default build targets for Visual Studio */ -#ifdef _MSC_VER - /* Officially, Microsoft's Windows SDK versions 6.X does not support Windows - 2000 as a supported build target. VS2008 default installations provides - an embedded Windows SDK v6.0A along with the claim that Windows 2000 is a - valid build target for VS2008. Popular belief is that binaries built with - VS2008 using Windows SDK versions v6.X and Windows 2000 as a build target - are functional. */ -# define VS2008_MIN_TARGET 0x0500 - - /* The minimum build target for VS2012 is Vista unless Update 1 is installed - and the v110_xp toolset is chosen. */ -# ifdef _USING_V110_SDK71_ -# define VS2012_MIN_TARGET 0x0501 -# else -# define VS2012_MIN_TARGET 0x0600 -# endif - - /* VS2008 default build target is Windows Vista. We override default target - to be Windows XP. */ -# define VS2008_DEF_TARGET 0x0501 - - /* VS2012 default build target is Windows Vista unless Update 1 is installed - and the v110_xp toolset is chosen. */ -# ifdef _USING_V110_SDK71_ -# define VS2012_DEF_TARGET 0x0501 -# else -# define VS2012_DEF_TARGET 0x0600 -# endif -#endif - -/* VS2008 default target settings and minimum build target check. */ -#if defined(_MSC_VER) && (_MSC_VER <= 1600) -# ifndef _WIN32_WINNT -# define _WIN32_WINNT VS2008_DEF_TARGET -# endif -# ifndef WINVER -# define WINVER VS2008_DEF_TARGET -# endif -# if (_WIN32_WINNT < VS2008_MIN_TARGET) || (WINVER < VS2008_MIN_TARGET) -# error VS2008 does not support Windows build targets prior to Windows 2000 -# endif -#endif - -/* VS2012 default target settings and minimum build target check. */ -#if defined(_MSC_VER) && (_MSC_VER >= 1700) -# ifndef _WIN32_WINNT -# define _WIN32_WINNT VS2012_DEF_TARGET -# endif -# ifndef WINVER -# define WINVER VS2012_DEF_TARGET -# endif -# if (_WIN32_WINNT < VS2012_MIN_TARGET) || (WINVER < VS2012_MIN_TARGET) -# ifdef _USING_V110_SDK71_ -# error VS2012 does not support Windows build targets prior to Windows XP -# else -# error VS2012 does not support Windows build targets prior to Windows \ -Vista -# endif -# endif -#endif - -#endif /* UNDER_CE */ - /* Windows XP is required for freeaddrinfo, getaddrinfo */ #ifndef UNDER_CE #define HAVE_FREEADDRINFO 1 diff --git a/vendor/curl/lib/conncache.c b/vendor/curl/lib/conncache.c index f5e2ea87252..1393bb565be 100644 --- a/vendor/curl/lib/conncache.c +++ b/vendor/curl/lib/conncache.c @@ -42,7 +42,6 @@ #include "sigpipe.h" #include "connect.h" #include "select.h" -#include "strcase.h" #include "curlx/strparse.h" #include "uint-table.h" @@ -516,7 +515,7 @@ static bool cpool_foreach(struct Curl_easy *data, struct connectdata *conn = Curl_node_elem(curr); curr = Curl_node_next(curr); - if(1 == func(data, conn, param)) { + if(func(data, conn, param) == 1) { return TRUE; } } @@ -710,7 +709,8 @@ static int cpool_reap_dead_cb(struct Curl_easy *data, struct connectdata *conn, void *param) { struct cpool_reaper_ctx *rctx = param; - if(Curl_conn_seems_dead(conn, data, &rctx->now)) { + if((!CONN_INUSE(conn) && conn->bits.no_reuse) || + Curl_conn_seems_dead(conn, data, &rctx->now)) { /* stop the iteration here, pass back the connection that was pruned */ Curl_conn_terminate(data, conn, FALSE); return 1; @@ -850,6 +850,40 @@ void Curl_cpool_do_locked(struct Curl_easy *data, cb(conn, data, cbdata); } +static int cpool_mark_stale(struct Curl_easy *data, + struct connectdata *conn, void *param) +{ + (void)data; + (void)param; + conn->bits.no_reuse = TRUE; + return 0; +} + +static int cpool_reap_no_reuse(struct Curl_easy *data, + struct connectdata *conn, void *param) +{ + (void)data; + (void)param; + if(!CONN_INUSE(conn) && conn->bits.no_reuse) { + Curl_conn_terminate(data, conn, FALSE); + return 1; + } + return 0; /* continue iteration */ +} + +void Curl_cpool_nw_changed(struct Curl_easy *data) +{ + struct cpool *cpool = cpool_get_instance(data); + + if(cpool) { + CPOOL_LOCK(cpool, data); + cpool_foreach(data, cpool, NULL, cpool_mark_stale); + while(cpool_foreach(data, cpool, NULL, cpool_reap_no_reuse)) + ; + CPOOL_UNLOCK(cpool, data); + } +} + #if 0 /* Useful for debugging the connection pool */ void Curl_cpool_print(struct cpool *cpool) diff --git a/vendor/curl/lib/conncache.h b/vendor/curl/lib/conncache.h index 1314b65c607..a5f133344fd 100644 --- a/vendor/curl/lib/conncache.h +++ b/vendor/curl/lib/conncache.h @@ -106,7 +106,7 @@ typedef bool Curl_cpool_done_match_cb(bool result, void *userdata); * Find a connection in the pool matching `destination`. * All callbacks are invoked while the pool's lock is held. * @param data current transfer - * @param destination match agaonst `conn->destination` in pool + * @param destination match against `conn->destination` in pool * @param conn_cb must be present, called for each connection in the * bundle until it returns TRUE * @return combined result of last conn_db and result_cb or FALSE if no @@ -163,4 +163,8 @@ void Curl_cpool_do_locked(struct Curl_easy *data, struct connectdata *conn, Curl_cpool_conn_do_cb *cb, void *cbdata); +/* Close all unused connections, prevent reuse of existing ones. */ +void Curl_cpool_nw_changed(struct Curl_easy *data); + + #endif /* HEADER_CURL_CONNCACHE_H */ diff --git a/vendor/curl/lib/connect.c b/vendor/curl/lib/connect.c index 1dcdde3fc5a..f0628d6206e 100644 --- a/vendor/curl/lib/connect.c +++ b/vendor/curl/lib/connect.c @@ -61,12 +61,13 @@ #include "connect.h" #include "cf-haproxy.h" #include "cf-https-connect.h" +#include "cf-ip-happy.h" #include "cf-socket.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 "curlx/inet_ntop.h" #include "curlx/inet_pton.h" #include "vtls/vtls.h" /* for vtsl cfilters */ #include "progress.h" @@ -74,11 +75,8 @@ #include "conncache.h" #include "multihandle.h" #include "share.h" -#include "curlx/version_win32.h" -#include "vquic/vquic.h" /* for quic cfilters */ #include "http_proxy.h" #include "socks.h" -#include "strcase.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -90,15 +88,15 @@ enum alpnid Curl_alpn2alpnid(const char *name, size_t len) { if(len == 2) { - if(strncasecompare(name, "h1", 2)) + if(curl_strnequal(name, "h1", 2)) return ALPN_h1; - if(strncasecompare(name, "h2", 2)) + if(curl_strnequal(name, "h2", 2)) return ALPN_h2; - if(strncasecompare(name, "h3", 2)) + if(curl_strnequal(name, "h3", 2)) return ALPN_h3; } else if(len == 8) { - if(strncasecompare(name, "http/1.1", 8)) + if(curl_strnequal(name, "http/1.1", 8)) return ALPN_h1; } return ALPN_none; /* unknown, probably rubbish input */ @@ -172,11 +170,11 @@ void Curl_shutdown_start(struct Curl_easy *data, int sockindex, } data->conn->shutdown.start[sockindex] = *nowp; data->conn->shutdown.timeout_ms = (timeout_ms > 0) ? - (unsigned int)timeout_ms : + (timediff_t)timeout_ms : ((data->set.shutdowntimeout > 0) ? data->set.shutdowntimeout : DEFAULT_SHUTDOWN_TIMEOUT_MS); /* Set a timer, unless we operate on the admin handle */ - if(data->mid && data->conn->shutdown.timeout_ms) + if(data->mid && (data->conn->shutdown.timeout_ms > 0)) Curl_expire_ex(data, nowp, data->conn->shutdown.timeout_ms, EXPIRE_SHUTDOWN); } @@ -187,7 +185,8 @@ timediff_t Curl_shutdown_timeleft(struct connectdata *conn, int sockindex, struct curltime now; timediff_t left_ms; - if(!conn->shutdown.start[sockindex].tv_sec || !conn->shutdown.timeout_ms) + if(!conn->shutdown.start[sockindex].tv_sec || + (conn->shutdown.timeout_ms <= 0)) return 0; /* not started or no limits */ if(!nowp) { @@ -232,30 +231,8 @@ bool Curl_shutdown_started(struct Curl_easy *data, int sockindex) return (pt->tv_sec > 0) || (pt->tv_usec > 0); } -static const struct Curl_addrinfo * -addr_first_match(const struct Curl_addrinfo *addr, int family) -{ - while(addr) { - if(addr->ai_family == family) - return addr; - addr = addr->ai_next; - } - return NULL; -} - -static const struct Curl_addrinfo * -addr_next_match(const struct Curl_addrinfo *addr, int family) -{ - while(addr && addr->ai_next) { - addr = addr->ai_next; - if(addr->ai_family == family) - return addr; - } - return NULL; -} - -/* retrieves ip address and port from a sockaddr structure. - note it calls Curl_inet_ntop which sets errno on fail, not SOCKERRNO. */ +/* retrieves ip address and port from a sockaddr structure. note it calls + curlx_inet_ntop which sets errno on fail, not SOCKERRNO. */ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, char *addr, int *port) { @@ -272,7 +249,7 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, switch(sa->sa_family) { case AF_INET: si = (struct sockaddr_in *)(void *) sa; - if(Curl_inet_ntop(sa->sa_family, &si->sin_addr, addr, MAX_IPADR_LEN)) { + if(curlx_inet_ntop(sa->sa_family, &si->sin_addr, addr, MAX_IPADR_LEN)) { unsigned short us_port = ntohs(si->sin_port); *port = us_port; return TRUE; @@ -281,7 +258,8 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, #ifdef USE_IPV6 case AF_INET6: si6 = (struct sockaddr_in6 *)(void *) sa; - if(Curl_inet_ntop(sa->sa_family, &si6->sin6_addr, addr, MAX_IPADR_LEN)) { + if(curlx_inet_ntop(sa->sa_family, &si6->sin6_addr, addr, + MAX_IPADR_LEN)) { unsigned short us_port = ntohs(si6->sin6_port); *port = us_port; return TRUE; @@ -371,877 +349,6 @@ void Curl_conncontrol(struct connectdata *conn, } } -/** - * job walking the matching addr infos, creating a sub-cfilter with the - * provided method `cf_create` and running setup/connect on it. - */ -struct eyeballer { - const char *name; - const struct Curl_addrinfo *first; /* complete address list, not owned */ - const struct Curl_addrinfo *addr; /* List of addresses to try, not owned */ - int ai_family; /* matching address family only */ - cf_ip_connect_create *cf_create; /* for creating cf */ - struct Curl_cfilter *cf; /* current sub-cfilter connecting */ - struct eyeballer *primary; /* eyeballer this one is backup for */ - timediff_t delay_ms; /* delay until start */ - struct curltime started; /* start of current attempt */ - timediff_t timeoutms; /* timeout for current attempt */ - expire_id timeout_id; /* ID for Curl_expire() */ - CURLcode result; - int error; - BIT(rewinded); /* if we rewinded the addr list */ - BIT(has_started); /* attempts have started */ - BIT(is_done); /* out of addresses/time */ - BIT(connected); /* cf has connected */ - BIT(shutdown); /* cf has shutdown */ - BIT(inconclusive); /* connect was not a hard failure, we - * might talk to a restarting server */ -}; - - -typedef enum { - SCFST_INIT, - SCFST_WAITING, - SCFST_DONE -} cf_connect_state; - -struct cf_he_ctx { - int transport; - cf_ip_connect_create *cf_create; - cf_connect_state state; - struct eyeballer *baller[2]; - struct eyeballer *winner; - struct curltime started; -}; - -/* when there are more than one IP address left to use, this macro returns how - much of the given timeout to spend on *this* attempt */ -#define TIMEOUT_LARGE 600 -#define USETIME(ms) ((ms > TIMEOUT_LARGE) ? (ms / 2) : ms) - -static CURLcode eyeballer_new(struct eyeballer **pballer, - cf_ip_connect_create *cf_create, - const struct Curl_addrinfo *addr, - int ai_family, - struct eyeballer *primary, - timediff_t delay_ms, - timediff_t timeout_ms, - expire_id timeout_id) -{ - struct eyeballer *baller; - - *pballer = NULL; - baller = calloc(1, sizeof(*baller)); - if(!baller) - return CURLE_OUT_OF_MEMORY; - - baller->name = ((ai_family == AF_INET) ? "ipv4" : ( -#ifdef USE_IPV6 - (ai_family == AF_INET6) ? "ipv6" : -#endif - "ip")); - baller->cf_create = cf_create; - baller->first = baller->addr = addr; - baller->ai_family = ai_family; - baller->primary = primary; - baller->delay_ms = delay_ms; - baller->timeoutms = addr_next_match(baller->addr, baller->ai_family) ? - USETIME(timeout_ms) : timeout_ms; - baller->timeout_id = timeout_id; - baller->result = CURLE_COULDNT_CONNECT; - - *pballer = baller; - return CURLE_OK; -} - -static void baller_close(struct eyeballer *baller, - struct Curl_easy *data) -{ - if(baller && baller->cf) { - Curl_conn_cf_discard_chain(&baller->cf, data); - } -} - -static void baller_free(struct eyeballer *baller, - struct Curl_easy *data) -{ - if(baller) { - baller_close(baller, data); - free(baller); - } -} - -static void baller_rewind(struct eyeballer *baller) -{ - baller->rewinded = TRUE; - baller->addr = baller->first; - baller->inconclusive = FALSE; -} - -static void baller_next_addr(struct eyeballer *baller) -{ - baller->addr = addr_next_match(baller->addr, baller->ai_family); -} - -/* - * Initiate a connect attempt walk. - * - * Note that even on connect fail it returns CURLE_OK, but with 'sock' set to - * CURL_SOCKET_BAD. Other errors will however return proper errors. - */ -static void baller_initiate(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct eyeballer *baller) -{ - struct cf_he_ctx *ctx = cf->ctx; - struct Curl_cfilter *cf_prev = baller->cf; - struct Curl_cfilter *wcf; - CURLcode result; - - - /* Do not close a previous cfilter yet to ensure that the next IP's - socket gets a different file descriptor, which can prevent bugs when - the curl_multi_socket_action interface is used with certain select() - replacements such as kqueue. */ - result = baller->cf_create(&baller->cf, data, cf->conn, baller->addr, - ctx->transport); - if(result) - goto out; - - /* the new filter might have sub-filters */ - for(wcf = baller->cf; wcf; wcf = wcf->next) { - wcf->conn = cf->conn; - wcf->sockindex = cf->sockindex; - } - - if(addr_next_match(baller->addr, baller->ai_family)) { - Curl_expire(data, baller->timeoutms, baller->timeout_id); - } - -out: - if(result) { - CURL_TRC_CF(data, cf, "%s failed", baller->name); - baller_close(baller, data); - } - if(cf_prev) - Curl_conn_cf_discard_chain(&cf_prev, data); - baller->result = result; -} - -/** - * Start a connection attempt on the current baller address. - * Will return CURLE_OK on the first address where a socket - * could be created and the non-blocking connect started. - * Returns error when all remaining addresses have been tried. - */ -static CURLcode baller_start(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct eyeballer *baller, - timediff_t timeoutms) -{ - baller->error = 0; - baller->connected = FALSE; - baller->has_started = TRUE; - - while(baller->addr) { - baller->started = curlx_now(); - baller->timeoutms = addr_next_match(baller->addr, baller->ai_family) ? - USETIME(timeoutms) : timeoutms; - baller_initiate(cf, data, baller); - if(!baller->result) - break; - baller_next_addr(baller); - } - if(!baller->addr) { - baller->is_done = TRUE; - } - return baller->result; -} - - -/* Used within the multi interface. Try next IP address, returns error if no - more address exists or error */ -static CURLcode baller_start_next(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct eyeballer *baller, - timediff_t timeoutms) -{ - if(cf->sockindex == FIRSTSOCKET) { - baller_next_addr(baller); - /* If we get inconclusive answers from the server(s), we start - * again until this whole thing times out. This allows us to - * connect to servers that are gracefully restarting and the - * packet routing to the new instance has not happened yet (e.g. QUIC). */ - if(!baller->addr && baller->inconclusive) - baller_rewind(baller); - baller_start(cf, data, baller, timeoutms); - } - else { - baller->error = 0; - baller->connected = FALSE; - baller->has_started = TRUE; - baller->is_done = TRUE; - baller->result = CURLE_COULDNT_CONNECT; - } - return baller->result; -} - -static CURLcode baller_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct eyeballer *baller, - struct curltime *now, - bool *connected) -{ - (void)cf; - *connected = baller->connected; - if(!baller->result && !*connected) { - /* evaluate again */ - baller->result = Curl_conn_cf_connect(baller->cf, data, connected); - - if(!baller->result) { - if(*connected) { - baller->connected = TRUE; - baller->is_done = TRUE; - } - else if(curlx_timediff(*now, baller->started) >= baller->timeoutms) { - infof(data, "%s connect timeout after %" FMT_TIMEDIFF_T - "ms, move on!", baller->name, baller->timeoutms); -#ifdef SOCKETIMEDOUT - baller->error = SOCKETIMEDOUT; -#endif - baller->result = CURLE_OPERATION_TIMEDOUT; - } - } - else if(baller->result == CURLE_WEIRD_SERVER_REPLY) - baller->inconclusive = TRUE; - } - return baller->result; -} - -/* - * is_connected() checks if the socket has connected. - */ -static CURLcode is_connected(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *connected) -{ - struct cf_he_ctx *ctx = cf->ctx; - struct connectdata *conn = cf->conn; - CURLcode result; - struct curltime now; - size_t i; - int ongoing, not_started; - const char *hostname; - - /* Check if any of the conn->tempsock we use for establishing connections - * succeeded and, if so, close any ongoing other ones. - * Transfer the successful conn->tempsock to conn->sock[sockindex] - * and set conn->tempsock to CURL_SOCKET_BAD. - * If transport is QUIC, we need to shutdown the ongoing 'other' - * cot ballers in a QUIC appropriate way. */ -evaluate: - *connected = FALSE; /* a negative world view is best */ - now = curlx_now(); - ongoing = not_started = 0; - for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { - struct eyeballer *baller = ctx->baller[i]; - - if(!baller || baller->is_done) - continue; - - if(!baller->has_started) { - ++not_started; - continue; - } - baller->result = baller_connect(cf, data, baller, &now, connected); - CURL_TRC_CF(data, cf, "%s connect -> %d, connected=%d", - baller->name, baller->result, *connected); - - if(!baller->result) { - if(*connected) { - /* connected, declare the winner */ - ctx->winner = baller; - ctx->baller[i] = NULL; - break; - } - else { /* still waiting */ - ++ongoing; - } - } - else if(!baller->is_done) { - /* The baller failed to connect, start its next attempt */ - if(baller->error) { - data->state.os_errno = baller->error; - SET_SOCKERRNO(baller->error); - } - baller_start_next(cf, data, baller, Curl_timeleft(data, &now, TRUE)); - if(baller->is_done) { - CURL_TRC_CF(data, cf, "%s done", baller->name); - } - else { - /* next attempt was started */ - CURL_TRC_CF(data, cf, "%s trying next", baller->name); - ++ongoing; - Curl_expire(data, 0, EXPIRE_RUN_NOW); - } - } - } - - if(ctx->winner) { - *connected = TRUE; - return CURLE_OK; - } - - /* Nothing connected, check the time before we might - * start new ballers or return ok. */ - if((ongoing || not_started) && Curl_timeleft(data, &now, TRUE) < 0) { - failf(data, "Connection timeout after %" FMT_OFF_T " ms", - curlx_timediff(now, data->progress.t_startsingle)); - return CURLE_OPERATION_TIMEDOUT; - } - - /* Check if we have any waiting ballers to start now. */ - if(not_started > 0) { - int added = 0; - - for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { - struct eyeballer *baller = ctx->baller[i]; - - if(!baller || baller->has_started) - continue; - /* We start its primary baller has failed to connect or if - * its start delay_ms have expired */ - if((baller->primary && baller->primary->is_done) || - curlx_timediff(now, ctx->started) >= baller->delay_ms) { - baller_start(cf, data, baller, Curl_timeleft(data, &now, TRUE)); - if(baller->is_done) { - CURL_TRC_CF(data, cf, "%s done", baller->name); - } - else { - CURL_TRC_CF(data, cf, "%s starting (timeout=%" FMT_TIMEDIFF_T "ms)", - baller->name, baller->timeoutms); - ++ongoing; - ++added; - } - } - } - if(added > 0) - goto evaluate; - } - - if(ongoing > 0) { - /* We are still trying, return for more waiting */ - *connected = FALSE; - return CURLE_OK; - } - - /* all ballers have failed to connect. */ - CURL_TRC_CF(data, cf, "all eyeballers failed"); - result = CURLE_COULDNT_CONNECT; - for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { - struct eyeballer *baller = ctx->baller[i]; - if(!baller) - continue; - CURL_TRC_CF(data, cf, "%s assess started=%d, result=%d", - baller->name, baller->has_started, baller->result); - if(baller->has_started && baller->result) { - result = baller->result; - break; - } - } - -#ifndef CURL_DISABLE_PROXY - if(conn->bits.socksproxy) - hostname = conn->socks_proxy.host.name; - else if(conn->bits.httpproxy) - hostname = conn->http_proxy.host.name; - else -#endif - if(conn->bits.conn_to_host) - hostname = conn->conn_to_host.name; - else - hostname = conn->host.name; - - failf(data, "Failed to connect to %s port %u after " - "%" FMT_TIMEDIFF_T " ms: %s", - hostname, conn->primary.remote_port, - curlx_timediff(now, data->progress.t_startsingle), - curl_easy_strerror(result)); - -#ifdef SOCKETIMEDOUT - if(SOCKETIMEDOUT == data->state.os_errno) - result = CURLE_OPERATION_TIMEDOUT; -#endif - - return result; -} - -/* - * Connect to the given host with timeout, proxy or remote does not matter. - * There might be more than one IP address to try out. - */ -static CURLcode start_connect(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_he_ctx *ctx = cf->ctx; - struct connectdata *conn = cf->conn; - CURLcode result = CURLE_COULDNT_CONNECT; - int ai_family0 = 0, ai_family1 = 0; - timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); - const struct Curl_addrinfo *addr0 = NULL, *addr1 = NULL; - struct Curl_dns_entry *dns = data->state.dns[cf->sockindex]; - - if(!dns) - return CURLE_FAILED_INIT; - - if(timeout_ms < 0) { - /* a precaution, no need to continue if time already is up */ - failf(data, "Connection time-out"); - return CURLE_OPERATION_TIMEDOUT; - } - - ctx->started = curlx_now(); - - /* dns->addr is the list of addresses from the resolver, each - * with an address family. The list has at least one entry, possibly - * many more. - * We try at most 2 at a time, until we either get a connection or - * run out of addresses to try. Since likelihood of success is tied - * to the address family (e.g. IPV6 might not work at all ), we want - * the 2 connect attempt ballers to try different families, if possible. - * - */ - if(conn->ip_version == CURL_IPRESOLVE_V6) { -#ifdef USE_IPV6 - ai_family0 = AF_INET6; - addr0 = addr_first_match(dns->addr, ai_family0); -#endif - } - else if(conn->ip_version == CURL_IPRESOLVE_V4) { - ai_family0 = AF_INET; - addr0 = addr_first_match(dns->addr, ai_family0); - } - else { - /* no user preference, we try ipv6 always first when available */ -#ifdef USE_IPV6 - ai_family0 = AF_INET6; - addr0 = addr_first_match(dns->addr, ai_family0); -#endif - /* next candidate is ipv4 */ - ai_family1 = AF_INET; - addr1 = addr_first_match(dns->addr, ai_family1); - /* no ip address families, probably AF_UNIX or something, use the - * address family given to us */ - if(!addr1 && !addr0 && dns->addr) { - ai_family0 = dns->addr->ai_family; - addr0 = addr_first_match(dns->addr, ai_family0); - } - } - - if(!addr0 && addr1) { - /* switch around, so a single baller always uses addr0 */ - addr0 = addr1; - ai_family0 = ai_family1; - addr1 = NULL; - } - - /* We found no address that matches our criteria, we cannot connect */ - if(!addr0) { - return CURLE_COULDNT_CONNECT; - } - - memset(ctx->baller, 0, sizeof(ctx->baller)); - result = eyeballer_new(&ctx->baller[0], ctx->cf_create, addr0, ai_family0, - NULL, 0, /* no primary/delay, start now */ - timeout_ms, EXPIRE_DNS_PER_NAME); - if(result) - return result; - CURL_TRC_CF(data, cf, "created %s (timeout %" FMT_TIMEDIFF_T "ms)", - ctx->baller[0]->name, ctx->baller[0]->timeoutms); - if(addr1) { - /* second one gets a delayed start */ - result = eyeballer_new(&ctx->baller[1], ctx->cf_create, addr1, ai_family1, - ctx->baller[0], /* wait on that to fail */ - /* or start this delayed */ - data->set.happy_eyeballs_timeout, - timeout_ms, EXPIRE_DNS_PER_NAME2); - if(result) - return result; - CURL_TRC_CF(data, cf, "created %s (timeout %" FMT_TIMEDIFF_T "ms)", - ctx->baller[1]->name, ctx->baller[1]->timeoutms); - Curl_expire(data, data->set.happy_eyeballs_timeout, - EXPIRE_HAPPY_EYEBALLS); - } - - return CURLE_OK; -} - -static void cf_he_ctx_clear(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct cf_he_ctx *ctx = cf->ctx; - size_t i; - - DEBUGASSERT(ctx); - DEBUGASSERT(data); - for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { - baller_free(ctx->baller[i], data); - ctx->baller[i] = NULL; - } - baller_free(ctx->winner, data); - ctx->winner = NULL; -} - -static CURLcode cf_he_shutdown(struct Curl_cfilter *cf, - struct Curl_easy *data, bool *done) -{ - struct cf_he_ctx *ctx = cf->ctx; - size_t i; - CURLcode result = CURLE_OK; - - DEBUGASSERT(data); - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - /* shutdown all ballers that have not done so already. If one fails, - * continue shutting down others until all are shutdown. */ - for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { - struct eyeballer *baller = ctx->baller[i]; - bool bdone = FALSE; - if(!baller || !baller->cf || baller->shutdown) - continue; - baller->result = baller->cf->cft->do_shutdown(baller->cf, data, &bdone); - if(baller->result || bdone) - baller->shutdown = TRUE; /* treat a failed shutdown as done */ - } - - *done = TRUE; - for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { - if(ctx->baller[i] && !ctx->baller[i]->shutdown) - *done = FALSE; - } - if(*done) { - for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { - if(ctx->baller[i] && ctx->baller[i]->result) - result = ctx->baller[i]->result; - } - } - CURL_TRC_CF(data, cf, "shutdown -> %d, done=%d", result, *done); - return result; -} - -static void cf_he_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct cf_he_ctx *ctx = cf->ctx; - size_t i; - - if(!cf->connected) { - for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { - struct eyeballer *baller = ctx->baller[i]; - if(!baller || !baller->cf) - continue; - Curl_conn_cf_adjust_pollset(baller->cf, data, ps); - } - CURL_TRC_CF(data, cf, "adjust_pollset -> %d socks", ps->num); - } -} - -static CURLcode cf_he_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct cf_he_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - DEBUGASSERT(ctx); - *done = FALSE; - - switch(ctx->state) { - case SCFST_INIT: - DEBUGASSERT(CURL_SOCKET_BAD == Curl_conn_cf_get_socket(cf, data)); - DEBUGASSERT(!cf->connected); - result = start_connect(cf, data); - if(result) - return result; - ctx->state = SCFST_WAITING; - FALLTHROUGH(); - case SCFST_WAITING: - result = is_connected(cf, data, done); - if(!result && *done) { - DEBUGASSERT(ctx->winner); - DEBUGASSERT(ctx->winner->cf); - DEBUGASSERT(ctx->winner->cf->connected); - /* we have a winner. Install and activate it. - * close/free all others. */ - ctx->state = SCFST_DONE; - cf->connected = TRUE; - cf->next = ctx->winner->cf; - ctx->winner->cf = NULL; - cf_he_ctx_clear(cf, data); - - if(cf->conn->handler->protocol & PROTO_FAMILY_SSH) - Curl_pgrsTime(data, TIMER_APPCONNECT); /* we are connected already */ - if(Curl_trc_cf_is_verbose(cf, data)) { - struct ip_quadruple ipquad; - int is_ipv6; - if(!Curl_conn_cf_get_ip_info(cf->next, data, &is_ipv6, &ipquad)) { - const char *host, *disphost; - int port; - cf->next->cft->get_host(cf->next, data, &host, &disphost, &port); - CURL_TRC_CF(data, cf, "Connected to %s (%s) port %u", - disphost, ipquad.remote_ip, ipquad.remote_port); - } - } - data->info.numconnects++; /* to track the # of connections made */ - } - break; - case SCFST_DONE: - *done = TRUE; - break; - } - return result; -} - -static void cf_he_close(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_he_ctx *ctx = cf->ctx; - - CURL_TRC_CF(data, cf, "close"); - cf_he_ctx_clear(cf, data); - cf->connected = FALSE; - ctx->state = SCFST_INIT; - - if(cf->next) { - cf->next->cft->do_close(cf->next, data); - Curl_conn_cf_discard_chain(&cf->next, data); - } -} - -static bool cf_he_data_pending(struct Curl_cfilter *cf, - const struct Curl_easy *data) -{ - struct cf_he_ctx *ctx = cf->ctx; - size_t i; - - if(cf->connected) - return cf->next->cft->has_data_pending(cf->next, data); - - for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { - struct eyeballer *baller = ctx->baller[i]; - if(!baller || !baller->cf) - continue; - if(baller->cf->cft->has_data_pending(baller->cf, data)) - return TRUE; - } - return FALSE; -} - -static struct curltime get_max_baller_time(struct Curl_cfilter *cf, - struct Curl_easy *data, - int query) -{ - struct cf_he_ctx *ctx = cf->ctx; - struct curltime t, tmax; - size_t i; - - memset(&tmax, 0, sizeof(tmax)); - for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { - struct eyeballer *baller = ctx->baller[i]; - - memset(&t, 0, sizeof(t)); - if(baller && baller->cf && - !baller->cf->cft->query(baller->cf, data, query, NULL, &t)) { - if((t.tv_sec || t.tv_usec) && curlx_timediff_us(t, tmax) > 0) - tmax = t; - } - } - return tmax; -} - -static CURLcode cf_he_query(struct Curl_cfilter *cf, - struct Curl_easy *data, - int query, int *pres1, void *pres2) -{ - struct cf_he_ctx *ctx = cf->ctx; - - if(!cf->connected) { - switch(query) { - case CF_QUERY_CONNECT_REPLY_MS: { - int reply_ms = -1; - size_t i; - - for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { - struct eyeballer *baller = ctx->baller[i]; - int breply_ms; - - if(baller && baller->cf && - !baller->cf->cft->query(baller->cf, data, query, - &breply_ms, NULL)) { - if(breply_ms >= 0 && (reply_ms < 0 || breply_ms < reply_ms)) - reply_ms = breply_ms; - } - } - *pres1 = reply_ms; - CURL_TRC_CF(data, cf, "query connect reply: %dms", *pres1); - return CURLE_OK; - } - case CF_QUERY_TIMER_CONNECT: { - struct curltime *when = pres2; - *when = get_max_baller_time(cf, data, CF_QUERY_TIMER_CONNECT); - return CURLE_OK; - } - case CF_QUERY_TIMER_APPCONNECT: { - struct curltime *when = pres2; - *when = 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_he_destroy(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct cf_he_ctx *ctx = cf->ctx; - - CURL_TRC_CF(data, cf, "destroy"); - if(ctx) { - cf_he_ctx_clear(cf, data); - } - /* release any resources held in state */ - Curl_safefree(ctx); -} - -struct Curl_cftype Curl_cft_happy_eyeballs = { - "HAPPY-EYEBALLS", - 0, - CURL_LOG_LVL_NONE, - cf_he_destroy, - cf_he_connect, - cf_he_close, - cf_he_shutdown, - Curl_cf_def_get_host, - cf_he_adjust_pollset, - cf_he_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_he_query, -}; - -/** - * Create a happy eyeball connection filter that uses the, once resolved, - * address information to connect on ip families based on connection - * configuration. - * @param pcf output, the created cfilter - * @param data easy handle used in creation - * @param conn connection the filter is created for - * @param cf_create method to create the sub-filters performing the - * actual connects. - */ -static CURLcode -cf_happy_eyeballs_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn, - cf_ip_connect_create *cf_create, - int transport) -{ - struct cf_he_ctx *ctx = NULL; - CURLcode result; - - (void)data; - (void)conn; - *pcf = NULL; - ctx = calloc(1, sizeof(*ctx)); - if(!ctx) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - ctx->transport = transport; - ctx->cf_create = cf_create; - - result = Curl_cf_create(pcf, &Curl_cft_happy_eyeballs, ctx); - -out: - if(result) { - Curl_safefree(*pcf); - free(ctx); - } - return result; -} - -struct transport_provider { - int transport; - cf_ip_connect_create *cf_create; -}; - -static -#ifndef UNITTESTS -const -#endif -struct transport_provider transport_providers[] = { - { TRNSPRT_TCP, Curl_cf_tcp_create }, -#ifdef USE_HTTP3 - { TRNSPRT_QUIC, Curl_cf_quic_create }, -#endif -#ifndef CURL_DISABLE_TFTP - { TRNSPRT_UDP, Curl_cf_udp_create }, -#endif -#ifdef USE_UNIX_SOCKETS - { TRNSPRT_UNIX, Curl_cf_unix_create }, -#endif -}; - -static cf_ip_connect_create *get_cf_create(int transport) -{ - size_t i; - for(i = 0; i < CURL_ARRAYSIZE(transport_providers); ++i) { - if(transport == transport_providers[i].transport) - return transport_providers[i].cf_create; - } - return NULL; -} - -static CURLcode cf_he_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data, - int transport) -{ - cf_ip_connect_create *cf_create; - struct Curl_cfilter *cf; - CURLcode result; - - /* Need to be first */ - DEBUGASSERT(cf_at); - cf_create = get_cf_create(transport); - if(!cf_create) { - CURL_TRC_CF(data, cf_at, "unsupported transport type %d", transport); - return CURLE_UNSUPPORTED_PROTOCOL; - } - result = cf_happy_eyeballs_create(&cf, data, cf_at->conn, - cf_create, transport); - if(result) - return result; - - Curl_conn_cf_insert_after(cf_at, cf); - return CURLE_OK; -} - typedef enum { CF_SETUP_INIT, CF_SETUP_CNNCT_EYEBALLS, @@ -1283,7 +390,7 @@ static CURLcode cf_setup_connect(struct Curl_cfilter *cf, } if(ctx->state < CF_SETUP_CNNCT_EYEBALLS) { - result = cf_he_insert_after(cf, data, ctx->transport); + result = cf_ip_happy_insert_after(cf, data, ctx->transport); if(result) return result; ctx->state = CF_SETUP_CNNCT_EYEBALLS; @@ -1312,7 +419,7 @@ static CURLcode cf_setup_connect(struct Curl_cfilter *cf, } #endif /* USE_SSL */ -#if !defined(CURL_DISABLE_HTTP) +#ifndef CURL_DISABLE_HTTP if(cf->conn->bits.tunnel_proxy) { result = Curl_cf_http_proxy_insert_after(cf, data); if(result) @@ -1326,7 +433,7 @@ static CURLcode cf_setup_connect(struct Curl_cfilter *cf, #endif /* !CURL_DISABLE_PROXY */ if(ctx->state < CF_SETUP_CNNCT_HAPROXY) { -#if !defined(CURL_DISABLE_PROXY) +#ifndef CURL_DISABLE_PROXY if(data->set.haproxyprotocol) { if(Curl_conn_is_ssl(cf->conn, cf->sockindex)) { failf(data, "haproxy protocol not support with SSL " @@ -1398,7 +505,6 @@ struct Curl_cftype Curl_cft_setup = { cf_setup_connect, cf_setup_close, Curl_cf_def_shutdown, - Curl_cf_def_get_host, Curl_cf_def_adjust_pollset, Curl_cf_def_data_pending, Curl_cf_def_send, @@ -1459,21 +565,6 @@ static CURLcode cf_setup_add(struct Curl_easy *data, return result; } -#ifdef UNITTESTS -/* used by unit2600.c */ -void Curl_debug_set_transport_provider(int transport, - cf_ip_connect_create *cf_create) -{ - size_t i; - for(i = 0; i < CURL_ARRAYSIZE(transport_providers); ++i) { - if(transport == transport_providers[i].transport) { - transport_providers[i].cf_create = cf_create; - return; - } - } -} -#endif /* UNITTESTS */ - CURLcode Curl_cf_setup_insert_after(struct Curl_cfilter *cf_at, struct Curl_easy *data, int transport, @@ -1506,7 +597,7 @@ CURLcode Curl_conn_setup(struct Curl_easy *data, Curl_resolv_unlink(data, &data->state.dns[sockindex]); data->state.dns[sockindex] = dns; -#if !defined(CURL_DISABLE_HTTP) +#ifndef CURL_DISABLE_HTTP if(!conn->cfilter[sockindex] && conn->handler->protocol == CURLPROTO_HTTPS) { DEBUGASSERT(ssl_mode != CURL_CF_SSL_DISABLE); @@ -1514,11 +605,12 @@ CURLcode Curl_conn_setup(struct Curl_easy *data, if(result) goto out; } -#endif /* !defined(CURL_DISABLE_HTTP) */ +#endif /* !CURL_DISABLE_HTTP */ /* Still no cfilter set, apply default. */ if(!conn->cfilter[sockindex]) { - result = cf_setup_add(data, conn, sockindex, conn->transport, ssl_mode); + result = cf_setup_add(data, conn, sockindex, + conn->transport_wanted, ssl_mode); if(result) goto out; } diff --git a/vendor/curl/lib/connect.h b/vendor/curl/lib/connect.h index 120338eb99f..6a2487ff538 100644 --- a/vendor/curl/lib/connect.h +++ b/vendor/curl/lib/connect.h @@ -107,23 +107,6 @@ void Curl_conncontrol(struct connectdata *conn, #define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP) #endif -/** - * Create a cfilter for making an "ip" connection to the - * given address, using parameters from `conn`. The "ip" connection - * can be a TCP socket, a UDP socket or even a QUIC connection. - * - * It MUST use only the supplied `ai` for its connection attempt. - * - * Such a filter may be used in "happy eyeball" scenarios, and its - * `connect` implementation needs to support non-blocking. Once connected, - * it MAY be installed in the connection filter chain to serve transfers. - */ -typedef CURLcode cf_ip_connect_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn, - const struct Curl_addrinfo *ai, - int transport); - CURLcode Curl_cf_setup_insert_after(struct Curl_cfilter *cf_at, struct Curl_easy *data, int transport, @@ -140,12 +123,6 @@ CURLcode Curl_conn_setup(struct Curl_easy *data, struct Curl_dns_entry *dns, int ssl_mode); -extern struct Curl_cftype Curl_cft_happy_eyeballs; extern struct Curl_cftype Curl_cft_setup; -#ifdef UNITTESTS -void Curl_debug_set_transport_provider(int transport, - cf_ip_connect_create *cf_create); -#endif - #endif /* HEADER_CURL_CONNECT_H */ diff --git a/vendor/curl/lib/content_encoding.c b/vendor/curl/lib/content_encoding.c index f2e77eede18..3a0549c4b1a 100644 --- a/vendor/curl/lib/content_encoding.c +++ b/vendor/curl/lib/content_encoding.c @@ -52,7 +52,6 @@ #include "http.h" #include "content_encoding.h" #include "strdup.h" -#include "strcase.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -97,7 +96,7 @@ struct zlib_writer { static voidpf zalloc_cb(voidpf opaque, unsigned int items, unsigned int size) { - (void) opaque; + (void)opaque; /* not a typo, keep it calloc() */ return (voidpf) calloc(items, size); } @@ -105,7 +104,7 @@ zalloc_cb(voidpf opaque, unsigned int items, unsigned int size) static void zfree_cb(voidpf opaque, voidpf ptr) { - (void) opaque; + (void)opaque; free(ptr); } @@ -343,7 +342,7 @@ static CURLcode gzip_do_write(struct Curl_easy *data, } static void gzip_do_close(struct Curl_easy *data, - struct Curl_cwriter *writer) + struct Curl_cwriter *writer) { struct zlib_writer *zp = (struct zlib_writer *) writer; z_stream *z = &zp->z; /* zlib state structure */ @@ -412,7 +411,7 @@ static CURLcode brotli_do_init(struct Curl_easy *data, struct Curl_cwriter *writer) { struct brotli_writer *bp = (struct brotli_writer *) writer; - (void) data; + (void)data; bp->br = BrotliDecoderCreateInstance(NULL, NULL, NULL); return bp->br ? CURLE_OK : CURLE_OUT_OF_MEMORY; @@ -464,10 +463,10 @@ static CURLcode brotli_do_write(struct Curl_easy *data, } static void brotli_do_close(struct Curl_easy *data, - struct Curl_cwriter *writer) + struct Curl_cwriter *writer) { struct brotli_writer *bp = (struct brotli_writer *) writer; - (void) data; + (void)data; if(bp->br) { BrotliDecoderDestroyInstance(bp->br); @@ -567,7 +566,7 @@ static CURLcode zstd_do_write(struct Curl_easy *data, } static void zstd_do_close(struct Curl_easy *data, - struct Curl_cwriter *writer) + struct Curl_cwriter *writer) { struct zstd_writer *zp = (struct zstd_writer *) writer; (void)data; @@ -636,7 +635,7 @@ void Curl_all_content_encodings(char *buf, size_t blen) for(cep = general_unencoders; *cep; cep++) { ce = *cep; - if(!strcasecompare(ce->name, CONTENT_ENCODING_DEFAULT)) + if(!curl_strequal(ce->name, CONTENT_ENCODING_DEFAULT)) len += strlen(ce->name) + 2; } @@ -648,7 +647,7 @@ void Curl_all_content_encodings(char *buf, size_t blen) char *p = buf; for(cep = general_unencoders; *cep; cep++) { ce = *cep; - if(!strcasecompare(ce->name, CONTENT_ENCODING_DEFAULT)) { + if(!curl_strequal(ce->name, CONTENT_ENCODING_DEFAULT)) { strcpy(p, ce->name); p += strlen(p); *p++ = ','; @@ -672,9 +671,9 @@ static CURLcode error_do_write(struct Curl_easy *data, struct Curl_cwriter *writer, int type, const char *buf, size_t nbytes) { - (void) writer; - (void) buf; - (void) nbytes; + (void)writer; + (void)buf; + (void)nbytes; if(!(type & CLIENTWRITE_BODY) || !nbytes) return Curl_cwriter_write(data, writer->next, type, buf, nbytes); @@ -688,10 +687,10 @@ static CURLcode error_do_write(struct Curl_easy *data, } static void error_do_close(struct Curl_easy *data, - struct Curl_cwriter *writer) + struct Curl_cwriter *writer) { - (void) data; - (void) writer; + (void)data; + (void)writer; } static const struct Curl_cwtype error_writer = { @@ -713,8 +712,8 @@ static const struct Curl_cwtype *find_unencode_writer(const char *name, if(phase == CURL_CW_TRANSFER_DECODE) { for(cep = transfer_unencoders; *cep; cep++) { const struct Curl_cwtype *ce = *cep; - if((strncasecompare(name, ce->name, len) && !ce->name[len]) || - (ce->alias && strncasecompare(name, ce->alias, len) + if((curl_strnequal(name, ce->name, len) && !ce->name[len]) || + (ce->alias && curl_strnequal(name, ce->alias, len) && !ce->alias[len])) return ce; } @@ -722,8 +721,8 @@ static const struct Curl_cwtype *find_unencode_writer(const char *name, /* look among the general decoders */ for(cep = general_unencoders; *cep; cep++) { const struct Curl_cwtype *ce = *cep; - if((strncasecompare(name, ce->name, len) && !ce->name[len]) || - (ce->alias && strncasecompare(name, ce->alias, len) && !ce->alias[len])) + if((curl_strnequal(name, ce->name, len) && !ce->name[len]) || + (ce->alias && curl_strnequal(name, ce->alias, len) && !ce->alias[len])) return ce; } return NULL; @@ -761,12 +760,12 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, CURL_TRC_WRITE(data, "looking for %s decoder: %.*s", is_transfer ? "transfer" : "content", (int)namelen, name); is_chunked = (is_transfer && (namelen == 7) && - strncasecompare(name, "chunked", 7)); + curl_strnequal(name, "chunked", 7)); /* if we skip the decoding in this phase, do not look further. * Exception is "chunked" transfer-encoding which always must happen */ if((is_transfer && !data->set.http_transfer_encoding && !is_chunked) || (!is_transfer && data->set.http_ce_skip)) { - bool is_identity = strncasecompare(name, "identity", 8); + bool is_identity = curl_strnequal(name, "identity", 8); /* not requested, ignore */ CURL_TRC_WRITE(data, "decoder not requested, ignored: %.*s", (int)namelen, name); @@ -844,9 +843,9 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, const char *enclist, int is_transfer) { - (void) data; - (void) enclist; - (void) is_transfer; + (void)data; + (void)enclist; + (void)is_transfer; return CURLE_NOT_BUILT_IN; } diff --git a/vendor/curl/lib/cookie.c b/vendor/curl/lib/cookie.c index 1a8426ca27f..b72dd99bce9 100644 --- a/vendor/curl/lib/cookie.c +++ b/vendor/curl/lib/cookie.c @@ -135,9 +135,9 @@ static bool cookie_tailmatch(const char *cookie_domain, if(hostname_len < cookie_domain_len) return FALSE; - if(!strncasecompare(cookie_domain, - hostname + hostname_len-cookie_domain_len, - cookie_domain_len)) + if(!curl_strnequal(cookie_domain, + hostname + hostname_len-cookie_domain_len, + cookie_domain_len)) return FALSE; /* @@ -167,13 +167,13 @@ static bool pathmatch(const char *cookie_path, const char *uri_path) /* cookie_path must not have last '/' separator. ex: /sample */ cookie_path_len = strlen(cookie_path); - if(1 == cookie_path_len) { + if(cookie_path_len == 1) { /* cookie_path must be '/' */ return TRUE; } /* #-fragments are already cut off! */ - if(0 == strlen(uri_path) || uri_path[0] != '/') + if(strlen(uri_path) == 0 || uri_path[0] != '/') uri_path = "/"; /* @@ -296,9 +296,9 @@ static char *sanitize_cookie_path(const char *cookie_path) /* Let cookie-path be the default-path. */ return strdup("/"); - /* remove trailing slash */ + /* remove trailing slash when path is non-empty */ /* convert /hoge/ to /hoge */ - if(len && cookie_path[len - 1] == '/') + if(len > 1 && cookie_path[len - 1] == '/') len--; return Curl_memdup0(cookie_path, len); @@ -409,7 +409,7 @@ static void remove_expired(struct CookieInfo *ci) /* Make sure domain contains a dot or is localhost. */ static bool bad_domain(const char *domain, size_t len) { - if((len == 9) && strncasecompare(domain, "localhost", 9)) + if((len == 9) && curl_strnequal(domain, "localhost", 9)) return FALSE; else { /* there must be a dot present, but that dot must not be a trailing dot */ @@ -815,7 +815,7 @@ parse_netscape(struct Cookie *co, * domain can access the variable. Set TRUE when the cookie says * .example.com and to false when the domain is complete www.example.com */ - co->tailmatch = !!strncasecompare(ptr, "TRUE", len); + co->tailmatch = !!curl_strnequal(ptr, "TRUE", len); break; case 2: /* The file format allows the path field to remain not filled in */ @@ -842,7 +842,7 @@ parse_netscape(struct Cookie *co, FALLTHROUGH(); case 3: co->secure = FALSE; - if(strncasecompare(ptr, "TRUE", len)) { + if(curl_strnequal(ptr, "TRUE", len)) { if(secure || ci->running) co->secure = TRUE; else @@ -859,9 +859,9 @@ parse_netscape(struct Cookie *co, return CERR_OUT_OF_MEMORY; else { /* For Netscape file format cookies we check prefix on the name */ - if(strncasecompare("__Secure-", co->name, 9)) + if(curl_strnequal("__Secure-", co->name, 9)) co->prefix_secure = TRUE; - else if(strncasecompare("__Host-", co->name, 7)) + else if(curl_strnequal("__Host-", co->name, 7)) co->prefix_host = TRUE; } break; @@ -872,7 +872,7 @@ parse_netscape(struct Cookie *co, break; } } - if(6 == fields) { + if(fields == 6) { /* we got a cookie with blank contents, fix it */ co->value = strdup(""); if(!co->value) @@ -881,7 +881,7 @@ parse_netscape(struct Cookie *co, fields++; } - if(7 != fields) + if(fields != 7) /* we did not find the sufficient number of fields */ return CERR_FIELDS; @@ -917,7 +917,7 @@ is_public_suffix(struct Curl_easy *data, Curl_psl_release(data); } else - infof(data, "libpsl problem, rejecting cookie for satety"); + infof(data, "libpsl problem, rejecting cookie for safety"); } if(!acceptable) { @@ -954,7 +954,7 @@ replace_existing(struct Curl_easy *data, bool matching_domains = FALSE; if(clist->domain && co->domain) { - if(strcasecompare(clist->domain, co->domain)) + if(curl_strequal(clist->domain, co->domain)) /* The domains are identical */ matching_domains = TRUE; } @@ -965,7 +965,7 @@ replace_existing(struct Curl_easy *data, clist->spath && co->spath && /* both have paths */ clist->secure && !co->secure && !secure) { size_t cllen; - const char *sep; + const char *sep = NULL; /* * A non-secure cookie may not overlay an existing secure cookie. @@ -974,14 +974,15 @@ replace_existing(struct Curl_easy *data, * "/loginhelper" is ok. */ - sep = strchr(clist->spath + 1, '/'); - + DEBUGASSERT(clist->spath[0]); + if(clist->spath[0]) + sep = strchr(clist->spath + 1, '/'); if(sep) cllen = sep - clist->spath; else cllen = strlen(clist->spath); - if(strncasecompare(clist->spath, co->spath, cllen)) { + if(curl_strnequal(clist->spath, co->spath, cllen)) { infof(data, "cookie '%s' for domain '%s' dropped, would " "overlay an existing cookie", co->name, co->domain); return CERR_BAD_SECURE; @@ -993,7 +994,7 @@ replace_existing(struct Curl_easy *data, /* the names are identical */ if(clist->domain && co->domain) { - if(strcasecompare(clist->domain, co->domain) && + if(curl_strequal(clist->domain, co->domain) && (clist->tailmatch == co->tailmatch)) /* The domains are identical */ replace_old = TRUE; @@ -1005,7 +1006,7 @@ replace_existing(struct Curl_easy *data, /* the domains were identical */ if(clist->spath && co->spath && - !strcasecompare(clist->spath, co->spath)) + !curl_strequal(clist->spath, co->spath)) replace_old = FALSE; else if(!clist->spath != !co->spath) replace_old = FALSE; @@ -1337,7 +1338,7 @@ int Curl_cookie_getlist(struct Curl_easy *data, if(!co->domain || (co->tailmatch && !is_ip && cookie_tailmatch(co->domain, strlen(co->domain), host)) || - ((!co->tailmatch || is_ip) && strcasecompare(host, co->domain)) ) { + ((!co->tailmatch || is_ip) && curl_strequal(host, co->domain)) ) { /* * the right part of the host matches the domain stuff in the * cookie data diff --git a/vendor/curl/lib/cshutdn.c b/vendor/curl/lib/cshutdn.c index f05b87d277a..1c144c6025f 100644 --- a/vendor/curl/lib/cshutdn.c +++ b/vendor/curl/lib/cshutdn.c @@ -40,7 +40,6 @@ #include "sigpipe.h" #include "connect.h" #include "select.h" -#include "strcase.h" #include "curlx/strparse.h" /* The last 3 #include files should be in this order */ @@ -54,12 +53,6 @@ static void cshutdn_run_conn_handler(struct Curl_easy *data, { if(!conn->bits.shutdown_handler) { - /* Cleanup NTLM connection-related data */ - Curl_http_auth_cleanup_ntlm(conn); - - /* Cleanup NEGOTIATE connection-related data */ - Curl_http_auth_cleanup_negotiate(conn); - if(conn->handler && conn->handler->disconnect) { /* Some disconnect handlers do a blocking wait on server responses. * FTP/IMAP/SMTP and SFTP are among them. When using the internal @@ -121,8 +114,8 @@ static void cshutdn_run_once(struct Curl_easy *data, } void Curl_cshutdn_run_once(struct Curl_easy *data, - struct connectdata *conn, - bool *done) + struct connectdata *conn, + bool *done) { DEBUGASSERT(!data->conn); Curl_attach_connection(data, conn); @@ -219,8 +212,8 @@ bool Curl_cshutdn_close_oldest(struct Curl_easy *data, #define NUM_POLLS_ON_STACK 10 static CURLcode cshutdn_wait(struct cshutdn *cshutdn, - struct Curl_easy *data, - int timeout_ms) + struct Curl_easy *data, + int timeout_ms) { struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK]; struct curl_pollfds cpfds; @@ -241,7 +234,7 @@ static CURLcode cshutdn_wait(struct cshutdn *cshutdn, static void cshutdn_perform(struct cshutdn *cshutdn, - struct Curl_easy *data) + struct Curl_easy *data) { struct Curl_llist_node *e = Curl_llist_head(&cshutdn->list); struct Curl_llist_node *enext; @@ -402,8 +395,8 @@ size_t Curl_cshutdn_dest_count(struct Curl_easy *data, static CURLMcode cshutdn_update_ev(struct cshutdn *cshutdn, - struct Curl_easy *data, - struct connectdata *conn) + struct Curl_easy *data, + struct connectdata *conn) { CURLMcode mresult; @@ -418,8 +411,8 @@ static CURLMcode cshutdn_update_ev(struct cshutdn *cshutdn, void Curl_cshutdn_add(struct cshutdn *cshutdn, - struct connectdata *conn, - size_t conns_in_pool) + struct connectdata *conn, + size_t conns_in_pool) { struct Curl_easy *data = cshutdn->multi->admin; size_t max_total = (cshutdn->multi->max_total_connections > 0) ? @@ -451,8 +444,8 @@ void Curl_cshutdn_add(struct cshutdn *cshutdn, static void cshutdn_multi_socket(struct cshutdn *cshutdn, - struct Curl_easy *data, - curl_socket_t s) + struct Curl_easy *data, + curl_socket_t s) { struct Curl_llist_node *e; struct connectdata *conn; @@ -493,19 +486,25 @@ void Curl_cshutdn_setfds(struct cshutdn *cshutdn, { if(Curl_llist_head(&cshutdn->list)) { struct Curl_llist_node *e; + struct easy_pollset ps; + Curl_pollset_init(&ps); for(e = Curl_llist_head(&cshutdn->list); e; e = Curl_node_next(e)) { - struct easy_pollset ps; unsigned int i; struct connectdata *conn = Curl_node_elem(e); - memset(&ps, 0, sizeof(ps)); + CURLcode result; + + Curl_pollset_reset(&ps); Curl_attach_connection(data, conn); - Curl_conn_adjust_pollset(data, conn, &ps); + result = Curl_conn_adjust_pollset(data, conn, &ps); Curl_detach_connection(data); - for(i = 0; i < ps.num; i++) { -#if defined(__DJGPP__) + if(result) + continue; + + for(i = 0; i < ps.n; i++) { +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif @@ -513,7 +512,7 @@ void Curl_cshutdn_setfds(struct cshutdn *cshutdn, FD_SET(ps.sockets[i], read_fd_set); if(ps.actions[i] & CURL_POLL_OUT) FD_SET(ps.sockets[i], write_fd_set); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif if((ps.actions[i] & (CURL_POLL_OUT | CURL_POLL_IN)) && @@ -521,6 +520,7 @@ void Curl_cshutdn_setfds(struct cshutdn *cshutdn, *maxfd = (int)ps.sockets[i]; } } + Curl_pollset_cleanup(&ps); } } @@ -535,17 +535,21 @@ unsigned int Curl_cshutdn_add_waitfds(struct cshutdn *cshutdn, struct Curl_llist_node *e; struct easy_pollset ps; struct connectdata *conn; + CURLcode result; + Curl_pollset_init(&ps); for(e = Curl_llist_head(&cshutdn->list); e; e = Curl_node_next(e)) { conn = Curl_node_elem(e); - memset(&ps, 0, sizeof(ps)); + Curl_pollset_reset(&ps); Curl_attach_connection(data, conn); - Curl_conn_adjust_pollset(data, conn, &ps); + result = Curl_conn_adjust_pollset(data, conn, &ps); Curl_detach_connection(data); - need += Curl_waitfds_add_ps(cwfds, &ps); + if(!result) + need += Curl_waitfds_add_ps(cwfds, &ps); } + Curl_pollset_cleanup(&ps); } return need; } @@ -561,20 +565,24 @@ CURLcode Curl_cshutdn_add_pollfds(struct cshutdn *cshutdn, struct easy_pollset ps; struct connectdata *conn; + Curl_pollset_init(&ps); for(e = Curl_llist_head(&cshutdn->list); e; e = Curl_node_next(e)) { conn = Curl_node_elem(e); - memset(&ps, 0, sizeof(ps)); + Curl_pollset_reset(&ps); Curl_attach_connection(data, conn); - Curl_conn_adjust_pollset(data, conn, &ps); + result = Curl_conn_adjust_pollset(data, conn, &ps); Curl_detach_connection(data); - result = Curl_pollfds_add_ps(cpfds, &ps); + if(!result) + result = Curl_pollfds_add_ps(cpfds, &ps); if(result) { + Curl_pollset_cleanup(&ps); Curl_pollfds_cleanup(cpfds); goto out; } } + Curl_pollset_cleanup(&ps); } out: return result; diff --git a/vendor/curl/lib/curl_addrinfo.c b/vendor/curl/lib/curl_addrinfo.c index b131c747b10..22212ac86f8 100644 --- a/vendor/curl/lib/curl_addrinfo.c +++ b/vendor/curl/lib/curl_addrinfo.c @@ -68,7 +68,7 @@ */ #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \ - defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__) + defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__) /* workaround icc 9.1 optimizer issue */ # define vqualifier volatile #else @@ -398,11 +398,7 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port) addr = (void *)ai->ai_addr; /* storage area for this info */ memcpy(&addr->sin_addr, inaddr, sizeof(struct in_addr)); -#ifdef __MINGW32__ - addr->sin_family = (short)af; -#else addr->sin_family = (CURL_SA_FAMILY_T)af; -#endif addr->sin_port = htons((unsigned short)port); break; @@ -411,11 +407,7 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port) addr6 = (void *)ai->ai_addr; /* storage area for this info */ memcpy(&addr6->sin6_addr, inaddr, sizeof(struct in6_addr)); -#ifdef __MINGW32__ - addr6->sin6_family = (short)af; -#else addr6->sin6_family = (CURL_SA_FAMILY_T)af; -#endif addr6->sin6_port = htons((unsigned short)port); break; #endif @@ -521,7 +513,7 @@ curl_dbg_freeaddrinfo(struct addrinfo *freethis, freeaddrinfo(freethis); #endif } -#endif /* defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) */ +#endif /* CURLDEBUG && HAVE_FREEADDRINFO */ #if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) @@ -552,7 +544,7 @@ curl_dbg_getaddrinfo(const char *hostname, #else int res = getaddrinfo(hostname, service, hints, result); #endif - if(0 == res) + if(res == 0) /* success */ curl_dbg_log("ADDR %s:%d getaddrinfo() = %p\n", source, line, (void *)*result); @@ -561,7 +553,7 @@ curl_dbg_getaddrinfo(const char *hostname, source, line); return res; } -#endif /* defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) */ +#endif /* CURLDEBUG && HAVE_GETADDRINFO */ #if defined(HAVE_GETADDRINFO) && defined(USE_RESOLVE_ON_IPS) /* diff --git a/vendor/curl/lib/curl_des.c b/vendor/curl/lib/curl_des.c index 15836f58b97..a202dd3fe4a 100644 --- a/vendor/curl/lib/curl_des.c +++ b/vendor/curl/lib/curl_des.c @@ -26,7 +26,6 @@ #if defined(USE_CURL_NTLM_CORE) && \ (defined(USE_GNUTLS) || \ - defined(USE_SECTRANSP) || \ defined(USE_OS400CRYPTO) || \ defined(USE_WIN32_CRYPTO)) diff --git a/vendor/curl/lib/curl_des.h b/vendor/curl/lib/curl_des.h index 2dd498da245..c50aaf45b17 100644 --- a/vendor/curl/lib/curl_des.h +++ b/vendor/curl/lib/curl_des.h @@ -28,7 +28,6 @@ #if defined(USE_CURL_NTLM_CORE) && \ (defined(USE_GNUTLS) || \ - defined(USE_SECTRANSP) || \ defined(USE_OS400CRYPTO) || \ defined(USE_WIN32_CRYPTO)) diff --git a/vendor/curl/lib/curl_fnmatch.c b/vendor/curl/lib/curl_fnmatch.c index 21eca4ceda5..66b9739f3c0 100644 --- a/vendor/curl/lib/curl_fnmatch.c +++ b/vendor/curl/lib/curl_fnmatch.c @@ -74,14 +74,13 @@ typedef enum { static int parsekeyword(const unsigned char **pattern, unsigned char *charset) { parsekey_state state = CURLFNM_PKW_INIT; -#define KEYLEN 10 - char keyword[KEYLEN] = { 0 }; - int i; + char keyword[10] = { 0 }; + size_t i; const unsigned char *p = *pattern; bool found = FALSE; for(i = 0; !found; i++) { char c = (char)*p++; - if(i >= KEYLEN) + if(i >= sizeof(keyword)) return SETCHARSET_FAIL; switch(state) { case CURLFNM_PKW_INIT: diff --git a/vendor/curl/lib/curl_get_line.c b/vendor/curl/lib/curl_get_line.c index 2bb57492b30..4b1c6c3e097 100644 --- a/vendor/curl/lib/curl_get_line.c +++ b/vendor/curl/lib/curl_get_line.c @@ -32,6 +32,15 @@ /* The last #include file should be: */ #include "memdebug.h" +static int appendnl(struct dynbuf *buf) +{ + CURLcode result = curlx_dyn_addn(buf, "\n", 1); + if(result) + /* too long line or out of memory */ + return 0; /* error */ + return 1; /* all good */ +} + /* * Curl_get_line() makes sure to only return complete whole lines that end * newlines. @@ -43,9 +52,10 @@ int Curl_get_line(struct dynbuf *buf, FILE *input) curlx_dyn_reset(buf); while(1) { char *b = fgets(buffer, sizeof(buffer), input); + size_t rlen; if(b) { - size_t rlen = strlen(b); + rlen = strlen(b); if(!rlen) break; @@ -59,19 +69,24 @@ int Curl_get_line(struct dynbuf *buf, FILE *input) /* end of the line */ return 1; /* all good */ - else if(feof(input)) { + else if(feof(input)) /* append a newline */ - result = curlx_dyn_addn(buf, "\n", 1); - if(result) - /* too long line or out of memory */ - return 0; /* error */ + return appendnl(buf); + } + else { + rlen = curlx_dyn_len(buf); + if(rlen) { + b = curlx_dyn_ptr(buf); + + if(b[rlen-1] != '\n') + /* append a newline */ + return appendnl(buf); + return 1; /* all good */ } + else + break; } - else if(curlx_dyn_len(buf)) - return 1; /* all good */ - else - break; } return 0; } diff --git a/vendor/curl/lib/curl_gethostname.c b/vendor/curl/lib/curl_gethostname.c index fb418b400d8..c3fa864effc 100644 --- a/vendor/curl/lib/curl_gethostname.c +++ b/vendor/curl/lib/curl_gethostname.c @@ -46,8 +46,8 @@ int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen) #ifndef HAVE_GETHOSTNAME /* Allow compilation and return failure when unavailable */ - (void) name; - (void) namelen; + (void)name; + (void)namelen; return -1; #else diff --git a/vendor/curl/lib/curl_gssapi.c b/vendor/curl/lib/curl_gssapi.c index f83701ad645..92b867f7753 100644 --- a/vendor/curl/lib/curl_gssapi.c +++ b/vendor/curl/lib/curl_gssapi.c @@ -34,7 +34,7 @@ #include "curl_memory.h" #include "memdebug.h" -#if defined(__GNUC__) +#ifdef __GNUC__ #define CURL_ALIGN8 __attribute__((aligned(8))) #else #define CURL_ALIGN8 @@ -52,17 +52,260 @@ gss_OID_desc Curl_krb5_mech_oid CURL_ALIGN8 = { 9, CURL_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") }; -OM_uint32 Curl_gss_init_sec_context( - struct Curl_easy *data, - OM_uint32 *minor_status, - gss_ctx_id_t *context, - gss_name_t target_name, - gss_OID mech_type, - gss_channel_bindings_t input_chan_bindings, - gss_buffer_t input_token, - gss_buffer_t output_token, - const bool mutual_auth, - OM_uint32 *ret_flags) +#ifdef DEBUGBUILD +enum min_err_code { + STUB_GSS_OK = 0, + STUB_GSS_NO_MEMORY, + STUB_GSS_INVALID_ARGS, + STUB_GSS_INVALID_CREDS, + STUB_GSS_INVALID_CTX, + STUB_GSS_SERVER_ERR, + STUB_GSS_NO_MECH, + STUB_GSS_LAST +}; + +/* libcurl is also passing this struct to these functions, which are not yet + * stubbed: + * gss_inquire_context() + * gss_unwrap() + * gss_wrap() + */ +struct stub_gss_ctx_id_t_desc { + enum { STUB_GSS_NONE, STUB_GSS_KRB5, STUB_GSS_NTLM1, STUB_GSS_NTLM3 } sent; + int have_krb5; + int have_ntlm; + OM_uint32 flags; + char creds[250]; +}; + +static OM_uint32 +stub_gss_init_sec_context(OM_uint32 *min, + gss_cred_id_t initiator_cred_handle, + struct stub_gss_ctx_id_t_desc **context, + gss_name_t target_name, + const gss_OID mech_type, + OM_uint32 req_flags, + OM_uint32 time_req, + const gss_channel_bindings_t input_chan_bindings, + gss_buffer_desc *input_token, + gss_OID *actual_mech_type, + gss_buffer_desc *output_token, + OM_uint32 *ret_flags, + OM_uint32 *time_rec) +{ + struct stub_gss_ctx_id_t_desc *ctx = NULL; + + /* The token will be encoded in base64 */ + size_t length = sizeof(ctx->creds) * 3 / 4; + size_t used = 0; + char *token = NULL; + const char *creds = NULL; + + (void)initiator_cred_handle; + (void)mech_type; + (void)time_req; + (void)input_chan_bindings; + (void)actual_mech_type; + + if(!min) + return GSS_S_FAILURE; + + *min = 0; + + if(!context || !target_name || !output_token) { + *min = STUB_GSS_INVALID_ARGS; + return GSS_S_FAILURE; + } + + creds = getenv("CURL_STUB_GSS_CREDS"); + if(!creds || strlen(creds) >= sizeof(ctx->creds)) { + *min = STUB_GSS_INVALID_CREDS; + return GSS_S_FAILURE; + } + + ctx = *context; + if(ctx && strcmp(ctx->creds, creds)) { + *min = STUB_GSS_INVALID_CREDS; + return GSS_S_FAILURE; + } + + output_token->length = 0; + output_token->value = NULL; + + if(input_token && input_token->length) { + if(!ctx) { + *min = STUB_GSS_INVALID_CTX; + return GSS_S_FAILURE; + } + + /* Server response, either D (RA==) or C (Qw==) */ + if(((char *) input_token->value)[0] == 'D') { + /* Done */ + switch(ctx->sent) { + case STUB_GSS_KRB5: + case STUB_GSS_NTLM3: + if(ret_flags) + *ret_flags = ctx->flags; + if(time_rec) + *time_rec = GSS_C_INDEFINITE; + return GSS_S_COMPLETE; + default: + *min = STUB_GSS_SERVER_ERR; + return GSS_S_FAILURE; + } + } + + if(((char *) input_token->value)[0] != 'C') { + /* We only support Done or Continue */ + *min = STUB_GSS_SERVER_ERR; + return GSS_S_FAILURE; + } + + /* Continue */ + switch(ctx->sent) { + case STUB_GSS_KRB5: + /* We sent KRB5 and it failed, let's try NTLM */ + if(ctx->have_ntlm) { + ctx->sent = STUB_GSS_NTLM1; + break; + } + else { + *min = STUB_GSS_SERVER_ERR; + return GSS_S_FAILURE; + } + case STUB_GSS_NTLM1: + ctx->sent = STUB_GSS_NTLM3; + break; + default: + *min = STUB_GSS_SERVER_ERR; + return GSS_S_FAILURE; + } + } + else { + if(ctx) { + *min = STUB_GSS_INVALID_CTX; + return GSS_S_FAILURE; + } + + ctx = calloc(1, sizeof(*ctx)); + if(!ctx) { + *min = STUB_GSS_NO_MEMORY; + return GSS_S_FAILURE; + } + + if(strstr(creds, "KRB5")) + ctx->have_krb5 = 1; + + if(strstr(creds, "NTLM")) + ctx->have_ntlm = 1; + + if(ctx->have_krb5) + ctx->sent = STUB_GSS_KRB5; + else if(ctx->have_ntlm) + ctx->sent = STUB_GSS_NTLM1; + else { + free(ctx); + *min = STUB_GSS_NO_MECH; + return GSS_S_FAILURE; + } + + strcpy(ctx->creds, creds); + ctx->flags = req_flags; + } + + /* To avoid memdebug macro replacement, wrap the name in parentheses to call + the original version. It is freed via the GSS API gss_release_buffer(). */ + token = (malloc)(length); + if(!token) { + free(ctx); + *min = STUB_GSS_NO_MEMORY; + return GSS_S_FAILURE; + } + + { + gss_buffer_desc target_desc; + gss_OID name_type = GSS_C_NO_OID; + OM_uint32 minor_status; + OM_uint32 major_status; + major_status = gss_display_name(&minor_status, target_name, + &target_desc, &name_type); + if(GSS_ERROR(major_status)) { + (free)(token); + free(ctx); + *min = STUB_GSS_NO_MEMORY; + return GSS_S_FAILURE; + } + + if(strlen(creds) + target_desc.length + 5 >= sizeof(ctx->creds)) { + (free)(token); + free(ctx); + *min = STUB_GSS_NO_MEMORY; + return GSS_S_FAILURE; + } + + /* Token format: creds:target:type:padding */ + used = msnprintf(token, length, "%s:%.*s:%d:", creds, + (int)target_desc.length, (const char *)target_desc.value, + ctx->sent); + + gss_release_buffer(&minor_status, &target_desc); + } + + if(used >= length) { + (free)(token); + free(ctx); + *min = STUB_GSS_NO_MEMORY; + return GSS_S_FAILURE; + } + + /* Overwrite null-terminator */ + memset(token + used, 'A', length - used); + + *context = ctx; + + output_token->value = token; + output_token->length = length; + + return GSS_S_CONTINUE_NEEDED; +} + +static OM_uint32 +stub_gss_delete_sec_context(OM_uint32 *min, + struct stub_gss_ctx_id_t_desc **context, + gss_buffer_t output_token) +{ + (void)output_token; + + if(!min) + return GSS_S_FAILURE; + + if(!context) { + *min = STUB_GSS_INVALID_CTX; + return GSS_S_FAILURE; + } + if(!*context) { + *min = STUB_GSS_INVALID_CTX; + return GSS_S_FAILURE; + } + + free(*context); + *context = NULL; + *min = 0; + + return GSS_S_COMPLETE; +} +#endif /* DEBUGBUILD */ + +OM_uint32 Curl_gss_init_sec_context(struct Curl_easy *data, + OM_uint32 *minor_status, + gss_ctx_id_t *context, + gss_name_t target_name, + gss_OID mech_type, + gss_channel_bindings_t input_chan_bindings, + gss_buffer_t input_token, + gss_buffer_t output_token, + const bool mutual_auth, + OM_uint32 *ret_flags) { OM_uint32 req_flags = GSS_C_REPLAY_FLAG; @@ -74,13 +317,30 @@ OM_uint32 Curl_gss_init_sec_context( req_flags |= GSS_C_DELEG_POLICY_FLAG; #else infof(data, "WARNING: support for CURLGSSAPI_DELEGATION_POLICY_FLAG not " - "compiled in"); + "compiled in"); #endif } if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_FLAG) req_flags |= GSS_C_DELEG_FLAG; +#ifdef DEBUGBUILD + if(getenv("CURL_STUB_GSS_CREDS")) + return stub_gss_init_sec_context(minor_status, + GSS_C_NO_CREDENTIAL, /* cred_handle */ + (struct stub_gss_ctx_id_t_desc **)context, + target_name, + mech_type, + req_flags, + 0, /* time_req */ + input_chan_bindings, + input_token, + NULL, /* actual_mech_type */ + output_token, + ret_flags, + NULL /* time_rec */); +#endif /* DEBUGBUILD */ + return gss_init_sec_context(minor_status, GSS_C_NO_CREDENTIAL, /* cred_handle */ context, @@ -96,6 +356,20 @@ OM_uint32 Curl_gss_init_sec_context( NULL /* time_rec */); } +OM_uint32 Curl_gss_delete_sec_context(OM_uint32 *min, + gss_ctx_id_t *context, + gss_buffer_t output_token) +{ +#ifdef DEBUGBUILD + if(getenv("CURL_STUB_GSS_CREDS")) + return stub_gss_delete_sec_context(min, + (struct stub_gss_ctx_id_t_desc **)context, + output_token); +#endif /* DEBUGBUILD */ + + return gss_delete_sec_context(min, context, output_token); +} + #define GSS_LOG_BUFFER_LEN 1024 static size_t display_gss_error(OM_uint32 status, int type, char *buf, size_t len) { diff --git a/vendor/curl/lib/curl_gssapi.h b/vendor/curl/lib/curl_gssapi.h index 7b9a534ea20..2659f23460d 100644 --- a/vendor/curl/lib/curl_gssapi.h +++ b/vendor/curl/lib/curl_gssapi.h @@ -32,17 +32,20 @@ extern gss_OID_desc Curl_spnego_mech_oid; extern gss_OID_desc Curl_krb5_mech_oid; /* Common method for using GSS-API */ -OM_uint32 Curl_gss_init_sec_context( - struct Curl_easy *data, - OM_uint32 *minor_status, - gss_ctx_id_t *context, - gss_name_t target_name, - gss_OID mech_type, - gss_channel_bindings_t input_chan_bindings, - gss_buffer_t input_token, - gss_buffer_t output_token, - const bool mutual_auth, - OM_uint32 *ret_flags); +OM_uint32 Curl_gss_init_sec_context(struct Curl_easy *data, + OM_uint32 *minor_status, + gss_ctx_id_t *context, + gss_name_t target_name, + gss_OID mech_type, + gss_channel_bindings_t input_chan_bindings, + gss_buffer_t input_token, + gss_buffer_t output_token, + const bool mutual_auth, + OM_uint32 *ret_flags); + +OM_uint32 Curl_gss_delete_sec_context(OM_uint32 *min, + gss_ctx_id_t *context_handle, + gss_buffer_t output_token); /* Helper to log a GSS-API error status */ void Curl_gss_log_error(struct Curl_easy *data, const char *prefix, diff --git a/vendor/curl/lib/curl_hmac.h b/vendor/curl/lib/curl_hmac.h index f54edeb49ed..9675c6c5425 100644 --- a/vendor/curl/lib/curl_hmac.h +++ b/vendor/curl/lib/curl_hmac.h @@ -26,7 +26,7 @@ #if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) || \ !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) || \ - defined(USE_SSL) + defined(USE_LIBSSH2) || defined(USE_SSL) #include diff --git a/vendor/curl/lib/curl_md4.h b/vendor/curl/lib/curl_md4.h index 4706e49578b..f103d38b41b 100644 --- a/vendor/curl/lib/curl_md4.h +++ b/vendor/curl/lib/curl_md4.h @@ -27,13 +27,13 @@ #include "curl_setup.h" #include -#if defined(USE_CURL_NTLM_CORE) +#ifdef USE_CURL_NTLM_CORE #define MD4_DIGEST_LENGTH 16 CURLcode Curl_md4it(unsigned char *output, const unsigned char *input, const size_t len); -#endif /* defined(USE_CURL_NTLM_CORE) */ +#endif /* USE_CURL_NTLM_CORE */ #endif /* HEADER_CURL_MD4_H */ diff --git a/vendor/curl/lib/curl_md5.h b/vendor/curl/lib/curl_md5.h index ec27503b144..16272c75910 100644 --- a/vendor/curl/lib/curl_md5.h +++ b/vendor/curl/lib/curl_md5.h @@ -24,8 +24,8 @@ * ***************************************************************************/ -#if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) \ - || !defined(CURL_DISABLE_DIGEST_AUTH) +#if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) || \ + !defined(CURL_DISABLE_DIGEST_AUTH) #include "curl_hmac.h" diff --git a/vendor/curl/lib/curl_mem_undef.h b/vendor/curl/lib/curl_mem_undef.h new file mode 100644 index 00000000000..2b0bef111d1 --- /dev/null +++ b/vendor/curl/lib/curl_mem_undef.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 + * + ***************************************************************************/ + +/* Unset redefined system symbols. */ + +#undef strdup +#undef malloc +#undef calloc +#undef realloc +#undef free +#undef send +#undef recv + +#ifdef _WIN32 +#undef _tcsdup +#endif + +#undef socket +#undef accept +#ifdef HAVE_ACCEPT4 +#undef accept4 +#endif +#ifdef HAVE_SOCKETPAIR +#undef socketpair +#endif + +#undef fopen +#ifdef CURL_FOPEN +#define fopen(fname, mode) CURL_FOPEN(fname, mode) +#endif +#undef fdopen +#undef fclose + +#undef HEADER_CURL_MEMORY_H +#undef HEADER_CURL_MEMDEBUG_H diff --git a/vendor/curl/lib/curl_memory.h b/vendor/curl/lib/curl_memory.h index bc3e944fea2..07ef111ce78 100644 --- a/vendor/curl/lib/curl_memory.h +++ b/vendor/curl/lib/curl_memory.h @@ -54,78 +54,6 @@ * */ -#ifdef HEADER_CURL_MEMDEBUG_H -/* cleanup after memdebug.h */ - -#ifdef MEMDEBUG_NODEFINES -#ifdef CURLDEBUG - -#undef strdup -#undef malloc -#undef calloc -#undef realloc -#undef free -#undef send -#undef recv - -#ifdef _WIN32 -# ifdef UNICODE -# undef wcsdup -# undef _wcsdup -# undef _tcsdup -# else -# undef _tcsdup -# endif -#endif - -#undef socket -#undef accept -#ifdef HAVE_SOCKETPAIR -#undef socketpair -#endif - -/* sclose is probably already defined, redefine it! */ -#undef sclose -#undef fopen -#undef fdopen -#undef fclose - -#endif /* MEMDEBUG_NODEFINES */ -#endif /* CURLDEBUG */ - -#undef HEADER_CURL_MEMDEBUG_H -#endif /* HEADER_CURL_MEMDEBUG_H */ - -/* -** Following section applies even when CURLDEBUG is not defined. -*/ - -#undef fake_sclose - -#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS /* only if not already done */ -/* - * The following memory function replacement typedef's are COPIED from - * curl/curl.h and MUST match the originals. We copy them to avoid having to - * include curl/curl.h here. We avoid that include since it includes stdio.h - * and other headers that may get messed up with defines done here. - */ -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 - -extern curl_malloc_callback Curl_cmalloc; -extern curl_free_callback Curl_cfree; -extern curl_realloc_callback Curl_crealloc; -extern curl_strdup_callback Curl_cstrdup; -extern curl_calloc_callback Curl_ccalloc; -#if defined(_WIN32) && defined(UNICODE) -extern curl_wcsdup_callback Curl_cwcsdup; -#endif - #ifndef CURLDEBUG /* @@ -149,18 +77,13 @@ extern curl_wcsdup_callback Curl_cwcsdup; #define free(ptr) Curl_cfree(ptr) #ifdef _WIN32 -# ifdef UNICODE -# undef wcsdup -# define wcsdup(ptr) Curl_cwcsdup(ptr) -# undef _wcsdup -# define _wcsdup(ptr) Curl_cwcsdup(ptr) -# undef _tcsdup -# define _tcsdup(ptr) Curl_cwcsdup(ptr) -# else -# undef _tcsdup -# define _tcsdup(ptr) Curl_cstrdup(ptr) -# endif +#undef _tcsdup +#ifdef UNICODE +#define _tcsdup(ptr) Curl_wcsdup(ptr) +#else +#define _tcsdup(ptr) Curl_cstrdup(ptr) #endif +#endif /* _WIN32 */ #endif /* CURLDEBUG */ #endif /* HEADER_CURL_MEMORY_H */ diff --git a/vendor/curl/lib/curl_ntlm_core.c b/vendor/curl/lib/curl_ntlm_core.c index d6cd44d963e..b2b94a3a9bf 100644 --- a/vendor/curl/lib/curl_ntlm_core.c +++ b/vendor/curl/lib/curl_ntlm_core.c @@ -24,7 +24,7 @@ #include "curl_setup.h" -#if defined(USE_CURL_NTLM_CORE) +#ifdef USE_CURL_NTLM_CORE /* * NTLM details: @@ -40,9 +40,8 @@ 3. USE_GNUTLS 4. - 5. USE_MBEDTLS - 6. USE_SECTRANSP - 7. USE_OS400CRYPTO - 8. USE_WIN32_CRYPTO + 6. USE_OS400CRYPTO + 7. USE_WIN32_CRYPTO This ensures that: - the same SSL branch gets activated throughout this source @@ -52,26 +51,26 @@ in NTLM type-3 messages. */ -#if defined(USE_OPENSSL) +#ifdef USE_OPENSSL #include #if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_DEPRECATED_3_0) #define USE_OPENSSL_DES #endif #elif defined(USE_WOLFSSL) #include - #if !defined(NO_DES3) + #ifndef NO_DES3 #define USE_OPENSSL_DES #endif #endif -#if defined(USE_OPENSSL_DES) +#ifdef USE_OPENSSL_DES -#if defined(USE_OPENSSL) +#ifdef USE_OPENSSL # include # include # include # include -# if defined(OPENSSL_IS_AWSLC) +# ifdef OPENSSL_IS_AWSLC # define DES_set_key_unchecked (void)DES_set_key # define DESKEYARG(x) *x # define DESKEY(x) &x @@ -84,7 +83,7 @@ # include # include # include -# if defined(OPENSSL_COEXIST) +# ifdef OPENSSL_COEXIST # define DES_key_schedule WOLFSSL_DES_key_schedule # define DES_cblock WOLFSSL_DES_cblock # define DES_set_odd_parity wolfSSL_DES_set_odd_parity @@ -107,11 +106,6 @@ # include -#elif defined(USE_SECTRANSP) - -# include -# include - #elif defined(USE_OS400CRYPTO) # include "cipher.mih" /* mih/cipher */ #elif defined(USE_WIN32_CRYPTO) @@ -135,7 +129,7 @@ #include "curl_memory.h" #include "memdebug.h" -#if !defined(CURL_NTLM_NOT_SUPPORTED) +#ifndef CURL_NTLM_NOT_SUPPORTED /* * Turns a 56-bit key into being 64-bit wide. */ @@ -152,7 +146,7 @@ static void extend_key_56_to_64(const unsigned char *key_56, char *key) } #endif -#if defined(USE_OPENSSL_DES) +#ifdef USE_OPENSSL_DES /* * Turns a 56-bit key into a 64-bit, odd parity key and sets the key. The * key schedule ks is also set. @@ -209,29 +203,6 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out, return mbedtls_des_crypt_ecb(&ctx, in, out) == 0; } -#elif defined(USE_SECTRANSP) - -static bool encrypt_des(const unsigned char *in, unsigned char *out, - const unsigned char *key_56) -{ - char key[8]; - size_t out_len; - CCCryptorStatus err; - - /* Expand the 56-bit key to 64 bits */ - extend_key_56_to_64(key_56, key); - - /* Set the key parity to odd */ - Curl_des_set_odd_parity((unsigned char *) key, sizeof(key)); - - /* Perform the encryption */ - err = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionECBMode, key, - kCCKeySizeDES, NULL, in, 8 /* inbuflen */, out, - 8 /* outbuflen */, &out_len); - - return err == kCCSuccess; -} - #elif defined(USE_OS400CRYPTO) static bool encrypt_des(const unsigned char *in, unsigned char *out, @@ -306,7 +277,7 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out, return TRUE; } -#endif /* defined(USE_WIN32_CRYPTO) */ +#endif /* USE_WIN32_CRYPTO */ /* * takes a 21 byte array and treats it as 3 56-bit DES keys. The @@ -317,7 +288,7 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys, const unsigned char *plaintext, unsigned char *results) { -#if defined(USE_OPENSSL_DES) +#ifdef USE_OPENSSL_DES DES_key_schedule ks; setup_des_key(keys, DESKEY(ks)); @@ -339,8 +310,8 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys, des_encrypt(&des, 8, results + 8, plaintext); setup_des_key(keys + 14, &des); des_encrypt(&des, 8, results + 16, plaintext); -#elif defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \ - || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) +#elif defined(USE_MBEDTLS) || defined(USE_OS400CRYPTO) || \ + defined(USE_WIN32_CRYPTO) encrypt_des(plaintext, results, keys); encrypt_des(plaintext, results + 8, keys + 7); encrypt_des(plaintext, results + 16, keys + 14); @@ -358,7 +329,7 @@ CURLcode Curl_ntlm_core_mk_lm_hash(const char *password, unsigned char *lmbuffer /* 21 bytes */) { unsigned char pw[14]; -#if !defined(CURL_NTLM_NOT_SUPPORTED) +#ifndef CURL_NTLM_NOT_SUPPORTED static const unsigned char magic[] = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */ }; @@ -371,7 +342,7 @@ CURLcode Curl_ntlm_core_mk_lm_hash(const char *password, { /* Create LanManager hashed password. */ -#if defined(USE_OPENSSL_DES) +#ifdef USE_OPENSSL_DES DES_key_schedule ks; setup_des_key(pw, DESKEY(ks)); @@ -387,8 +358,8 @@ CURLcode Curl_ntlm_core_mk_lm_hash(const char *password, des_encrypt(&des, 8, lmbuffer, magic); setup_des_key(pw + 7, &des); des_encrypt(&des, 8, lmbuffer + 8, magic); -#elif defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \ - || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) +#elif defined(USE_MBEDTLS) || defined(USE_OS400CRYPTO) || \ + defined(USE_WIN32_CRYPTO) encrypt_des(magic, lmbuffer, pw); encrypt_des(magic, lmbuffer + 8, pw + 7); #endif @@ -409,7 +380,7 @@ static void ascii_to_unicode_le(unsigned char *dest, const char *src, } } -#if !defined(USE_WINDOWS_SSPI) +#ifndef USE_WINDOWS_SSPI static void ascii_uppercase_to_unicode_le(unsigned char *dest, const char *src, size_t srclen) @@ -451,7 +422,7 @@ CURLcode Curl_ntlm_core_mk_nt_hash(const char *password, return result; } -#if !defined(USE_WINDOWS_SSPI) +#ifndef USE_WINDOWS_SSPI #define NTLMv2_BLOB_SIGNATURE "\x01\x01\x00\x00" #define NTLMv2_BLOB_LEN (44 -16 + ntlm->target_info_len + 4) @@ -466,7 +437,7 @@ struct ms_filetime { static void time2filetime(struct ms_filetime *ft, time_t t) { #if SIZEOF_TIME_T > 4 - t = (t + CURL_OFF_T_C(11644473600)) * 10000000; + t = (t + (curl_off_t)11644473600) * 10000000; ft->dwLowDateTime = (unsigned int) (t & 0xFFFFFFFF); ft->dwHighDateTime = (unsigned int) (t >> 32); #else diff --git a/vendor/curl/lib/curl_ntlm_core.h b/vendor/curl/lib/curl_ntlm_core.h index e2e4b1bd43a..584f4a17d50 100644 --- a/vendor/curl/lib/curl_ntlm_core.h +++ b/vendor/curl/lib/curl_ntlm_core.h @@ -26,7 +26,11 @@ #include "curl_setup.h" -#if defined(USE_CURL_NTLM_CORE) +#ifdef USE_CURL_NTLM_CORE + +#include "vauth/vauth.h" + +struct ntlmdata; /* Helpers to generate function byte arguments in little endian order */ #define SHORTPAIR(x) ((int)((x) & 0xff)), ((int)(((x) >> 8) & 0xff)) @@ -43,7 +47,7 @@ CURLcode Curl_ntlm_core_mk_lm_hash(const char *password, CURLcode Curl_ntlm_core_mk_nt_hash(const char *password, unsigned char *ntbuffer /* 21 bytes */); -#if !defined(USE_WINDOWS_SSPI) +#ifndef USE_WINDOWS_SSPI CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen, const unsigned char *data, unsigned int datalen, diff --git a/vendor/curl/lib/curl_rtmp.c b/vendor/curl/lib/curl_rtmp.c index 62632c1e9cb..b178dff8450 100644 --- a/vendor/curl/lib/curl_rtmp.c +++ b/vendor/curl/lib/curl_rtmp.c @@ -81,10 +81,10 @@ const struct Curl_handler Curl_handler_rtmp = { rtmp_connect, /* connect_it */ ZERO_NULL, /* connecting */ ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* proto_pollset */ + ZERO_NULL, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ rtmp_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -106,10 +106,10 @@ const struct Curl_handler Curl_handler_rtmpt = { rtmp_connect, /* connect_it */ ZERO_NULL, /* connecting */ ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* proto_pollset */ + ZERO_NULL, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ rtmp_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -131,10 +131,10 @@ const struct Curl_handler Curl_handler_rtmpe = { rtmp_connect, /* connect_it */ ZERO_NULL, /* connecting */ ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* proto_pollset */ + ZERO_NULL, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ rtmp_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -156,10 +156,10 @@ const struct Curl_handler Curl_handler_rtmpte = { rtmp_connect, /* connect_it */ ZERO_NULL, /* connecting */ ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* proto_pollset */ + ZERO_NULL, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ rtmp_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -181,10 +181,10 @@ const struct Curl_handler Curl_handler_rtmps = { rtmp_connect, /* connect_it */ ZERO_NULL, /* connecting */ ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* proto_pollset */ + ZERO_NULL, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ rtmp_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -206,10 +206,10 @@ const struct Curl_handler Curl_handler_rtmpts = { rtmp_connect, /* connect_it */ ZERO_NULL, /* connecting */ ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* proto_pollset */ + ZERO_NULL, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ rtmp_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -296,10 +296,10 @@ static CURLcode rtmp_do(struct Curl_easy *data, bool *done) if(data->state.upload) { Curl_pgrsSetUploadSize(data, data->state.infilesize); - Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE); + Curl_xfer_setup_send(data, FIRSTSOCKET); } else - Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); *done = TRUE; return CURLE_OK; } @@ -326,51 +326,54 @@ static CURLcode rtmp_disconnect(struct Curl_easy *data, return CURLE_OK; } -static ssize_t rtmp_recv(struct Curl_easy *data, int sockindex, char *buf, - size_t len, CURLcode *err) +static CURLcode rtmp_recv(struct Curl_easy *data, int sockindex, char *buf, + size_t len, size_t *pnread) { struct connectdata *conn = data->conn; RTMP *r = Curl_conn_meta_get(conn, CURL_META_RTMP_CONN); + CURLcode result = CURLE_OK; ssize_t nread; (void)sockindex; /* unused */ - if(!r) { - *err = CURLE_FAILED_INIT; - return -1; - } + *pnread = 0; + if(!r) + return CURLE_FAILED_INIT; nread = RTMP_Read(r, buf, curlx_uztosi(len)); if(nread < 0) { if(r->m_read.status == RTMP_READ_COMPLETE || r->m_read.status == RTMP_READ_EOF) { data->req.size = data->req.bytecount; - nread = 0; } else - *err = CURLE_RECV_ERROR; + result = CURLE_RECV_ERROR; } - return nread; + else + *pnread = (size_t)nread; + + return result; } -static ssize_t rtmp_send(struct Curl_easy *data, int sockindex, - const void *buf, size_t len, bool eos, CURLcode *err) +static CURLcode rtmp_send(struct Curl_easy *data, int sockindex, + const void *buf, size_t len, bool eos, + size_t *pnwritten) { struct connectdata *conn = data->conn; RTMP *r = Curl_conn_meta_get(conn, CURL_META_RTMP_CONN); - ssize_t num; + ssize_t nwritten; (void)sockindex; /* unused */ (void)eos; /* unused */ - if(!r) { - *err = CURLE_FAILED_INIT; - return -1; - } + *pnwritten = 0; + if(!r) + return CURLE_FAILED_INIT; - num = RTMP_Write(r, (const char *)buf, curlx_uztosi(len)); - if(num < 0) - *err = CURLE_SEND_ERROR; + nwritten = RTMP_Write(r, (const char *)buf, curlx_uztosi(len)); + if(nwritten < 0) + return CURLE_SEND_ERROR; - return num; + *pnwritten = (size_t)nwritten; + return CURLE_OK; } void Curl_rtmp_version(char *version, size_t len) diff --git a/vendor/curl/lib/curl_sasl.c b/vendor/curl/lib/curl_sasl.c index 4fcbaac263b..8eb63fb9495 100644 --- a/vendor/curl/lib/curl_sasl.c +++ b/vendor/curl/lib/curl_sasl.c @@ -76,44 +76,6 @@ static const struct { { ZERO_NULL, 0, 0 } }; -/* - * Curl_sasl_cleanup() - * - * This is used to cleanup any libraries or curl modules used by the sasl - * functions. - * - * Parameters: - * - * conn [in] - The connection data. - * authused [in] - The authentication mechanism used. - */ -void Curl_sasl_cleanup(struct connectdata *conn, unsigned short authused) -{ - (void)conn; - (void)authused; - -#if defined(USE_KERBEROS5) - /* Cleanup the gssapi structure */ - if(authused == SASL_MECH_GSSAPI) { - Curl_auth_cleanup_gssapi(&conn->krb5); - } -#endif - -#if defined(USE_GSASL) - /* Cleanup the GSASL structure */ - if(authused & (SASL_MECH_SCRAM_SHA_1 | SASL_MECH_SCRAM_SHA_256)) { - Curl_auth_gsasl_cleanup(&conn->gsasl); - } -#endif - -#if defined(USE_NTLM) - /* Cleanup the NTLM structure */ - if(authused == SASL_MECH_NTLM) { - Curl_auth_cleanup_ntlm(&conn->ntlm); - } -#endif -} - /* * Curl_sasl_decode_mech() * @@ -260,7 +222,7 @@ static void sasl_state(struct SASL *sasl, struct Curl_easy *data, infof(data, "SASL %p state change from %s to %s", (void *)sasl, names[sasl->state], names[newstate]); #else - (void) data; + (void)data; #endif sasl->state = newstate; @@ -334,6 +296,241 @@ bool Curl_sasl_can_authenticate(struct SASL *sasl, struct Curl_easy *data) return FALSE; } +struct sasl_ctx { + struct SASL *sasl; + struct connectdata *conn; + const char *user; + unsigned short enabledmechs; + const char *mech; + saslstate state1; + saslstate state2; + struct bufref resp; + CURLcode result; +}; + +static bool sasl_choose_external(struct Curl_easy *data, struct sasl_ctx *sctx) +{ + if((sctx->enabledmechs & SASL_MECH_EXTERNAL) && !sctx->conn->passwd[0]) { + sctx->mech = SASL_MECH_STRING_EXTERNAL; + sctx->state1 = SASL_EXTERNAL; + sctx->sasl->authused = SASL_MECH_EXTERNAL; + + if(sctx->sasl->force_ir || data->set.sasl_ir) + Curl_auth_create_external_message(sctx->conn->user, &sctx->resp); + return TRUE; + } + return FALSE; +} + +#ifdef USE_KERBEROS5 +static bool sasl_choose_krb5(struct Curl_easy *data, struct sasl_ctx *sctx) +{ + if(sctx->user && + (sctx->enabledmechs & SASL_MECH_GSSAPI) && + Curl_auth_is_gssapi_supported() && + Curl_auth_user_contains_domain(sctx->conn->user)) { + const char *service = data->set.str[STRING_SERVICE_NAME] ? + data->set.str[STRING_SERVICE_NAME] : + sctx->sasl->params->service; + + sctx->sasl->mutual_auth = FALSE; + sctx->mech = SASL_MECH_STRING_GSSAPI; + sctx->state1 = SASL_GSSAPI; + sctx->state2 = SASL_GSSAPI_TOKEN; + sctx->sasl->authused = SASL_MECH_GSSAPI; + + if(sctx->sasl->force_ir || data->set.sasl_ir) { + struct kerberos5data *krb5 = Curl_auth_krb5_get(sctx->conn); + sctx->result = !krb5 ? CURLE_OUT_OF_MEMORY : + Curl_auth_create_gssapi_user_message(data, sctx->conn->user, + sctx->conn->passwd, + service, sctx->conn->host.name, + sctx->sasl->mutual_auth, NULL, + krb5, &sctx->resp); + } + return TRUE; + } + return FALSE; +} +#endif /* USE_KERBEROS5 */ + +#ifdef USE_GSASL +static bool sasl_choose_gsasl(struct Curl_easy *data, struct sasl_ctx *sctx) +{ + struct gsasldata *gsasl; + struct bufref nullmsg; + + if(sctx->user && + (sctx->enabledmechs & (SASL_MECH_SCRAM_SHA_256|SASL_MECH_SCRAM_SHA_1))) { + gsasl = Curl_auth_gsasl_get(sctx->conn); + if(!gsasl) { + sctx->result = CURLE_OUT_OF_MEMORY; + return TRUE; /* attempted, but failed */ + } + + if((sctx->enabledmechs & SASL_MECH_SCRAM_SHA_256) && + Curl_auth_gsasl_is_supported(data, SASL_MECH_STRING_SCRAM_SHA_256, + gsasl)) { + sctx->mech = SASL_MECH_STRING_SCRAM_SHA_256; + sctx->sasl->authused = SASL_MECH_SCRAM_SHA_256; + } + else if((sctx->enabledmechs & SASL_MECH_SCRAM_SHA_1) && + Curl_auth_gsasl_is_supported(data, SASL_MECH_STRING_SCRAM_SHA_1, + gsasl)) { + sctx->mech = SASL_MECH_STRING_SCRAM_SHA_1; + sctx->sasl->authused = SASL_MECH_SCRAM_SHA_1; + } + else + return FALSE; + + Curl_bufref_init(&nullmsg); + sctx->state1 = SASL_GSASL; + sctx->state2 = SASL_GSASL; + sctx->result = Curl_auth_gsasl_start(data, sctx->conn->user, + sctx->conn->passwd, gsasl); + if(!sctx->result && (sctx->sasl->force_ir || data->set.sasl_ir)) + sctx->result = Curl_auth_gsasl_token(data, &nullmsg, gsasl, &sctx->resp); + return TRUE; + } + return FALSE; +} + +#endif /* USE_GSASL */ + +#ifndef CURL_DISABLE_DIGEST_AUTH +static bool sasl_choose_digest(struct Curl_easy *data, struct sasl_ctx *sctx) +{ + (void)data; + if(!sctx->user) + return FALSE; + else if((sctx->enabledmechs & SASL_MECH_DIGEST_MD5) && + Curl_auth_is_digest_supported()) { + sctx->mech = SASL_MECH_STRING_DIGEST_MD5; + sctx->state1 = SASL_DIGESTMD5; + sctx->sasl->authused = SASL_MECH_DIGEST_MD5; + return TRUE; + } + else if(sctx->enabledmechs & SASL_MECH_CRAM_MD5) { + sctx->mech = SASL_MECH_STRING_CRAM_MD5; + sctx->state1 = SASL_CRAMMD5; + sctx->sasl->authused = SASL_MECH_CRAM_MD5; + return TRUE; + } + return FALSE; +} +#endif /* !CURL_DISABLE_DIGEST_AUTH */ + +#ifdef USE_NTLM +static bool sasl_choose_ntlm(struct Curl_easy *data, struct sasl_ctx *sctx) +{ + if(!sctx->user) + return FALSE; + else if((sctx->enabledmechs & SASL_MECH_NTLM) && + Curl_auth_is_ntlm_supported()) { + const char *service = data->set.str[STRING_SERVICE_NAME] ? + data->set.str[STRING_SERVICE_NAME] : + sctx->sasl->params->service; + const char *hostname; + int port; + + Curl_conn_get_current_host(data, FIRSTSOCKET, &hostname, &port); + + sctx->mech = SASL_MECH_STRING_NTLM; + sctx->state1 = SASL_NTLM; + sctx->state2 = SASL_NTLM_TYPE2MSG; + sctx->sasl->authused = SASL_MECH_NTLM; + + if(sctx->sasl->force_ir || data->set.sasl_ir) { + struct ntlmdata *ntlm = Curl_auth_ntlm_get(sctx->conn, FALSE); + sctx->result = !ntlm ? CURLE_OUT_OF_MEMORY : + Curl_auth_create_ntlm_type1_message(data, + sctx->conn->user, + sctx->conn->passwd, + service, hostname, + ntlm, &sctx->resp); + } + return TRUE; + } + return FALSE; +} +#endif /* USE_NTLM */ + +static bool sasl_choose_oauth(struct Curl_easy *data, struct sasl_ctx *sctx) +{ + const char *oauth_bearer = data->set.str[STRING_BEARER]; + + if(sctx->user && oauth_bearer && + (sctx->enabledmechs & SASL_MECH_OAUTHBEARER)) { + const char *hostname; + int port; + Curl_conn_get_current_host(data, FIRSTSOCKET, &hostname, &port); + + sctx->mech = SASL_MECH_STRING_OAUTHBEARER; + sctx->state1 = SASL_OAUTH2; + sctx->state2 = SASL_OAUTH2_RESP; + sctx->sasl->authused = SASL_MECH_OAUTHBEARER; + + if(sctx->sasl->force_ir || data->set.sasl_ir) + sctx->result = + Curl_auth_create_oauth_bearer_message(sctx->conn->user, + hostname, port, + oauth_bearer, &sctx->resp); + return TRUE; + } + return FALSE; +} + +static bool sasl_choose_oauth2(struct Curl_easy *data, struct sasl_ctx *sctx) +{ + const char *oauth_bearer = data->set.str[STRING_BEARER]; + + if(sctx->user && oauth_bearer && + (sctx->enabledmechs & SASL_MECH_XOAUTH2)) { + sctx->mech = SASL_MECH_STRING_XOAUTH2; + sctx->state1 = SASL_OAUTH2; + sctx->sasl->authused = SASL_MECH_XOAUTH2; + + if(sctx->sasl->force_ir || data->set.sasl_ir) + sctx->result = Curl_auth_create_xoauth_bearer_message(sctx->conn->user, + oauth_bearer, + &sctx->resp); + return TRUE; + } + return FALSE; +} + +static bool sasl_choose_plain(struct Curl_easy *data, struct sasl_ctx *sctx) +{ + if(sctx->user && (sctx->enabledmechs & SASL_MECH_PLAIN)) { + sctx->mech = SASL_MECH_STRING_PLAIN; + sctx->state1 = SASL_PLAIN; + sctx->sasl->authused = SASL_MECH_PLAIN; + + if(sctx->sasl->force_ir || data->set.sasl_ir) + sctx->result = + Curl_auth_create_plain_message(sctx->conn->sasl_authzid, + sctx->conn->user, sctx->conn->passwd, + &sctx->resp); + return TRUE; + } + return FALSE; +} + +static bool sasl_choose_login(struct Curl_easy *data, struct sasl_ctx *sctx) +{ + if(sctx->user && (sctx->enabledmechs & SASL_MECH_LOGIN)) { + sctx->mech = SASL_MECH_STRING_LOGIN; + sctx->state1 = SASL_LOGIN; + sctx->state2 = SASL_LOGIN_PASSWD; + sctx->sasl->authused = SASL_MECH_LOGIN; + + if(sctx->sasl->force_ir || data->set.sasl_ir) + Curl_auth_create_login_message(sctx->conn->user, &sctx->resp); + return TRUE; + } + return FALSE; +} + /* * Curl_sasl_start() * @@ -342,185 +539,66 @@ bool Curl_sasl_can_authenticate(struct SASL *sasl, struct Curl_easy *data) CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data, bool force_ir, saslprogress *progress) { - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - unsigned short enabledmechs; - const char *mech = NULL; - struct bufref resp; - saslstate state1 = SASL_STOP; - saslstate state2 = SASL_FINAL; - const char *hostname, *disp_hostname; - int port; -#if defined(USE_KERBEROS5) || defined(USE_NTLM) - const char *service = data->set.str[STRING_SERVICE_NAME] ? - data->set.str[STRING_SERVICE_NAME] : - sasl->params->service; -#endif - const char *oauth_bearer = data->set.str[STRING_BEARER]; - struct bufref nullmsg; + struct sasl_ctx sctx; - Curl_conn_get_host(data, FIRSTSOCKET, &hostname, &disp_hostname, &port); - Curl_bufref_init(&nullmsg); - Curl_bufref_init(&resp); sasl->force_ir = force_ir; /* Latch for future use */ sasl->authused = 0; /* No mechanism used yet */ - enabledmechs = sasl->authmechs & sasl->prefmech; *progress = SASL_IDLE; + memset(&sctx, 0, sizeof(sctx)); + sctx.sasl = sasl; + sctx.conn = data->conn; + sctx.user = data->state.aptr.user; + Curl_bufref_init(&sctx.resp); + sctx.enabledmechs = sasl->authmechs & sasl->prefmech; + sctx.state1 = SASL_STOP; + sctx.state2 = SASL_FINAL; + /* Calculate the supported authentication mechanism, by decreasing order of security, as well as the initial response where appropriate */ - if((enabledmechs & SASL_MECH_EXTERNAL) && !conn->passwd[0]) { - mech = SASL_MECH_STRING_EXTERNAL; - state1 = SASL_EXTERNAL; - sasl->authused = SASL_MECH_EXTERNAL; - - if(force_ir || data->set.sasl_ir) - Curl_auth_create_external_message(conn->user, &resp); - } - else if(data->state.aptr.user) { -#if defined(USE_KERBEROS5) - if((enabledmechs & SASL_MECH_GSSAPI) && Curl_auth_is_gssapi_supported() && - Curl_auth_user_contains_domain(conn->user)) { - sasl->mutual_auth = FALSE; - mech = SASL_MECH_STRING_GSSAPI; - state1 = SASL_GSSAPI; - state2 = SASL_GSSAPI_TOKEN; - sasl->authused = SASL_MECH_GSSAPI; - - if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_gssapi_user_message(data, conn->user, - conn->passwd, - service, - conn->host.name, - sasl->mutual_auth, - NULL, &conn->krb5, - &resp); - } - else + if(sasl_choose_external(data, &sctx) || +#ifdef USE_KERBEROS5 + sasl_choose_krb5(data, &sctx) || #endif #ifdef USE_GSASL - if((enabledmechs & SASL_MECH_SCRAM_SHA_256) && - Curl_auth_gsasl_is_supported(data, SASL_MECH_STRING_SCRAM_SHA_256, - &conn->gsasl)) { - mech = SASL_MECH_STRING_SCRAM_SHA_256; - sasl->authused = SASL_MECH_SCRAM_SHA_256; - state1 = SASL_GSASL; - state2 = SASL_GSASL; - - result = Curl_auth_gsasl_start(data, conn->user, - conn->passwd, &conn->gsasl); - if(result == CURLE_OK && (force_ir || data->set.sasl_ir)) - result = Curl_auth_gsasl_token(data, &nullmsg, &conn->gsasl, &resp); - } - else if((enabledmechs & SASL_MECH_SCRAM_SHA_1) && - Curl_auth_gsasl_is_supported(data, SASL_MECH_STRING_SCRAM_SHA_1, - &conn->gsasl)) { - mech = SASL_MECH_STRING_SCRAM_SHA_1; - sasl->authused = SASL_MECH_SCRAM_SHA_1; - state1 = SASL_GSASL; - state2 = SASL_GSASL; - - result = Curl_auth_gsasl_start(data, conn->user, - conn->passwd, &conn->gsasl); - if(result == CURLE_OK && (force_ir || data->set.sasl_ir)) - result = Curl_auth_gsasl_token(data, &nullmsg, &conn->gsasl, &resp); - } - else + sasl_choose_gsasl(data, &sctx) || #endif #ifndef CURL_DISABLE_DIGEST_AUTH - if((enabledmechs & SASL_MECH_DIGEST_MD5) && - Curl_auth_is_digest_supported()) { - mech = SASL_MECH_STRING_DIGEST_MD5; - state1 = SASL_DIGESTMD5; - sasl->authused = SASL_MECH_DIGEST_MD5; - } - else if(enabledmechs & SASL_MECH_CRAM_MD5) { - mech = SASL_MECH_STRING_CRAM_MD5; - state1 = SASL_CRAMMD5; - sasl->authused = SASL_MECH_CRAM_MD5; - } - else + sasl_choose_digest(data, &sctx) || #endif #ifdef USE_NTLM - if((enabledmechs & SASL_MECH_NTLM) && Curl_auth_is_ntlm_supported()) { - mech = SASL_MECH_STRING_NTLM; - state1 = SASL_NTLM; - state2 = SASL_NTLM_TYPE2MSG; - sasl->authused = SASL_MECH_NTLM; - - if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_ntlm_type1_message(data, - conn->user, conn->passwd, - service, - hostname, - &conn->ntlm, &resp); - } - else + sasl_choose_ntlm(data, &sctx) || #endif - if((enabledmechs & SASL_MECH_OAUTHBEARER) && oauth_bearer) { - mech = SASL_MECH_STRING_OAUTHBEARER; - state1 = SASL_OAUTH2; - state2 = SASL_OAUTH2_RESP; - sasl->authused = SASL_MECH_OAUTHBEARER; - - if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_oauth_bearer_message(conn->user, - hostname, - port, - oauth_bearer, - &resp); - } - else if((enabledmechs & SASL_MECH_XOAUTH2) && oauth_bearer) { - mech = SASL_MECH_STRING_XOAUTH2; - state1 = SASL_OAUTH2; - sasl->authused = SASL_MECH_XOAUTH2; - - if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_xoauth_bearer_message(conn->user, - oauth_bearer, - &resp); - } - else if(enabledmechs & SASL_MECH_PLAIN) { - mech = SASL_MECH_STRING_PLAIN; - state1 = SASL_PLAIN; - sasl->authused = SASL_MECH_PLAIN; - - if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_plain_message(conn->sasl_authzid, - conn->user, conn->passwd, - &resp); - } - else if(enabledmechs & SASL_MECH_LOGIN) { - mech = SASL_MECH_STRING_LOGIN; - state1 = SASL_LOGIN; - state2 = SASL_LOGIN_PASSWD; - sasl->authused = SASL_MECH_LOGIN; - - if(force_ir || data->set.sasl_ir) - Curl_auth_create_login_message(conn->user, &resp); - } + sasl_choose_oauth(data, &sctx) || + sasl_choose_oauth2(data, &sctx) || + sasl_choose_plain(data, &sctx) || + sasl_choose_login(data, &sctx)) { + /* selected, either we have a mechanism or a failure */ + DEBUGASSERT(sctx.mech || sctx.result); } - if(!result && mech) { - sasl->curmech = mech; - if(Curl_bufref_ptr(&resp)) - result = build_message(sasl, &resp); + if(!sctx.result && sctx.mech) { + sasl->curmech = sctx.mech; + if(Curl_bufref_ptr(&sctx.resp)) + sctx.result = build_message(sasl, &sctx.resp); if(sasl->params->maxirlen && - strlen(mech) + Curl_bufref_len(&resp) > sasl->params->maxirlen) - Curl_bufref_free(&resp); + strlen(sctx.mech) + Curl_bufref_len(&sctx.resp) > + sasl->params->maxirlen) + Curl_bufref_free(&sctx.resp); - if(!result) - result = sasl->params->sendauth(data, mech, &resp); + if(!sctx.result) + sctx.result = sasl->params->sendauth(data, sctx.mech, &sctx.resp); - if(!result) { + if(!sctx.result) { *progress = SASL_INPROGRESS; - sasl_state(sasl, data, Curl_bufref_ptr(&resp) ? state2 : state1); + sasl_state(sasl, data, Curl_bufref_ptr(&sctx.resp) ? + sctx.state2 : sctx.state1); } } - Curl_bufref_free(&resp); - return result; + Curl_bufref_free(&sctx.resp); + return sctx.result; } /* @@ -535,10 +613,10 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, struct connectdata *conn = data->conn; saslstate newstate = SASL_FINAL; struct bufref resp; - const char *hostname, *disp_hostname; + const char *hostname; int port; -#if defined(USE_KERBEROS5) || defined(USE_NTLM) \ - || !defined(CURL_DISABLE_DIGEST_AUTH) +#if defined(USE_KERBEROS5) || defined(USE_NTLM) || \ + !defined(CURL_DISABLE_DIGEST_AUTH) const char *service = data->set.str[STRING_SERVICE_NAME] ? data->set.str[STRING_SERVICE_NAME] : sasl->params->service; @@ -546,7 +624,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, const char *oauth_bearer = data->set.str[STRING_BEARER]; struct bufref serverdata; - Curl_conn_get_host(data, FIRSTSOCKET, &hostname, &disp_hostname, &port); + Curl_conn_get_current_host(data, FIRSTSOCKET, &hostname, &port); Curl_bufref_init(&serverdata); Curl_bufref_init(&resp); *progress = SASL_INPROGRESS; @@ -587,8 +665,11 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, #ifdef USE_GSASL case SASL_GSASL: result = get_server_message(sasl, data, &serverdata); - if(!result) - result = Curl_auth_gsasl_token(data, &serverdata, &conn->gsasl, &resp); + if(!result) { + struct gsasldata *gsasl = Curl_auth_gsasl_get(conn); + result = !gsasl ? CURLE_OUT_OF_MEMORY : + Curl_auth_gsasl_token(data, &serverdata, gsasl, &resp); + } if(!result && Curl_bufref_len(&resp) > 0) newstate = SASL_GSASL; break; @@ -615,50 +696,57 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, #endif #ifdef USE_NTLM - case SASL_NTLM: + case SASL_NTLM: { /* Create the type-1 message */ - result = Curl_auth_create_ntlm_type1_message(data, - conn->user, conn->passwd, - service, hostname, - &conn->ntlm, &resp); + struct ntlmdata *ntlm = Curl_auth_ntlm_get(conn, FALSE); + result = !ntlm ? CURLE_OUT_OF_MEMORY : + Curl_auth_create_ntlm_type1_message(data, + conn->user, conn->passwd, + service, hostname, + ntlm, &resp); newstate = SASL_NTLM_TYPE2MSG; break; - case SASL_NTLM_TYPE2MSG: + } + case SASL_NTLM_TYPE2MSG: { /* Decode the type-2 message */ - result = get_server_message(sasl, data, &serverdata); + struct ntlmdata *ntlm = Curl_auth_ntlm_get(conn, FALSE); + result = !ntlm ? CURLE_FAILED_INIT : + get_server_message(sasl, data, &serverdata); if(!result) - result = Curl_auth_decode_ntlm_type2_message(data, &serverdata, - &conn->ntlm); + result = Curl_auth_decode_ntlm_type2_message(data, &serverdata, ntlm); if(!result) result = Curl_auth_create_ntlm_type3_message(data, conn->user, - conn->passwd, &conn->ntlm, + conn->passwd, ntlm, &resp); break; + } #endif -#if defined(USE_KERBEROS5) - case SASL_GSSAPI: - result = Curl_auth_create_gssapi_user_message(data, conn->user, - conn->passwd, - service, - conn->host.name, +#ifdef USE_KERBEROS5 + case SASL_GSSAPI: { + struct kerberos5data *krb5 = Curl_auth_krb5_get(conn); + result = !krb5 ? CURLE_OUT_OF_MEMORY : + Curl_auth_create_gssapi_user_message(data, conn->user, conn->passwd, + service, conn->host.name, sasl->mutual_auth, NULL, - &conn->krb5, - &resp); + krb5, &resp); newstate = SASL_GSSAPI_TOKEN; break; + } case SASL_GSSAPI_TOKEN: result = get_server_message(sasl, data, &serverdata); if(!result) { - if(sasl->mutual_auth) { + struct kerberos5data *krb5 = Curl_auth_krb5_get(conn); + if(!krb5) + result = CURLE_OUT_OF_MEMORY; + else if(sasl->mutual_auth) { /* Decode the user token challenge and create the optional response message */ result = Curl_auth_create_gssapi_user_message(data, NULL, NULL, NULL, NULL, sasl->mutual_auth, &serverdata, - &conn->krb5, - &resp); + krb5, &resp); newstate = SASL_GSSAPI_NO_DATA; } else @@ -666,19 +754,22 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, result = Curl_auth_create_gssapi_security_message(data, conn->sasl_authzid, &serverdata, - &conn->krb5, - &resp); + krb5, &resp); } break; case SASL_GSSAPI_NO_DATA: /* Decode the security challenge and create the response message */ result = get_server_message(sasl, data, &serverdata); - if(!result) - result = Curl_auth_create_gssapi_security_message(data, - conn->sasl_authzid, - &serverdata, - &conn->krb5, - &resp); + if(!result) { + struct kerberos5data *krb5 = Curl_auth_krb5_get(conn); + if(!krb5) + result = CURLE_OUT_OF_MEMORY; + else + result = Curl_auth_create_gssapi_security_message(data, + conn->sasl_authzid, + &serverdata, + krb5, &resp); + } break; #endif diff --git a/vendor/curl/lib/curl_sasl.h b/vendor/curl/lib/curl_sasl.h index 59983f7c669..0674d56f865 100644 --- a/vendor/curl/lib/curl_sasl.h +++ b/vendor/curl/lib/curl_sasl.h @@ -135,10 +135,6 @@ struct SASL { (wordlen == (sizeof(mech) - 1) / sizeof(char) && \ !memcmp(line, mech, wordlen)) -/* This is used to cleanup any libraries or curl modules used by the sasl - functions */ -void Curl_sasl_cleanup(struct connectdata *conn, unsigned short authused); - /* Convert a mechanism name to a token */ unsigned short Curl_sasl_decode_mech(const char *ptr, size_t maxlen, size_t *len); diff --git a/vendor/curl/lib/curl_setup.h b/vendor/curl/lib/curl_setup.h index 1d484c61ab4..0a6591db834 100644 --- a/vendor/curl/lib/curl_setup.h +++ b/vendor/curl/lib/curl_setup.h @@ -75,6 +75,11 @@ #endif #endif +#if defined(__MINGW32__) && !defined(__MINGW32CE__) && \ + (!defined(__MINGW64_VERSION_MAJOR) || (__MINGW64_VERSION_MAJOR < 3)) +#error "Building curl requires mingw-w64 3.0 or later" +#endif + /* Visual Studio 2008 is the minimum Visual Studio version we support. Workarounds for older versions of Visual Studio have been removed. */ #if defined(_MSC_VER) && (_MSC_VER < 1500) @@ -224,46 +229,46 @@ #ifdef HTTP_ONLY # ifndef CURL_DISABLE_DICT -# define CURL_DISABLE_DICT +# define CURL_DISABLE_DICT # endif # ifndef CURL_DISABLE_FILE -# define CURL_DISABLE_FILE +# define CURL_DISABLE_FILE # endif # ifndef CURL_DISABLE_FTP -# define CURL_DISABLE_FTP +# define CURL_DISABLE_FTP # endif # ifndef CURL_DISABLE_GOPHER -# define CURL_DISABLE_GOPHER +# define CURL_DISABLE_GOPHER # endif # ifndef CURL_DISABLE_IMAP -# define CURL_DISABLE_IMAP +# define CURL_DISABLE_IMAP # endif # ifndef CURL_DISABLE_LDAP -# define CURL_DISABLE_LDAP +# define CURL_DISABLE_LDAP # endif # ifndef CURL_DISABLE_LDAPS -# define CURL_DISABLE_LDAPS +# define CURL_DISABLE_LDAPS # endif # ifndef CURL_DISABLE_MQTT -# define CURL_DISABLE_MQTT +# define CURL_DISABLE_MQTT # endif # ifndef CURL_DISABLE_POP3 -# define CURL_DISABLE_POP3 +# define CURL_DISABLE_POP3 # endif # ifndef CURL_DISABLE_RTSP -# define CURL_DISABLE_RTSP +# define CURL_DISABLE_RTSP # endif # ifndef CURL_DISABLE_SMB -# define CURL_DISABLE_SMB +# define CURL_DISABLE_SMB # endif # ifndef CURL_DISABLE_SMTP -# define CURL_DISABLE_SMTP +# define CURL_DISABLE_SMTP # endif # ifndef CURL_DISABLE_TELNET -# define CURL_DISABLE_TELNET +# define CURL_DISABLE_TELNET # endif # ifndef CURL_DISABLE_TFTP -# define CURL_DISABLE_TFTP +# define CURL_DISABLE_TFTP # endif #endif @@ -331,10 +336,10 @@ #define CURL_CONC_MACROS(A,B) CURL_CONC_MACROS_(A,B) /* curl uses its own printf() function internally. It understands the GNU - * format. Use this format, so that is matches the GNU format attribute we + * format. Use this format, so that it matches the GNU format attribute we * use with the MinGW compiler, allowing it to verify them at compile-time. */ -#ifdef __MINGW32__ +#ifdef __MINGW32__ # undef CURL_FORMAT_CURL_OFF_T # undef CURL_FORMAT_CURL_OFF_TU # define CURL_FORMAT_CURL_OFF_T "lld" @@ -470,62 +475,46 @@ #include #endif -/* - * Large file (>2Gb) support using Win32 functions. - */ - -#ifdef USE_WIN32_LARGE_FILES +#ifdef _WIN32 # ifdef HAVE_IO_H # include # endif # include # include -# undef lseek -# define lseek(fdes,offset,whence) _lseeki64(fdes, offset, whence) -# undef fstat -# define fstat(fdes,stp) _fstati64(fdes, stp) -# undef stat -# define stat(fname,stp) curlx_win32_stat(fname, stp) -# define struct_stat struct _stati64 -# define LSEEK_ERROR (__int64)-1 -# define open curlx_win32_open -# define fopen(fname,mode) curlx_win32_fopen(fname, mode) - int curlx_win32_open(const char *filename, int oflag, ...); - int curlx_win32_stat(const char *path, struct_stat *buffer); - FILE *curlx_win32_fopen(const char *filename, const char *mode); -#endif - -#ifdef __DJGPP__ -/* Requires DJGPP 2.04 */ -# include -# undef lseek -# define lseek(fdes,offset,whence) llseek(fdes, offset, whence) -# define LSEEK_ERROR (offset_t)-1 -#endif - -/* - * Small file (<2Gb) support using Win32 functions. - */ - -#if defined(_WIN32) && !defined(USE_WIN32_LARGE_FILES) -# ifdef HAVE_IO_H -# include +# ifdef USE_WIN32_LARGE_FILES + /* Large file (>2Gb) support using Win32 functions. */ +# undef lseek +# define lseek(fdes, offset, whence) _lseeki64(fdes, offset, whence) +# undef fstat +# define fstat(fdes,stp) _fstati64(fdes, stp) +# undef stat +# define struct_stat struct _stati64 +# define LSEEK_ERROR (__int64)-1 +# else + /* Small file (<2Gb) support using Win32 functions. */ +# ifndef UNDER_CE +# undef lseek +# define lseek(fdes, offset, whence) _lseek(fdes, (long)offset, whence) +# define fstat(fdes, stp) _fstat(fdes, stp) +# define struct_stat struct _stat +# endif +# define LSEEK_ERROR (long)-1 # endif -# include -# include # ifndef UNDER_CE -# undef lseek -# define lseek(fdes,offset,whence) _lseek(fdes, (long)offset, whence) -# define fstat(fdes,stp) _fstat(fdes, stp) -# define stat(fname,stp) curlx_win32_stat(fname, stp) -# define struct_stat struct _stat -# define open curlx_win32_open -# define fopen(fname,mode) curlx_win32_fopen(fname, mode) int curlx_win32_stat(const char *path, struct_stat *buffer); int curlx_win32_open(const char *filename, int oflag, ...); FILE *curlx_win32_fopen(const char *filename, const char *mode); +# define stat(fname, stp) curlx_win32_stat(fname, stp) +# define open curlx_win32_open +# define CURL_FOPEN(fname, mode) curlx_win32_fopen(fname, mode) +# define fopen(fname, mode) CURL_FOPEN(fname, mode) # endif -# define LSEEK_ERROR (long)-1 +#elif defined(__DJGPP__) + /* Requires DJGPP 2.04 */ +# include +# undef lseek +# define lseek(fdes,offset,whence) llseek(fdes, offset, whence) +# define LSEEK_ERROR (offset_t)-1 #endif #ifndef struct_stat @@ -565,11 +554,11 @@ #ifndef SIZEOF_OFF_T # if defined(__VMS) && !defined(__VAX) -# if defined(_LARGEFILE) +# ifdef _LARGEFILE # define SIZEOF_OFF_T 8 # endif # elif defined(__OS400__) && defined(__ILEC400__) -# if defined(_LARGE_FILES) +# ifdef _LARGE_FILES # define SIZEOF_OFF_T 8 # endif # elif defined(__MVS__) && defined(__IBMC__) @@ -582,7 +571,7 @@ # endif # endif # ifndef SIZEOF_OFF_T -# define SIZEOF_OFF_T 4 +# define SIZEOF_OFF_T 4 # endif #endif @@ -590,9 +579,9 @@ #error "too small curl_off_t" #else /* assume SIZEOF_CURL_OFF_T == 8 */ -# define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF) +# define CURL_OFF_T_MAX 0x7FFFFFFFFFFFFFFF #endif -#define CURL_OFF_T_MIN (-CURL_OFF_T_MAX - CURL_OFF_T_C(1)) +#define CURL_OFF_T_MIN (-CURL_OFF_T_MAX - 1) #if (SIZEOF_CURL_OFF_T != 8) # error "curl_off_t must be exactly 64 bits" @@ -677,12 +666,8 @@ # define select(n,r,w,x,t) select_s(n,r,w,x,t) # define ioctl(x,y,z) ioctlsocket(x,y,(char *)(z)) # include -# ifdef word -# undef word -# endif -# ifdef byte -# undef byte -# endif +# undef word +# undef byte # endif /* MSDOS */ @@ -739,8 +724,8 @@ #endif #if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_MBEDTLS) || \ - defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \ - defined(USE_BEARSSL) || defined(USE_RUSTLS) + defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || \ + defined(USE_RUSTLS) #define USE_SSL /* SSL support has been enabled */ #endif @@ -775,7 +760,7 @@ /* Single point where USE_NTLM definition might be defined */ #ifndef CURL_DISABLE_NTLM # if defined(USE_OPENSSL) || defined(USE_MBEDTLS) || \ - defined(USE_GNUTLS) || defined(USE_SECTRANSP) || \ + defined(USE_GNUTLS) || \ defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \ (defined(USE_WOLFSSL) && defined(HAVE_WOLFSSL_DES_ECB_ENCRYPT)) # define USE_CURL_NTLM_CORE @@ -952,10 +937,10 @@ endings either CRLF or LF so 't' is appropriate. /* for systems that do not detect this in configure */ #ifndef CURL_SA_FAMILY_T -# if defined(HAVE_SA_FAMILY_T) -# define CURL_SA_FAMILY_T sa_family_t -# elif defined(HAVE_ADDRESS_FAMILY) +# if defined(_WIN32) && !defined(UNDER_CE) # define CURL_SA_FAMILY_T ADDRESS_FAMILY +# elif defined(HAVE_SA_FAMILY_T) +# define CURL_SA_FAMILY_T sa_family_t # elif defined(__AMIGA__) # define CURL_SA_FAMILY_T unsigned char # else @@ -976,15 +961,140 @@ endings either CRLF or LF so 't' is appropriate. #define CURL_ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) +#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS /* only if not already done */ +/* + * The following memory function replacement typedef's are COPIED from + * curl/curl.h and MUST match the originals. We copy them to avoid having to + * include curl/curl.h here. We avoid that include since it includes stdio.h + * and other headers that may get messed up with defines done here. + */ +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 + +extern curl_malloc_callback Curl_cmalloc; +extern curl_free_callback Curl_cfree; +extern curl_realloc_callback Curl_crealloc; +extern curl_strdup_callback Curl_cstrdup; +extern curl_calloc_callback Curl_ccalloc; + +/* + * Curl_safefree defined as a macro to allow MemoryTracking feature + * to log free() calls at same location where Curl_safefree is used. + * This macro also assigns NULL to given pointer when free'd. + */ +#define Curl_safefree(ptr) \ + do { free((ptr)); (ptr) = NULL;} while(0) + #ifdef CURLDEBUG +#ifdef __clang__ +# define ALLOC_FUNC __attribute__((__malloc__)) +# if __clang_major__ >= 4 +# define ALLOC_SIZE(s) __attribute__((__alloc_size__(s))) +# define ALLOC_SIZE2(n, s) __attribute__((__alloc_size__(n, s))) +# else +# define ALLOC_SIZE(s) +# define ALLOC_SIZE2(n, s) +# endif +#elif defined(__GNUC__) && __GNUC__ >= 3 +# define ALLOC_FUNC __attribute__((__malloc__)) +# define ALLOC_SIZE(s) __attribute__((__alloc_size__(s))) +# define ALLOC_SIZE2(n, s) __attribute__((__alloc_size__(n, s))) +#elif defined(_MSC_VER) +# define ALLOC_FUNC __declspec(restrict) +# define ALLOC_SIZE(s) +# define ALLOC_SIZE2(n, s) +#else +# define ALLOC_FUNC +# define ALLOC_SIZE(s) +# define ALLOC_SIZE2(n, s) +#endif + +#include /* for CURL_EXTERN */ + +extern FILE *curl_dbg_logfile; + +/* memory functions */ +CURL_EXTERN void curl_dbg_free(void *ptr, int line, const char *source); +CURL_EXTERN ALLOC_FUNC ALLOC_SIZE(1) + void *curl_dbg_malloc(size_t size, int line, const char *source); +CURL_EXTERN ALLOC_FUNC ALLOC_SIZE2(1, 2) + void *curl_dbg_calloc(size_t n, size_t size, int line, const char *source); +CURL_EXTERN ALLOC_SIZE(2) + void *curl_dbg_realloc(void *ptr, size_t size, int line, const char *source); +CURL_EXTERN ALLOC_FUNC + char *curl_dbg_strdup(const char *str, int line, const char *src); +#if defined(_WIN32) && defined(UNICODE) +CURL_EXTERN ALLOC_FUNC + wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, const char *source); +#endif + +CURL_EXTERN void curl_dbg_memdebug(const char *logname); +CURL_EXTERN void curl_dbg_memlimit(long limit); +CURL_EXTERN void curl_dbg_log(const char *format, ...) CURL_PRINTF(1, 2); + +/* file descriptor manipulators */ +CURL_EXTERN curl_socket_t curl_dbg_socket(int domain, int type, int protocol, + int line, const char *source); +CURL_EXTERN void curl_dbg_mark_sclose(curl_socket_t sockfd, + int line, const char *source); +CURL_EXTERN int curl_dbg_sclose(curl_socket_t sockfd, + int line, const char *source); +CURL_EXTERN curl_socket_t curl_dbg_accept(curl_socket_t s, void *a, void *alen, + int line, const char *source); +#ifdef HAVE_ACCEPT4 +CURL_EXTERN curl_socket_t curl_dbg_accept4(curl_socket_t s, void *saddr, + void *saddrlen, int flags, + int line, const char *source); +#endif +#ifdef HAVE_SOCKETPAIR +CURL_EXTERN int curl_dbg_socketpair(int domain, int type, int protocol, + curl_socket_t socket_vector[2], + int line, const char *source); +#endif + +/* send/receive sockets */ +CURL_EXTERN SEND_TYPE_RETV curl_dbg_send(SEND_TYPE_ARG1 sockfd, + SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf, + SEND_TYPE_ARG3 len, + SEND_TYPE_ARG4 flags, int line, + const char *source); +CURL_EXTERN RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd, + RECV_TYPE_ARG2 buf, + RECV_TYPE_ARG3 len, + RECV_TYPE_ARG4 flags, int line, + const char *source); + +/* FILE functions */ +CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source); +CURL_EXTERN ALLOC_FUNC + FILE *curl_dbg_fopen(const char *file, const char *mode, + int line, const char *source); +CURL_EXTERN ALLOC_FUNC + FILE *curl_dbg_fdopen(int filedes, const char *mode, + int line, const char *source); + +#define sclose(sockfd) curl_dbg_sclose(sockfd,__LINE__,__FILE__) +#define fake_sclose(sockfd) curl_dbg_mark_sclose(sockfd,__LINE__,__FILE__) + #define CURL_GETADDRINFO(host,serv,hint,res) \ curl_dbg_getaddrinfo(host, serv, hint, res, __LINE__, __FILE__) #define CURL_FREEADDRINFO(data) \ curl_dbg_freeaddrinfo(data, __LINE__, __FILE__) -#else + +#else /* !CURLDEBUG */ + +#define sclose(x) CURL_SCLOSE(x) +#define fake_sclose(x) Curl_nop_stmt + #define CURL_GETADDRINFO getaddrinfo #define CURL_FREEADDRINFO freeaddrinfo -#endif + +#endif /* CURLDEBUG */ /* Some versions of the Android NDK is missing the declaration */ #if defined(HAVE_GETPWUID_R) && \ @@ -1006,7 +1116,7 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, #if (defined(USE_NGTCP2) && defined(USE_NGHTTP3)) || \ (defined(USE_OPENSSL_QUIC) && defined(USE_NGHTTP3)) || \ - defined(USE_QUICHE) || defined(USE_MSH3) + defined(USE_QUICHE) #ifdef CURL_WITH_MULTI_SSL #error "MultiSSL combined with QUIC is not supported" @@ -1015,6 +1125,11 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, #define USE_HTTP3 #endif +/* WebAssembly builds have TCP_NODELAY, but runtime support is missing. */ +#ifndef __EMSCRIPTEN__ +#define CURL_TCP_NODELAY_SUPPORTED +#endif + /* Certain Windows implementations are not aligned with what curl expects, so always use the local one on this platform. E.g. the mingw-w64 implementation can return wrong results for non-ASCII inputs. */ @@ -1023,7 +1138,7 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, #endif #if defined(USE_UNIX_SOCKETS) && defined(_WIN32) -# if !defined(UNIX_PATH_MAX) +# ifndef UNIX_PATH_MAX /* Replicating logic present in afunix.h (distributed with newer Windows 10 SDK versions only) */ # define UNIX_PATH_MAX 108 @@ -1071,3 +1186,5 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, #endif #endif /* HEADER_CURL_SETUP_H */ + +#include "curl_mem_undef.h" diff --git a/vendor/curl/lib/curl_setup_once.h b/vendor/curl/lib/curl_setup_once.h index c1051e0faef..642e1487c8a 100644 --- a/vendor/curl/lib/curl_setup_once.h +++ b/vendor/curl/lib/curl_setup_once.h @@ -41,11 +41,9 @@ #include #endif -#ifdef HAVE_SYS_STAT_H #include -#endif -#ifdef HAVE_SYS_TIME_H +#if !defined(_WIN32) || defined(__MINGW32__) #include #endif @@ -96,7 +94,7 @@ # endif #endif -#ifdef HAVE_SYS_SOCKET_H +#ifndef _WIN32 #include #endif @@ -197,15 +195,15 @@ struct timeval { */ #ifdef HAVE_CLOSESOCKET -# define sclose(x) closesocket((x)) +# define CURL_SCLOSE(x) closesocket((x)) #elif defined(HAVE_CLOSESOCKET_CAMEL) -# define sclose(x) CloseSocket((x)) +# define CURL_SCLOSE(x) CloseSocket((x)) #elif defined(MSDOS) /* Watt-32 */ -# define sclose(x) close_s((x)) +# define CURL_SCLOSE(x) close_s((x)) #elif defined(USE_LWIPSOCK) -# define sclose(x) lwip_close((x)) +# define CURL_SCLOSE(x) lwip_close((x)) #else -# define sclose(x) close((x)) +# define CURL_SCLOSE(x) close((x)) #endif /* diff --git a/vendor/curl/lib/curl_sha256.h b/vendor/curl/lib/curl_sha256.h index f532939d056..caa5080b3f0 100644 --- a/vendor/curl/lib/curl_sha256.h +++ b/vendor/curl/lib/curl_sha256.h @@ -25,8 +25,8 @@ * ***************************************************************************/ -#if !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) \ - || defined(USE_LIBSSH2) || defined(USE_SSL) +#if !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) || \ + defined(USE_LIBSSH2) || defined(USE_SSL) #include #include "curl_hmac.h" diff --git a/vendor/curl/lib/curl_sha512_256.c b/vendor/curl/lib/curl_sha512_256.c index 2d8a23f19a7..6c39967d2b9 100644 --- a/vendor/curl/lib/curl_sha512_256.c +++ b/vendor/curl/lib/curl_sha512_256.c @@ -34,13 +34,11 @@ * * GnuTLS * * wolfSSL * * Schannel SSPI - * * Secure Transport (Darwin) * * mbedTLS - * * BearSSL * * Rustls * Skip the backend if it does not support the required algorithm */ -#if defined(USE_OPENSSL) +#ifdef USE_OPENSSL # include # if (!defined(LIBRESSL_VERSION_NUMBER) && \ defined(OPENSSL_VERSION_NUMBER) && \ @@ -80,12 +78,12 @@ #if !defined(HAS_SHA512_256_IMPLEMENTATION) && defined(USE_GNUTLS) # include -# if defined(SHA512_256_DIGEST_SIZE) +# ifdef SHA512_256_DIGEST_SIZE # define USE_GNUTLS_SHA512_256 1 # endif #endif /* ! HAS_SHA512_256_IMPLEMENTATION && USE_GNUTLS */ -#if defined(USE_OPENSSL_SHA512_256) +#ifdef USE_OPENSSL_SHA512_256 /* OpenSSL does not provide macros for SHA-512/256 sizes */ @@ -112,8 +110,7 @@ typedef EVP_MD_CTX *Curl_sha512_256_ctx; * @return CURLE_OK if succeed, * error code otherwise */ -static CURLcode -Curl_sha512_256_init(void *context) +static CURLcode Curl_sha512_256_init(void *context) { Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context; @@ -144,10 +141,9 @@ Curl_sha512_256_init(void *context) * @return CURLE_OK if succeed, * error code otherwise */ -static CURLcode -Curl_sha512_256_update(void *context, - const unsigned char *data, - size_t length) +static CURLcode Curl_sha512_256_update(void *context, + const unsigned char *data, + size_t length) { Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context; @@ -167,9 +163,7 @@ Curl_sha512_256_update(void *context, * @return CURLE_OK if succeed, * error code otherwise */ -static CURLcode -Curl_sha512_256_finish(unsigned char *digest, - void *context) +static CURLcode Curl_sha512_256_finish(unsigned char *digest, void *context) { CURLcode ret; Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context; @@ -209,8 +203,7 @@ typedef struct sha512_256_ctx Curl_sha512_256_ctx; * @param context the calculation context * @return always CURLE_OK */ -static CURLcode -Curl_sha512_256_init(void *context) +static CURLcode Curl_sha512_256_init(void *context) { Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context; @@ -231,10 +224,9 @@ Curl_sha512_256_init(void *context) * @param length number of bytes in @a data * @return always CURLE_OK */ -static CURLcode -Curl_sha512_256_update(void *context, - const unsigned char *data, - size_t length) +static CURLcode Curl_sha512_256_update(void *context, + const unsigned char *data, + size_t length) { Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context; @@ -254,9 +246,8 @@ Curl_sha512_256_update(void *context, # bytes * @return always CURLE_OK */ -static CURLcode -Curl_sha512_256_finish(unsigned char *digest, - void *context) +static CURLcode Curl_sha512_256_finish(unsigned char *digest, + void *context) { Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context; @@ -286,13 +277,13 @@ Curl_sha512_256_finish(unsigned char *digest, #if !defined(CURL_FORCEINLINE) && \ defined(_MSC_VER) && !defined(__GNUC__) && !defined(__clang__) -# define CURL_FORCEINLINE __forceinline +#define CURL_FORCEINLINE __forceinline #endif -#if !defined(CURL_FORCEINLINE) - /* Assume that 'CURL_INLINE' keyword works or the - * macro was already defined correctly. */ -# define CURL_FORCEINLINE CURL_INLINE +/* Assume that 'CURL_INLINE' keyword works or the + * macro was already defined correctly. */ +#ifndef CURL_FORCEINLINE +#define CURL_FORCEINLINE CURL_INLINE #endif /* Bits manipulation macros and functions. @@ -322,11 +313,11 @@ Curl_sha512_256_finish(unsigned char *digest, /* Defined as a function. The macro version may duplicate the binary code * size as each argument is used twice, so if any calculation is used * as an argument, the calculation could be done twice. */ -static CURL_FORCEINLINE curl_uint64_t -Curl_rotr64(curl_uint64_t value, unsigned int bits) +static CURL_FORCEINLINE curl_uint64_t Curl_rotr64(curl_uint64_t value, + unsigned int bits) { bits %= 64; - if(0 == bits) + if(bits == 0) return value; /* Defined in a form which modern compiler could optimize. */ return (value >> bits) | (value << (64 - bits)); @@ -382,8 +373,7 @@ Curl_rotr64(curl_uint64_t value, unsigned int bits) /** * SHA-512/256 calculation context */ -struct Curl_sha512_256ctx -{ +struct Curl_sha512_256ctx { /** * Intermediate hash value. The variable is properly aligned. Smart * compilers may automatically use fast load/store instruction for big @@ -419,8 +409,7 @@ typedef struct Curl_sha512_256ctx Curl_sha512_256_ctx; * @param context the calculation context * @return always CURLE_OK */ -static CURLcode -Curl_sha512_256_init(void *context) +static CURLcode Curl_sha512_256_init(void *context) { struct Curl_sha512_256ctx *const ctx = (struct Curl_sha512_256ctx *)context; @@ -455,9 +444,9 @@ Curl_sha512_256_init(void *context) * @param H hash values * @param data the data buffer with #CURL_SHA512_256_BLOCK_SIZE bytes block */ -static void -Curl_sha512_256_transform(curl_uint64_t H[SHA512_256_HASH_SIZE_WORDS], - const void *data) +static +void Curl_sha512_256_transform(curl_uint64_t H[SHA512_256_HASH_SIZE_WORDS], + const void *data) { /* Working variables, see FIPS PUB 180-4 section 6.7, 6.4. */ @@ -621,10 +610,9 @@ Curl_sha512_256_transform(curl_uint64_t H[SHA512_256_HASH_SIZE_WORDS], * @param length number of bytes in @a data * @return always CURLE_OK */ -static CURLcode -Curl_sha512_256_update(void *context, - const unsigned char *data, - size_t length) +static CURLcode Curl_sha512_256_update(void *context, + const unsigned char *data, + size_t length) { unsigned int bytes_have; /**< Number of bytes in the context buffer */ struct Curl_sha512_256ctx *const ctx = (struct Curl_sha512_256ctx *)context; @@ -633,7 +621,7 @@ Curl_sha512_256_update(void *context, DEBUGASSERT((data != NULL) || (length == 0)); - if(0 == length) + if(length == 0) return CURLE_OK; /* Shortcut, do nothing */ /* Note: (count & (CURL_SHA512_256_BLOCK_SIZE-1)) @@ -645,7 +633,7 @@ Curl_sha512_256_update(void *context, ctx->count_bits_hi += ctx->count >> 61; ctx->count &= CURL_UINT64_C(0x1FFFFFFFFFFFFFFF); - if(0 != bytes_have) { + if(bytes_have) { unsigned int bytes_left = CURL_SHA512_256_BLOCK_SIZE - bytes_have; if(length >= bytes_left) { /* Combine new data with data in the buffer and process the full @@ -668,7 +656,7 @@ Curl_sha512_256_update(void *context, length -= CURL_SHA512_256_BLOCK_SIZE; } - if(0 != length) { + if(length) { /* Copy incomplete block of new data (if any) to the buffer. */ memcpy(((unsigned char *) ctx_buf) + bytes_have, data, length); @@ -698,9 +686,7 @@ Curl_sha512_256_update(void *context, # bytes * @return always CURLE_OK */ -static CURLcode -Curl_sha512_256_finish(unsigned char *digest, - void *context) +static CURLcode Curl_sha512_256_finish(unsigned char *digest, void *context) { struct Curl_sha512_256ctx *const ctx = (struct Curl_sha512_256ctx *)context; curl_uint64_t num_bits; /**< Number of processed bits */ @@ -748,14 +734,14 @@ Curl_sha512_256_finish(unsigned char *digest, part of number of bits as big-endian values. See FIPS PUB 180-4 section 5.1.2. */ /* Note: the target location is predefined and buffer is always aligned */ - CURL_PUT_64BIT_BE(((unsigned char *) ctx_buf) \ + CURL_PUT_64BIT_BE(((unsigned char *) ctx_buf) \ + CURL_SHA512_256_BLOCK_SIZE \ - SHA512_256_SIZE_OF_LEN_ADD, \ ctx->count_bits_hi); - CURL_PUT_64BIT_BE(((unsigned char *) ctx_buf) \ - + CURL_SHA512_256_BLOCK_SIZE \ - - SHA512_256_SIZE_OF_LEN_ADD \ - + SHA512_256_BYTES_IN_WORD, \ + CURL_PUT_64BIT_BE(((unsigned char *) ctx_buf) \ + + CURL_SHA512_256_BLOCK_SIZE \ + - SHA512_256_SIZE_OF_LEN_ADD \ + + SHA512_256_BYTES_IN_WORD, \ num_bits); /* Process the full final block. */ Curl_sha512_256_transform(ctx->H, ctx->buffer); @@ -784,9 +770,8 @@ Curl_sha512_256_finish(unsigned char *digest, * @param input_size the size of the data pointed by @a input * @return always #CURLE_OK */ -CURLcode -Curl_sha512_256it(unsigned char *output, const unsigned char *input, - size_t input_size) +CURLcode Curl_sha512_256it(unsigned char *output, const unsigned char *input, + size_t input_size) { Curl_sha512_256_ctx ctx; CURLcode res; @@ -798,7 +783,7 @@ Curl_sha512_256it(unsigned char *output, const unsigned char *input, res = Curl_sha512_256_update(&ctx, (const void *) input, input_size); if(res != CURLE_OK) { - (void) Curl_sha512_256_finish(output, &ctx); + (void)Curl_sha512_256_finish(output, &ctx); return res; } @@ -806,22 +791,19 @@ Curl_sha512_256it(unsigned char *output, const unsigned char *input, } /* Wrapper function, takes 'unsigned int' as length type, returns void */ -static void -Curl_sha512_256_update_i(void *context, - const unsigned char *data, - unsigned int length) +static void Curl_sha512_256_update_i(void *context, + const unsigned char *data, + unsigned int length) { /* Hypothetically the function may fail, but assume it does not */ - (void) Curl_sha512_256_update(context, data, length); + (void)Curl_sha512_256_update(context, data, length); } /* Wrapper function, returns void */ -static void -Curl_sha512_256_finish_v(unsigned char *result, - void *context) +static void Curl_sha512_256_finish_v(unsigned char *result, void *context) { /* Hypothetically the function may fail, but assume it does not */ - (void) Curl_sha512_256_finish(result, context); + (void)Curl_sha512_256_finish(result, context); } /* Wrapper function, takes 'unsigned int' as length type, returns void */ diff --git a/vendor/curl/lib/curl_sspi.c b/vendor/curl/lib/curl_sspi.c index cd577e8a5e2..635f560b68a 100644 --- a/vendor/curl/lib/curl_sspi.c +++ b/vendor/curl/lib/curl_sspi.c @@ -28,32 +28,15 @@ #include #include "curl_sspi.h" +#include "strdup.h" #include "curlx/multibyte.h" #include "system_win32.h" -#include "curlx/version_win32.h" #include "curlx/warnless.h" /* The last #include files should be: */ #include "curl_memory.h" #include "memdebug.h" -/* We use our own typedef here since some headers might lack these */ -typedef PSecurityFunctionTable (APIENTRY *INITSECURITYINTERFACE_FN)(VOID); - -/* See definition of SECURITY_ENTRYPOINT in sspi.h */ -#ifdef UNICODE -# ifdef UNDER_CE -# define SECURITYENTRYPOINT L"InitSecurityInterfaceW" -# else -# define SECURITYENTRYPOINT "InitSecurityInterfaceW" -# endif -#else -# define SECURITYENTRYPOINT "InitSecurityInterfaceA" -#endif - -/* Handle of security.dll or secur32.dll, depending on Windows version */ -HMODULE Curl_hSecDll = NULL; - /* Pointer to SSPI dispatch table */ PSecurityFunctionTable Curl_pSecFn = NULL; @@ -76,31 +59,14 @@ PSecurityFunctionTable Curl_pSecFn = NULL; */ CURLcode Curl_sspi_global_init(void) { - INITSECURITYINTERFACE_FN pInitSecurityInterface; - /* If security interface is not yet initialized try to do this */ - if(!Curl_hSecDll) { - /* Security Service Provider Interface (SSPI) functions are located in - * security.dll on WinNT 4.0 and in secur32.dll on Win9x. Win2K and XP - * have both these DLLs (security.dll forwards calls to secur32.dll) */ - - /* Load SSPI dll into the address space of the calling process */ - if(curlx_verify_windows_version(4, 0, 0, PLATFORM_WINNT, VERSION_EQUAL)) - Curl_hSecDll = Curl_load_library(TEXT("security.dll")); - else - Curl_hSecDll = Curl_load_library(TEXT("secur32.dll")); - if(!Curl_hSecDll) - return CURLE_FAILED_INIT; - - /* Get address of the InitSecurityInterfaceA function from the SSPI dll */ - pInitSecurityInterface = - CURLX_FUNCTION_CAST(INITSECURITYINTERFACE_FN, - (GetProcAddress(Curl_hSecDll, SECURITYENTRYPOINT))); - if(!pInitSecurityInterface) - return CURLE_FAILED_INIT; - + if(!Curl_pSecFn) { /* Get pointer to Security Service Provider Interface dispatch table */ - Curl_pSecFn = pInitSecurityInterface(); +#ifdef __MINGW32CE__ + Curl_pSecFn = InitSecurityInterfaceW(); +#else + Curl_pSecFn = InitSecurityInterface(); +#endif if(!Curl_pSecFn) return CURLE_FAILED_INIT; } @@ -119,9 +85,7 @@ CURLcode Curl_sspi_global_init(void) */ void Curl_sspi_global_cleanup(void) { - if(Curl_hSecDll) { - FreeLibrary(Curl_hSecDll); - Curl_hSecDll = NULL; + if(Curl_pSecFn) { Curl_pSecFn = NULL; } } @@ -213,7 +177,12 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp, curlx_unicodefree(passwd.tchar_ptr); /* Setup the identity's flags */ - identity->Flags = SECFLAG_WINNT_AUTH_IDENTITY; + identity->Flags = (unsigned long) +#ifdef UNICODE + SEC_WINNT_AUTH_IDENTITY_UNICODE; +#else + SEC_WINNT_AUTH_IDENTITY_ANSI; +#endif return CURLE_OK; } diff --git a/vendor/curl/lib/curl_sspi.h b/vendor/curl/lib/curl_sspi.h index 8fdf8ef2496..8ecd81fdea1 100644 --- a/vendor/curl/lib/curl_sspi.h +++ b/vendor/curl/lib/curl_sspi.h @@ -57,7 +57,6 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp, void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity); /* Forward-declaration of global variables defined in curl_sspi.c */ -extern HMODULE Curl_hSecDll; extern PSecurityFunctionTable Curl_pSecFn; /* Provide some definitions missing in old headers */ @@ -66,6 +65,7 @@ extern PSecurityFunctionTable Curl_pSecFn; #define SP_NAME_NEGOTIATE "Negotiate" #define SP_NAME_KERBEROS "Kerberos" +/* Offered by mingw-w64 v9+. MS SDK 7.0A+. */ #ifndef ISC_REQ_USE_HTTP_STYLE #define ISC_REQ_USE_HTTP_STYLE 0x01000000 #endif @@ -289,14 +289,17 @@ extern PSecurityFunctionTable Curl_pSecFn; #define SEC_E_KDC_CERT_REVOKED ((HRESULT)0x8009035BL) #endif #endif /* __MINGW32CE__ */ +/* Offered by mingw-w64 v8+. MS SDK 6.0A+. */ #ifndef SEC_E_INVALID_PARAMETER -# define SEC_E_INVALID_PARAMETER ((HRESULT)0x8009035DL) +#define SEC_E_INVALID_PARAMETER ((HRESULT)0x8009035DL) #endif +/* Offered by mingw-w64 v8+. MS SDK 6.0A+. */ #ifndef SEC_E_DELEGATION_POLICY -# define SEC_E_DELEGATION_POLICY ((HRESULT)0x8009035EL) +#define SEC_E_DELEGATION_POLICY ((HRESULT)0x8009035EL) #endif +/* Offered by mingw-w64 v8+. MS SDK 6.0A+. */ #ifndef SEC_E_POLICY_NLTM_ONLY -# define SEC_E_POLICY_NLTM_ONLY ((HRESULT)0x8009035FL) +#define SEC_E_POLICY_NLTM_ONLY ((HRESULT)0x8009035FL) #endif #ifdef __MINGW32CE__ @@ -325,37 +328,17 @@ extern PSecurityFunctionTable Curl_pSecFn; #define SEC_I_NO_LSA_CONTEXT ((HRESULT)0x00090323L) #endif #endif /* __MINGW32CE__ */ + +/* Offered by mingw-w64 v8+. MS SDK 6.0A+. */ #ifndef SEC_I_SIGNATURE_NEEDED #define SEC_I_SIGNATURE_NEEDED ((HRESULT)0x0009035CL) #endif -#ifndef CRYPT_E_REVOKED -#define CRYPT_E_REVOKED ((HRESULT)0x80092010L) -#endif - -#ifndef CRYPT_E_NO_REVOCATION_DLL -#define CRYPT_E_NO_REVOCATION_DLL ((HRESULT)0x80092011L) -#endif - -#ifndef CRYPT_E_NO_REVOCATION_CHECK -#define CRYPT_E_NO_REVOCATION_CHECK ((HRESULT)0x80092012L) -#endif - -#ifndef CRYPT_E_REVOCATION_OFFLINE -#define CRYPT_E_REVOCATION_OFFLINE ((HRESULT)0x80092013L) -#endif - +#ifdef __MINGW32CE__ #ifndef CRYPT_E_NOT_IN_REVOCATION_DATABASE #define CRYPT_E_NOT_IN_REVOCATION_DATABASE ((HRESULT)0x80092014L) #endif - -#ifdef UNICODE -# define SECFLAG_WINNT_AUTH_IDENTITY \ - (unsigned long)SEC_WINNT_AUTH_IDENTITY_UNICODE -#else -# define SECFLAG_WINNT_AUTH_IDENTITY \ - (unsigned long)SEC_WINNT_AUTH_IDENTITY_ANSI -#endif +#endif /* __MINGW32CE__ */ /* * Definitions required from ntsecapi.h are directly provided below this point diff --git a/vendor/curl/lib/curl_threads.c b/vendor/curl/lib/curl_threads.c index eae75440161..bb2e026cbeb 100644 --- a/vendor/curl/lib/curl_threads.c +++ b/vendor/curl/lib/curl_threads.c @@ -26,7 +26,7 @@ #include -#if defined(USE_THREADS_POSIX) +#ifdef USE_THREADS_POSIX # ifdef HAVE_PTHREAD_H # include # endif @@ -39,7 +39,7 @@ /* The last #include file should be: */ #include "memdebug.h" -#if defined(USE_THREADS_POSIX) +#ifdef USE_THREADS_POSIX struct Curl_actual_call { unsigned int (*func)(void *); @@ -59,7 +59,8 @@ static void *curl_thread_create_thunk(void *arg) return 0; } -curl_thread_t Curl_thread_create(unsigned int (*func) (void *), void *arg) +curl_thread_t Curl_thread_create(CURL_THREAD_RETURN_T + (CURL_STDCALL *func) (void *), void *arg) { curl_thread_t t = malloc(sizeof(pthread_t)); struct Curl_actual_call *ac = malloc(sizeof(struct Curl_actual_call)); @@ -101,14 +102,8 @@ int Curl_thread_join(curl_thread_t *hnd) #elif defined(USE_THREADS_WIN32) -curl_thread_t Curl_thread_create( -#if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE) - DWORD -#else - unsigned int -#endif - (CURL_STDCALL *func) (void *), - void *arg) +curl_thread_t Curl_thread_create(CURL_THREAD_RETURN_T + (CURL_STDCALL *func) (void *), void *arg) { #if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE) typedef HANDLE curl_win_thread_handle_t; @@ -147,8 +142,7 @@ void Curl_thread_destroy(curl_thread_t *hnd) int Curl_thread_join(curl_thread_t *hnd) { -#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \ - (_WIN32_WINNT < _WIN32_WINNT_VISTA) +#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < _WIN32_WINNT_VISTA) int ret = (WaitForSingleObject(*hnd, INFINITE) == WAIT_OBJECT_0); #else int ret = (WaitForSingleObjectEx(*hnd, INFINITE, FALSE) == WAIT_OBJECT_0); diff --git a/vendor/curl/lib/curl_threads.h b/vendor/curl/lib/curl_threads.h index b060d4acd3e..82f08c5fbb5 100644 --- a/vendor/curl/lib/curl_threads.h +++ b/vendor/curl/lib/curl_threads.h @@ -25,7 +25,7 @@ ***************************************************************************/ #include "curl_setup.h" -#if defined(USE_THREADS_POSIX) +#ifdef USE_THREADS_POSIX # define CURL_STDCALL # define curl_mutex_t pthread_mutex_t # define curl_thread_t pthread_t * @@ -39,8 +39,7 @@ # define curl_mutex_t CRITICAL_SECTION # define curl_thread_t HANDLE # define curl_thread_t_null (HANDLE)0 -# if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \ - (_WIN32_WINNT < _WIN32_WINNT_VISTA) +# if !defined(_WIN32_WINNT) || (_WIN32_WINNT < _WIN32_WINNT_VISTA) # define Curl_mutex_init(m) InitializeCriticalSection(m) # else # define Curl_mutex_init(m) InitializeCriticalSectionEx(m, 0, 1) @@ -48,18 +47,20 @@ # define Curl_mutex_acquire(m) EnterCriticalSection(m) # define Curl_mutex_release(m) LeaveCriticalSection(m) # define Curl_mutex_destroy(m) DeleteCriticalSection(m) +#else +# define CURL_STDCALL #endif -#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) - -curl_thread_t Curl_thread_create( #if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE) - DWORD +#define CURL_THREAD_RETURN_T DWORD #else - unsigned int +#define CURL_THREAD_RETURN_T unsigned int #endif - (CURL_STDCALL *func) (void *), - void *arg); + +#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) + +curl_thread_t Curl_thread_create(CURL_THREAD_RETURN_T + (CURL_STDCALL *func) (void *), void *arg); void Curl_thread_destroy(curl_thread_t *hnd); diff --git a/vendor/curl/lib/curl_trc.c b/vendor/curl/lib/curl_trc.c index 566cdc533e2..8c01eff1424 100644 --- a/vendor/curl/lib/curl_trc.c +++ b/vendor/curl/lib/curl_trc.c @@ -31,7 +31,6 @@ #include "easyif.h" #include "cfilters.h" #include "multiif.h" -#include "strcase.h" #include "cf-socket.h" #include "connect.h" @@ -42,6 +41,7 @@ #include "cf-h2-proxy.h" #include "cf-haproxy.h" #include "cf-https-connect.h" +#include "cf-ip-happy.h" #include "socks.h" #include "curlx/strparse.h" #include "vtls/vtls.h" @@ -162,10 +162,12 @@ void Curl_debug(struct Curl_easy *data, curl_infotype type, case CURLINFO_TEXT: case CURLINFO_HEADER_OUT: case CURLINFO_HEADER_IN: +#ifndef CURL_DISABLE_VERBOSE_STRINGS if(CURL_TRC_IDS(data)) { len = trc_print_ids(data, buf, TRC_LINE_MAX); fwrite(buf, len, 1, data->set.err); } +#endif fwrite(s_infotype[type], 2, 1, data->set.err); fwrite(ptr, size, 1, data->set.err); break; @@ -200,13 +202,12 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...) } } -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) - +#ifndef CURL_DISABLE_VERBOSE_STRINGS static void trc_infof(struct Curl_easy *data, struct curl_trc_feat *feat, const char *opt_id, int opt_id_idx, - const char * const fmt, va_list ap) CURL_PRINTF(5, 0); + const char * const fmt, va_list ap) CURL_PRINTF(5, 0); static void trc_infof(struct Curl_easy *data, struct curl_trc_feat *feat, @@ -462,9 +463,9 @@ static struct trc_cft_def trc_cfts[] = { { &Curl_cft_udp, TRC_CT_NETWORK }, { &Curl_cft_unix, TRC_CT_NETWORK }, { &Curl_cft_tcp_accept, TRC_CT_NETWORK }, - { &Curl_cft_happy_eyeballs, TRC_CT_NETWORK }, + { &Curl_cft_ip_happy, TRC_CT_NETWORK }, { &Curl_cft_setup, TRC_CT_PROTOCOL }, -#ifdef USE_NGHTTP2 +#if !defined(CURL_DISABLE_HTTP) && defined(USE_NGHTTP2) { &Curl_cft_nghttp2, TRC_CT_PROTOCOL }, #endif #ifdef USE_SSL @@ -473,8 +474,8 @@ static struct trc_cft_def trc_cfts[] = { { &Curl_cft_ssl_proxy, TRC_CT_PROXY }, #endif #endif -#if !defined(CURL_DISABLE_PROXY) -#if !defined(CURL_DISABLE_HTTP) +#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_HTTP { &Curl_cft_h1_proxy, TRC_CT_PROXY }, #ifdef USE_NGHTTP2 { &Curl_cft_h2_proxy, TRC_CT_PROXY }, @@ -484,10 +485,10 @@ static struct trc_cft_def trc_cfts[] = { { &Curl_cft_haproxy, TRC_CT_PROXY }, { &Curl_cft_socks_proxy, TRC_CT_PROXY }, #endif /* !CURL_DISABLE_PROXY */ -#ifdef USE_HTTP3 +#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP3) { &Curl_cft_http3, TRC_CT_PROTOCOL }, #endif -#if !defined(CURL_DISABLE_HTTP) +#ifndef CURL_DISABLE_HTTP { &Curl_cft_http_connect, TRC_CT_PROTOCOL }, #endif }; @@ -582,7 +583,7 @@ CURLcode Curl_trc_init(void) #endif } -#else /* defined(CURL_DISABLE_VERBOSE_STRINGS) */ +#else /* CURL_DISABLE_VERBOSE_STRINGS */ CURLcode Curl_trc_init(void) { @@ -634,17 +635,18 @@ void Curl_trc_smtp(struct Curl_easy *data, const char *fmt, ...) (void)data; (void)fmt; } #endif -#if !defined(CURL_DISABLE_WEBSOCKETS) || !defined(CURL_DISABLE_HTTP) +#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP) void Curl_trc_ws(struct Curl_easy *data, const char *fmt, ...) { (void)data; (void)fmt; } #endif - +#ifdef USE_SSL void Curl_trc_ssls(struct Curl_easy *data, const char *fmt, ...) { (void)data; (void)fmt; } +#endif -#endif /* !defined(CURL_DISABLE_VERBOSE_STRINGS) */ +#endif /* !CURL_DISABLE_VERBOSE_STRINGS */ diff --git a/vendor/curl/lib/curl_trc.h b/vendor/curl/lib/curl_trc.h index ed7e5d89f00..6db1496c770 100644 --- a/vendor/curl/lib/curl_trc.h +++ b/vendor/curl/lib/curl_trc.h @@ -203,7 +203,7 @@ extern struct curl_trc_feat Curl_trc_feat_dns; (ft)->log_level >= CURL_LOG_LVL_INFO) #define CURL_MSTATE_NAME(s) Curl_trc_mstate_name((int)(s)) -#else /* defined(CURL_DISABLE_VERBOSE_STRINGS) */ +#else /* CURL_DISABLE_VERBOSE_STRINGS */ /* All informational messages are not compiled in for size savings */ #define Curl_trc_is_verbose(d) (FALSE) @@ -211,6 +211,6 @@ extern struct curl_trc_feat Curl_trc_feat_dns; #define Curl_trc_ft_is_verbose(x,y) (FALSE) #define CURL_MSTATE_NAME(x) ((void)(x), "-") -#endif /* !defined(CURL_DISABLE_VERBOSE_STRINGS) */ +#endif /* !CURL_DISABLE_VERBOSE_STRINGS */ #endif /* HEADER_CURL_TRC_H */ diff --git a/vendor/curl/lib/curlx/base64.c b/vendor/curl/lib/curlx/base64.c index 92ebc57e1e6..dc6e9c001ce 100644 --- a/vendor/curl/lib/curlx/base64.c +++ b/vendor/curl/lib/curlx/base64.c @@ -26,13 +26,6 @@ #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_DIGEST_AUTH) || \ - !defined(CURL_DISABLE_DOH) || defined(USE_SSL) || !defined(BUILDING_LIBCURL) #include #include "warnless.h" #include "base64.h" @@ -281,5 +274,3 @@ CURLcode curlx_base64url_encode(const char *inputbuff, size_t insize, { return base64_encode(base64url, 0, inputbuff, insize, outptr, outlen); } - -#endif /* no users so disabled */ diff --git a/vendor/curl/lib/curlx/binmode.h b/vendor/curl/lib/curlx/binmode.h new file mode 100644 index 00000000000..3f356edd597 --- /dev/null +++ b/vendor/curl/lib/curlx/binmode.h @@ -0,0 +1,39 @@ +#ifndef HEADER_CURL_TOOL_BINMODE_H +#define HEADER_CURL_TOOL_BINMODE_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(HAVE_SETMODE) || defined(HAVE__SETMODE)) && defined(O_BINARY) +/* Requires io.h and/or fcntl.h when available */ +#ifdef HAVE__SETMODE +# define CURLX_SET_BINMODE(stream) (void)_setmode(fileno(stream), O_BINARY) +#else +# define CURLX_SET_BINMODE(stream) (void)setmode(fileno(stream), O_BINARY) +#endif +#else +# define CURLX_SET_BINMODE(stream) (void)stream; Curl_nop_stmt +#endif + +#endif /* HEADER_CURL_TOOL_BINMODE_H */ diff --git a/vendor/curl/lib/curlx/curlx.h b/vendor/curl/lib/curlx/curlx.h index 983c7b5c75b..9f7bd3a975e 100644 --- a/vendor/curl/lib/curlx/curlx.h +++ b/vendor/curl/lib/curlx/curlx.h @@ -31,6 +31,9 @@ * be. */ +#include "binmode.h" +/* "binmode.h" provides macro CURLX_SET_BINMODE() */ + #include "nonblock.h" /* "nonblock.h" provides curlx_nonblock() */ @@ -65,10 +68,16 @@ #include "timeval.h" #include "timediff.h" +#include "wait.h" +/* for curlx_wait_ms */ + #include "winapi.h" /* for curlx_winapi_strerror */ #include "inet_pton.h" /* for curlx_inet_pton */ +#include "inet_ntop.h" +/* for curlx_inet_ntop */ + #endif /* HEADER_CURL_CURLX_H */ diff --git a/vendor/curl/lib/curlx/dynbuf.c b/vendor/curl/lib/curlx/dynbuf.c index 0b8dfe8e34f..447203e42a8 100644 --- a/vendor/curl/lib/curlx/dynbuf.c +++ b/vendor/curl/lib/curlx/dynbuf.c @@ -71,14 +71,14 @@ void curlx_dyn_free(struct dynbuf *s) static CURLcode dyn_nappend(struct dynbuf *s, const unsigned char *mem, size_t len) { - size_t indx = s->leng; + size_t idx = s->leng; size_t a = s->allc; - size_t fit = len + indx + 1; /* new string + old string + zero byte */ + size_t fit = len + idx + 1; /* new string + old string + zero byte */ /* try to detect if there is rubbish in the struct */ DEBUGASSERT(s->init == DYNINIT); DEBUGASSERT(s->toobig); - DEBUGASSERT(indx < s->toobig); + DEBUGASSERT(idx < s->toobig); DEBUGASSERT(!s->leng || s->bufr); DEBUGASSERT(a <= s->toobig); DEBUGASSERT(!len || mem); @@ -88,7 +88,7 @@ static CURLcode dyn_nappend(struct dynbuf *s, return CURLE_TOO_LARGE; } else if(!a) { - DEBUGASSERT(!indx); + DEBUGASSERT(!idx); /* first invoke */ if(MIN_FIRST_ALLOC > s->toobig) a = s->toobig; @@ -118,8 +118,8 @@ static CURLcode dyn_nappend(struct dynbuf *s, } if(len) - memcpy(&s->bufr[indx], mem, len); - s->leng = indx + len; + memcpy(&s->bufr[idx], mem, len); + s->leng = idx + len; s->bufr[s->leng] = 0; return CURLE_OK; } @@ -231,6 +231,7 @@ CURLcode curlx_dyn_addf(struct dynbuf *s, const char *fmt, ...) DEBUGASSERT(s); DEBUGASSERT(s->init == DYNINIT); DEBUGASSERT(!s->leng || s->bufr); + DEBUGASSERT(strcmp(fmt, "%s")); /* use curlx_dyn_add instead */ va_start(ap, fmt); result = curlx_dyn_vaddf(s, fmt, ap); va_end(ap); diff --git a/vendor/curl/lib/curlx/inet_ntop.c b/vendor/curl/lib/curlx/inet_ntop.c new file mode 100644 index 00000000000..3f8bcbf3668 --- /dev/null +++ b/vendor/curl/lib/curlx/inet_ntop.c @@ -0,0 +1,225 @@ +/* + * Copyright (C) 1996-2022 Internet Software Consortium. + * + * 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" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * SPDX-License-Identifier: ISC + */ +/* + * Original code by Paul Vixie. "curlified" by Gisle Vanem. + */ + +#include "../curl_setup.h" + +#ifndef HAVE_INET_NTOP + +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#include "inet_ntop.h" + +#define IN6ADDRSZ 16 +/* #define INADDRSZ 4 */ +#define INT16SZ 2 + +/* + * If USE_IPV6 is disabled, we still want to parse IPv6 addresses, so make + * sure we have _some_ value for AF_INET6 without polluting our fake value + * everywhere. + */ +#if !defined(USE_IPV6) && !defined(AF_INET6) +#define AF_INET6 (AF_INET + 1) +#endif + +/* + * Format an IPv4 address, more or less like inet_ntop(). + * + * Returns `dst' (as a const) + * Note: + * - uses no static variables + * - takes an unsigned char* not an in_addr as input + */ +static char *inet_ntop4(const unsigned char *src, char *dst, size_t size) +{ + char tmp[sizeof("255.255.255.255")]; + size_t len; + + DEBUGASSERT(size >= 16); + + /* this sprintf() does not overflow the buffer. Avoids snprintf to work more + widely. Avoids the msnprintf family to work as a curlx function. */ + (void)(sprintf)(tmp, "%d.%d.%d.%d", + ((int)((unsigned char)src[0])) & 0xff, + ((int)((unsigned char)src[1])) & 0xff, + ((int)((unsigned char)src[2])) & 0xff, + ((int)((unsigned char)src[3])) & 0xff); + + len = strlen(tmp); + if(len == 0 || len >= size) { +#ifdef USE_WINSOCK + CURL_SETERRNO(WSAEINVAL); +#else + CURL_SETERRNO(ENOSPC); +#endif + return NULL; + } + strcpy(dst, tmp); + return dst; +} + +/* + * Convert IPv6 binary address into presentation (printable) format. + */ +static char *inet_ntop6(const unsigned char *src, char *dst, size_t size) +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; + char *tp; + struct { + int base; + int len; + } best, cur; + unsigned int words[IN6ADDRSZ / INT16SZ]; + int i; + + /* Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, '\0', sizeof(words)); + for(i = 0; i < IN6ADDRSZ; i++) + words[i/2] |= ((unsigned int)src[i] << ((1 - (i % 2)) << 3)); + + best.base = -1; + cur.base = -1; + best.len = 0; + cur.len = 0; + + for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + if(words[i] == 0) { + if(cur.base == -1) { + cur.base = i; cur.len = 1; + } + else + cur.len++; + } + else if(cur.base != -1) { + if(best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + if((cur.base != -1) && (best.base == -1 || cur.len > best.len)) + best = cur; + if(best.base != -1 && best.len < 2) + best.base = -1; + /* Format the result. */ + tp = tmp; + for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + /* Are we inside the best run of 0x00's? */ + if(best.base != -1 && i >= best.base && i < (best.base + best.len)) { + if(i == best.base) + *tp++ = ':'; + continue; + } + + /* Are we following an initial run of 0x00s or any real hex? + */ + if(i) + *tp++ = ':'; + + /* Is this address an encapsulated IPv4? + */ + if(i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { + if(!inet_ntop4(src + 12, tp, sizeof(tmp) - (tp - tmp))) { + return NULL; + } + tp += strlen(tp); + break; + } + else { + /* Lower-case digits. Can't use the set from mprintf.c since this + needs to work as a curlx function */ + static const unsigned char ldigits[] = "0123456789abcdef"; + + unsigned int w = words[i]; + /* output lowercase 16bit hex number but ignore leading zeroes */ + if(w & 0xf000) + *tp++ = ldigits[(w & 0xf000) >> 12]; + if(w & 0xff00) + *tp++ = ldigits[(w & 0x0f00) >> 8]; + if(w & 0xfff0) + *tp++ = ldigits[(w & 0x00f0) >> 4]; + *tp++ = ldigits[(w & 0x000f)]; + } + } + + /* Was it a trailing run of 0x00's? + */ + if(best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) + *tp++ = ':'; + *tp++ = '\0'; + + /* Check for overflow, copy, and we are done. + */ + if((size_t)(tp - tmp) > size) { +#ifdef USE_WINSOCK + CURL_SETERRNO(WSAEINVAL); +#else + CURL_SETERRNO(ENOSPC); +#endif + return NULL; + } + strcpy(dst, tmp); + return dst; +} + +/* + * Convert a network format address to presentation format. + * + * Returns pointer to presentation format address (`buf'). + * Returns NULL on error and errno set with the specific + * error, EAFNOSUPPORT or ENOSPC. + * + * On Windows we store the error in the thread errno, not in the Winsock error + * code. This is to avoid losing the actual last Winsock error. When this + * function returns NULL, check errno not SOCKERRNO. + */ +char *curlx_inet_ntop(int af, const void *src, char *buf, size_t size) +{ + switch(af) { + case AF_INET: + return inet_ntop4((const unsigned char *)src, buf, size); + case AF_INET6: + return inet_ntop6((const unsigned char *)src, buf, size); + default: + CURL_SETERRNO(SOCKEAFNOSUPPORT); + return NULL; + } +} +#endif /* HAVE_INET_NTOP */ diff --git a/vendor/curl/lib/curlx/inet_ntop.h b/vendor/curl/lib/curlx/inet_ntop.h new file mode 100644 index 00000000000..490f49e8a19 --- /dev/null +++ b/vendor/curl/lib/curlx/inet_ntop.h @@ -0,0 +1,51 @@ +#ifndef HEADER_CURL_INET_NTOP_H +#define HEADER_CURL_INET_NTOP_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" + +#ifdef HAVE_INET_NTOP +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifndef _WIN32 +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef __AMIGA__ +#define curlx_inet_ntop(af,addr,buf,size) \ + (char *)inet_ntop(af, CURL_UNCONST(addr), (unsigned char *)buf, \ + (curl_socklen_t)(size)) +#else +#define curlx_inet_ntop(af,addr,buf,size) \ + inet_ntop(af, addr, buf, (curl_socklen_t)(size)) +#endif +#else +char *curlx_inet_ntop(int af, const void *addr, char *buf, size_t size); +#endif /* HAVE_INET_NTOP */ + +#endif /* HEADER_CURL_INET_NTOP_H */ diff --git a/vendor/curl/lib/curlx/inet_pton.h b/vendor/curl/lib/curlx/inet_pton.h index a9dc43085f4..a9ad24c9447 100644 --- a/vendor/curl/lib/curlx/inet_pton.h +++ b/vendor/curl/lib/curlx/inet_pton.h @@ -26,13 +26,11 @@ #include "../curl_setup.h" -int curlx_inet_pton(int, const char *, void *); - #ifdef HAVE_INET_PTON #ifdef HAVE_NETINET_IN_H #include #endif -#ifdef HAVE_SYS_SOCKET_H +#ifndef _WIN32 #include #endif #ifdef HAVE_ARPA_INET_H @@ -43,6 +41,8 @@ int curlx_inet_pton(int, const char *, void *); #else #define curlx_inet_pton(x,y,z) inet_pton(x,y,z) #endif -#endif +#else +int curlx_inet_pton(int, const char *, void *); +#endif /* HAVE_INET_PTON */ #endif /* HEADER_CURL_INET_PTON_H */ diff --git a/vendor/curl/lib/curlx/multibyte.h b/vendor/curl/lib/curlx/multibyte.h index 7835fdc3b5e..c60ce258c9b 100644 --- a/vendor/curl/lib/curlx/multibyte.h +++ b/vendor/curl/lib/curlx/multibyte.h @@ -26,14 +26,10 @@ #include "../curl_setup.h" #ifdef _WIN32 - - /* - * MultiByte conversions using Windows kernel32 library. - */ - +/* MultiByte conversions using Windows kernel32 library. */ wchar_t *curlx_convert_UTF8_to_wchar(const char *str_utf8); char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w); -#endif /* _WIN32 */ +#endif /* * Macros curlx_convert_UTF8_to_tchar(), curlx_convert_tchar_to_UTF8() diff --git a/vendor/curl/lib/curlx/nonblock.c b/vendor/curl/lib/curlx/nonblock.c index 409b187f1fd..b944f9546bb 100644 --- a/vendor/curl/lib/curlx/nonblock.c +++ b/vendor/curl/lib/curlx/nonblock.c @@ -46,7 +46,7 @@ int curlx_nonblock(curl_socket_t sockfd, /* operate on this */ int nonblock /* TRUE or FALSE */) { -#if defined(HAVE_FCNTL_O_NONBLOCK) +#ifdef HAVE_FCNTL_O_NONBLOCK /* most recent Unix versions */ int flags; flags = sfcntl(sockfd, F_GETFL, 0); diff --git a/vendor/curl/lib/curlx/strparse.c b/vendor/curl/lib/curlx/strparse.c index b8b2a14d3cb..ecdf5b96153 100644 --- a/vendor/curl/lib/curlx/strparse.c +++ b/vendor/curl/lib/curlx/strparse.c @@ -23,7 +23,10 @@ ***************************************************************************/ #include "strparse.h" -#include "../strcase.h" + +#ifndef WITHOUT_LIBCURL +#include /* for curl_strnequal() */ +#endif void curlx_str_init(struct Curl_str *out) { @@ -40,7 +43,7 @@ void curlx_str_assign(struct Curl_str *out, const char *str, size_t len) /* Get a word until the first DELIM or end of string. At least one byte long. return non-zero on error */ int curlx_str_until(const char **linep, struct Curl_str *out, - const size_t max, char delim) + const size_t max, char delim) { const char *s = *linep; size_t len = 0; @@ -64,7 +67,7 @@ int curlx_str_until(const char **linep, struct Curl_str *out, /* Get a word until the first space or end of string. At least one byte long. return non-zero on error */ int curlx_str_word(const char **linep, struct Curl_str *out, - const size_t max) + const size_t max) { return curlx_str_until(linep, out, max, ' '); } @@ -72,7 +75,7 @@ int curlx_str_word(const char **linep, struct Curl_str *out, /* Get a word until a newline byte or end of string. At least one byte long. return non-zero on error */ int curlx_str_untilnl(const char **linep, struct Curl_str *out, - const size_t max) + const size_t max) { const char *s = *linep; size_t len = 0; @@ -96,7 +99,7 @@ int curlx_str_untilnl(const char **linep, struct Curl_str *out, /* Get a "quoted" word. No escaping possible. return non-zero on error */ int curlx_str_quotedword(const char **linep, struct Curl_str *out, - const size_t max) + const size_t max) { const char *s = *linep; size_t len = 0; @@ -238,7 +241,7 @@ int curlx_str_newline(const char **linep) int curlx_str_casecompare(struct Curl_str *str, const char *check) { size_t clen = check ? strlen(check) : 0; - return ((str->len == clen) && strncasecompare(str->str, check, clen)); + return ((str->len == clen) && curl_strnequal(str->str, check, clen)); } #endif diff --git a/vendor/curl/lib/curlx/strparse.h b/vendor/curl/lib/curlx/strparse.h index 17bfdb80710..6a0bf28d6cb 100644 --- a/vendor/curl/lib/curlx/strparse.h +++ b/vendor/curl/lib/curlx/strparse.h @@ -55,17 +55,17 @@ int curlx_str_word(const char **linep, struct Curl_str *out, const size_t max); /* Get a word until the first DELIM or end of string return non-zero on error */ int curlx_str_until(const char **linep, struct Curl_str *out, const size_t max, - char delim); + char delim); /* Get a word until a newline byte or end of string. At least one byte long. return non-zero on error */ int curlx_str_untilnl(const char **linep, struct Curl_str *out, - const size_t max); + const size_t max); /* Get a "quoted" word. No escaping possible. return non-zero on error */ int curlx_str_quotedword(const char **linep, struct Curl_str *out, - const size_t max); + const size_t max); /* Advance over a single character. return non-zero on error */ diff --git a/vendor/curl/lib/curlx/timeval.c b/vendor/curl/lib/curlx/timeval.c index 501bf9c3fd9..bd8b9bcee27 100644 --- a/vendor/curl/lib/curlx/timeval.c +++ b/vendor/curl/lib/curlx/timeval.c @@ -115,7 +115,7 @@ struct curltime curlx_now(void) (HAVE_BUILTIN_AVAILABLE == 1) have_clock_gettime && #endif - (0 == clock_gettime(CLOCK_MONOTONIC_RAW, &tsnow))) { + (clock_gettime(CLOCK_MONOTONIC_RAW, &tsnow) == 0)) { cnow.tv_sec = tsnow.tv_sec; cnow.tv_usec = (int)(tsnow.tv_nsec / 1000); } @@ -127,7 +127,7 @@ struct curltime curlx_now(void) (HAVE_BUILTIN_AVAILABLE == 1) have_clock_gettime && #endif - (0 == clock_gettime(CLOCK_MONOTONIC, &tsnow))) { + (clock_gettime(CLOCK_MONOTONIC, &tsnow) == 0)) { cnow.tv_sec = tsnow.tv_sec; cnow.tv_usec = (int)(tsnow.tv_nsec / 1000); } @@ -168,11 +168,11 @@ struct curltime curlx_now(void) struct curltime cnow; uint64_t usecs; - if(0 == timebase.denom) - (void) mach_timebase_info(&timebase); + if(timebase.denom == 0) + (void)mach_timebase_info(&timebase); usecs = mach_absolute_time(); - usecs *= timebase.numer; + usecs *= timebase.numer; /* spellchecker:disable-line */ usecs /= timebase.denom; usecs /= 1000; diff --git a/vendor/curl/lib/curlx/wait.c b/vendor/curl/lib/curlx/wait.c new file mode 100644 index 00000000000..4e10a8297a9 --- /dev/null +++ b/vendor/curl/lib/curlx/wait.c @@ -0,0 +1,97 @@ +/*************************************************************************** + * _ _ ____ _ + * 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" + +#ifndef HAVE_SELECT +#error "We cannot compile without select() support." +#endif + +#include + +#ifdef HAVE_SYS_SELECT_H +#include +#elif defined(HAVE_UNISTD_H) +#include +#endif + +#ifdef MSDOS +#include /* delay() */ +#endif + +#include "timediff.h" +#include "wait.h" + +/* + * Internal function used for waiting a specific amount of ms in + * Curl_socket_check() and Curl_poll() when no file descriptor is provided to + * wait on, just being used to delay execution. Winsock select() and poll() + * timeout mechanisms need a valid socket descriptor in a not null file + * descriptor set to work. Waiting indefinitely with this function is not + * allowed, a zero or negative timeout value will return immediately. Timeout + * resolution, accuracy, as well as maximum supported value is system + * dependent, neither factor is a critical issue for the intended use of this + * function in the library. + * + * Return values: + * -1 = system call error, or invalid timeout value + * 0 = specified timeout has elapsed, or interrupted + */ +int curlx_wait_ms(timediff_t timeout_ms) +{ + int r = 0; + + if(!timeout_ms) + return 0; + if(timeout_ms < 0) { + SET_SOCKERRNO(SOCKEINVAL); + return -1; + } +#ifdef MSDOS + delay((unsigned int)timeout_ms); +#elif defined(_WIN32) + /* prevent overflow, timeout_ms is typecast to ULONG/DWORD. */ +#if TIMEDIFF_T_MAX >= ULONG_MAX + if(timeout_ms >= ULONG_MAX) + timeout_ms = ULONG_MAX-1; + /* do not use ULONG_MAX, because that is equal to INFINITE */ +#endif + Sleep((DWORD)timeout_ms); +#else + /* avoid using poll() for this since it behaves incorrectly with no sockets + on Apple operating systems */ + { + struct timeval pending_tv; + r = select(0, NULL, NULL, NULL, curlx_mstotv(&pending_tv, timeout_ms)); + } +#endif /* _WIN32 */ + if(r) { + if((r == -1) && (SOCKERRNO == SOCKEINTR)) + /* make EINTR from select or poll not a "lethal" error */ + r = 0; + else + r = -1; + } + return r; +} diff --git a/vendor/curl/lib/curlx/wait.h b/vendor/curl/lib/curlx/wait.h new file mode 100644 index 00000000000..208bc20accb --- /dev/null +++ b/vendor/curl/lib/curlx/wait.h @@ -0,0 +1,31 @@ +#ifndef HEADER_CURL_WAIT_H +#define HEADER_CURL_WAIT_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" + +int curlx_wait_ms(timediff_t timeout_ms); + +#endif /* HEADER_CURL_WAIT_H */ diff --git a/vendor/curl/lib/curlx/warnless.c b/vendor/curl/lib/curlx/warnless.c index 5ca92450d89..c6cb7c6e5e3 100644 --- a/vendor/curl/lib/curlx/warnless.c +++ b/vendor/curl/lib/curlx/warnless.c @@ -35,11 +35,6 @@ #endif /* __INTEL_COMPILER && __unix__ */ -#ifdef _WIN32 -#undef read -#undef write -#endif - #include #define CURL_MASK_UCHAR ((unsigned char)~0) @@ -295,21 +290,3 @@ size_t curlx_sitouz(int sinum) # pragma warning(pop) #endif } - -#ifdef _WIN32 - -ssize_t curlx_read(int fd, void *buf, size_t count) -{ - return (ssize_t)read(fd, buf, curlx_uztoui(count)); -} - -ssize_t curlx_write(int fd, const void *buf, size_t count) -{ - return (ssize_t)write(fd, buf, curlx_uztoui(count)); -} - -#endif /* _WIN32 */ - -/* Ensure that warnless.h redefinitions continue to have an effect - in "unity" builds. */ -#undef HEADER_CURL_WARNLESS_H_REDEFS diff --git a/vendor/curl/lib/curlx/warnless.h b/vendor/curl/lib/curlx/warnless.h index c78b61169bf..0a0c6080734 100644 --- a/vendor/curl/lib/curlx/warnless.h +++ b/vendor/curl/lib/curlx/warnless.h @@ -57,24 +57,11 @@ unsigned short curlx_uitous(unsigned int uinum); size_t curlx_sitouz(int sinum); -#ifdef _WIN32 - -ssize_t curlx_read(int fd, void *buf, size_t count); - -ssize_t curlx_write(int fd, const void *buf, size_t count); - -#endif /* _WIN32 */ - -#endif /* HEADER_CURL_WARNLESS_H */ - -#ifndef HEADER_CURL_WARNLESS_H_REDEFS -#define HEADER_CURL_WARNLESS_H_REDEFS - #ifdef _WIN32 #undef read -#define read(fd, buf, count) curlx_read(fd, buf, count) +#define read(fd, buf, count) (ssize_t)_read(fd, buf, curlx_uztoui(count)) #undef write -#define write(fd, buf, count) curlx_write(fd, buf, count) +#define write(fd, buf, count) (ssize_t)_write(fd, buf, curlx_uztoui(count)) #endif -#endif /* HEADER_CURL_WARNLESS_H_REDEFS */ +#endif /* HEADER_CURL_WARNLESS_H */ diff --git a/vendor/curl/lib/cw-out.c b/vendor/curl/lib/cw-out.c index 097ef85e8b4..ee7dc65dffc 100644 --- a/vendor/curl/lib/cw-out.c +++ b/vendor/curl/lib/cw-out.c @@ -31,6 +31,7 @@ #include "headers.h" #include "multiif.h" #include "sendf.h" +#include "transfer.h" #include "cw-out.h" #include "cw-pause.h" @@ -234,11 +235,9 @@ static CURLcode cw_out_ptr_flush(struct cw_out_ctx *ctx, failf(data, "Write callback asked for PAUSE when not supported"); return CURLE_WRITE_ERROR; } - /* mark the connection as RECV paused */ - data->req.keepon |= KEEP_RECV_PAUSE; ctx->paused = TRUE; CURL_TRC_WRITE(data, "[OUT] PAUSE requested by client"); - break; + return Curl_xfer_pause_recv(data, TRUE); } else if(CURL_WRITEFUNC_ERROR == nwritten) { failf(data, "client returned ERROR on write of %zu bytes", wlen); diff --git a/vendor/curl/lib/dict.c b/vendor/curl/lib/dict.c index 637f349e700..819584f284a 100644 --- a/vendor/curl/lib/dict.c +++ b/vendor/curl/lib/dict.c @@ -60,7 +60,6 @@ #include "progress.h" #include "dict.h" #include "curl_printf.h" -#include "strcase.h" #include "curl_memory.h" /* The last #include file should be: */ #include "memdebug.h" @@ -93,10 +92,10 @@ const struct Curl_handler Curl_handler_dict = { ZERO_NULL, /* connect_it */ ZERO_NULL, /* connecting */ ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* proto_pollset */ + ZERO_NULL, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ ZERO_NULL, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -198,9 +197,9 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done) if(result) return result; - if(strncasecompare(path, DICT_MATCH, sizeof(DICT_MATCH)-1) || - strncasecompare(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) || - strncasecompare(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) { + if(curl_strnequal(path, DICT_MATCH, sizeof(DICT_MATCH)-1) || + curl_strnequal(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) || + curl_strnequal(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) { word = strchr(path, ':'); if(word) { @@ -243,11 +242,11 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done) failf(data, "Failed sending DICT request"); goto error; } - Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE); /* no upload */ + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); } - else if(strncasecompare(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) || - strncasecompare(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) || - strncasecompare(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) { + else if(curl_strnequal(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) || + curl_strnequal(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) || + curl_strnequal(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) { word = strchr(path, ':'); if(word) { @@ -284,7 +283,7 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done) failf(data, "Failed sending DICT request"); goto error; } - Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); } else { @@ -306,7 +305,7 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done) goto error; } - Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); } } diff --git a/vendor/curl/lib/doh.c b/vendor/curl/lib/doh.c index 9f408402a03..030b026fe29 100644 --- a/vendor/curl/lib/doh.c +++ b/vendor/curl/lib/doh.c @@ -257,7 +257,7 @@ static void doh_probe_done(struct Curl_easy *data, if(!dohp->pending) { /* DoH completed, run the transfer picking up the results */ - Curl_expire(data, 0, EXPIRE_RUN_NOW); + Curl_multi_mark_dirty(data); } } } @@ -348,10 +348,10 @@ static CURLcode doh_probe_run(struct Curl_easy *data, #endif #ifndef DEBUGBUILD /* enforce HTTPS if not debug */ - ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, (long)CURLPROTO_HTTPS); + ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTPS); #else /* in debug mode, also allow http */ - ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, (long)CURLPROTO_HTTP|CURLPROTO_HTTPS); + ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS); #endif ERROR_CHECK_SETOPT(CURLOPT_TIMEOUT_MS, (long)timeout_ms); ERROR_CHECK_SETOPT(CURLOPT_SHARE, (CURLSH *)data->share); @@ -377,8 +377,6 @@ static CURLcode doh_probe_run(struct Curl_easy *data, options should be added to check doh proxy insecure separately, CURLOPT_DOH_PROXY_SSL_VERIFYHOST and CURLOPT_DOH_PROXY_SSL_VERIFYPEER. */ - if(data->set.ssl.falsestart) - ERROR_CHECK_SETOPT(CURLOPT_SSL_FALSESTART, 1L); if(data->set.str[STRING_SSL_CAFILE]) { ERROR_CHECK_SETOPT(CURLOPT_CAINFO, data->set.str[STRING_SSL_CAFILE]); @@ -486,7 +484,7 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, data->sub_xfer_done = doh_probe_done; /* create IPv4 DoH request */ - result = doh_probe_run(data, DNS_TYPE_A, + result = doh_probe_run(data, CURL_DNS_TYPE_A, hostname, data->set.str[STRING_DOH], data->multi, &dohp->probe_resp[DOH_SLOT_IPV4].probe_mid); @@ -497,7 +495,7 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, #ifdef USE_IPV6 if((ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data)) { /* create IPv6 DoH request */ - result = doh_probe_run(data, DNS_TYPE_AAAA, + result = doh_probe_run(data, CURL_DNS_TYPE_AAAA, hostname, data->set.str[STRING_DOH], data->multi, &dohp->probe_resp[DOH_SLOT_IPV6].probe_mid); @@ -516,7 +514,7 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, if(!qname) goto error; } - result = doh_probe_run(data, DNS_TYPE_HTTPS, + result = doh_probe_run(data, CURL_DNS_TYPE_HTTPS, qname ? qname : hostname, data->set.str[STRING_DOH], data->multi, &dohp->probe_resp[DOH_SLOT_HTTPS_RR].probe_mid); @@ -583,19 +581,19 @@ static void doh_store_a(const unsigned char *doh, int index, /* silently ignore addresses over the limit */ if(d->numaddr < DOH_MAX_ADDR) { struct dohaddr *a = &d->addr[d->numaddr]; - a->type = DNS_TYPE_A; + a->type = CURL_DNS_TYPE_A; memcpy(&a->ip.v4, &doh[index], 4); d->numaddr++; } } static void doh_store_aaaa(const unsigned char *doh, int index, - struct dohentry *d) + struct dohentry *d) { /* silently ignore addresses over the limit */ if(d->numaddr < DOH_MAX_ADDR) { struct dohaddr *a = &d->addr[d->numaddr]; - a->type = DNS_TYPE_AAAA; + a->type = CURL_DNS_TYPE_AAAA; memcpy(&a->ip.v6, &doh[index], 16); d->numaddr++; } @@ -683,29 +681,29 @@ static DOHcode doh_rdata(const unsigned char *doh, DOHcode rc; switch(type) { - case DNS_TYPE_A: + case CURL_DNS_TYPE_A: if(rdlength != 4) return DOH_DNS_RDATA_LEN; doh_store_a(doh, index, d); break; - case DNS_TYPE_AAAA: + case CURL_DNS_TYPE_AAAA: if(rdlength != 16) return DOH_DNS_RDATA_LEN; doh_store_aaaa(doh, index, d); break; #ifdef USE_HTTPSRR - case DNS_TYPE_HTTPS: + case CURL_DNS_TYPE_HTTPS: rc = doh_store_https(doh, index, d, rdlength); if(rc) return rc; break; #endif - case DNS_TYPE_CNAME: + case CURL_DNS_TYPE_CNAME: rc = doh_store_cname(doh, dohlen, (unsigned int)index, d); if(rc) return rc; break; - case DNS_TYPE_DNAME: + case CURL_DNS_TYPE_DNAME: /* explicit for clarity; just skip; rely on synthesized CNAME */ break; default: @@ -772,8 +770,8 @@ UNITTEST DOHcode doh_resp_decode(const unsigned char *doh, return DOH_DNS_OUT_OF_RANGE; type = doh_get16bit(doh, index); - if((type != DNS_TYPE_CNAME) /* may be synthesized from DNAME */ - && (type != DNS_TYPE_DNAME) /* if present, accept and ignore */ + if((type != CURL_DNS_TYPE_CNAME) /* may be synthesized from DNAME */ + && (type != CURL_DNS_TYPE_DNAME) /* if present, accept and ignore */ && (type != dnstype)) /* Not the same type as was asked for nor CNAME nor DNAME */ return DOH_DNS_UNEXPECTED_TYPE; @@ -857,9 +855,10 @@ UNITTEST DOHcode doh_resp_decode(const unsigned char *doh, return DOH_DNS_MALFORMAT; /* something is wrong */ #ifdef USE_HTTTPS - if((type != DNS_TYPE_NS) && !d->numcname && !d->numaddr && !d->numhttps_rrs) + if((type != CURL_DNS_TYPE_NS) && !d->numcname && !d->numaddr && + !d->numhttps_rrs) #else - if((type != DNS_TYPE_NS) && !d->numcname && !d->numaddr) + if((type != CURL_DNS_TYPE_NS) && !d->numcname && !d->numaddr) #endif /* nothing stored! */ return DOH_NO_CONTENT; @@ -875,12 +874,12 @@ static void doh_show(struct Curl_easy *data, infof(data, "[DoH] TTL: %u seconds", d->ttl); for(i = 0; i < d->numaddr; i++) { const struct dohaddr *a = &d->addr[i]; - if(a->type == DNS_TYPE_A) { + if(a->type == CURL_DNS_TYPE_A) { infof(data, "[DoH] A: %u.%u.%u.%u", a->ip.v4[0], a->ip.v4[1], a->ip.v4[2], a->ip.v4[3]); } - else if(a->type == DNS_TYPE_AAAA) { + else if(a->type == CURL_DNS_TYPE_AAAA) { int j; char buffer[128] = "[DoH] AAAA: "; size_t len = strlen(buffer); @@ -950,7 +949,7 @@ static CURLcode doh2ai(const struct dohentry *de, const char *hostname, for(i = 0; i < de->numaddr; i++) { size_t ss_size; CURL_SA_FAMILY_T addrtype; - if(de->addr[i].type == DNS_TYPE_AAAA) { + if(de->addr[i].type == CURL_DNS_TYPE_AAAA) { #ifndef USE_IPV6 /* we cannot handle IPv6 addresses */ continue; @@ -1027,12 +1026,12 @@ static CURLcode doh2ai(const struct dohentry *de, const char *hostname, static const char *doh_type2name(DNStype dnstype) { switch(dnstype) { - case DNS_TYPE_A: + case CURL_DNS_TYPE_A: return "A"; - case DNS_TYPE_AAAA: + case CURL_DNS_TYPE_AAAA: return "AAAA"; #ifdef USE_HTTPSRR - case DNS_TYPE_HTTPS: + case CURL_DNS_TYPE_HTTPS: return "HTTPS"; #endif default: @@ -1250,8 +1249,8 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data, p->dnstype, &de); #ifndef CURL_DISABLE_VERBOSE_STRINGS if(rc[slot]) { - infof(data, "DoH: %s type %s for %s", doh_strerror(rc[slot]), - doh_type2name(p->dnstype), dohp->host); + CURL_TRC_DNS(data, "DoH: %s type %s for %s", doh_strerror(rc[slot]), + doh_type2name(p->dnstype), dohp->host); } #endif } /* next slot */ diff --git a/vendor/curl/lib/doh.h b/vendor/curl/lib/doh.h index 9146f53580f..3fd7de2c1c5 100644 --- a/vendor/curl/lib/doh.h +++ b/vendor/curl/lib/doh.h @@ -51,12 +51,12 @@ typedef enum { } DOHcode; typedef enum { - DNS_TYPE_A = 1, - DNS_TYPE_NS = 2, - DNS_TYPE_CNAME = 5, - DNS_TYPE_AAAA = 28, - DNS_TYPE_DNAME = 39, /* RFC6672 */ - DNS_TYPE_HTTPS = 65 + CURL_DNS_TYPE_A = 1, + CURL_DNS_TYPE_NS = 2, + CURL_DNS_TYPE_CNAME = 5, + CURL_DNS_TYPE_AAAA = 28, + CURL_DNS_TYPE_DNAME = 39, /* RFC6672 */ + CURL_DNS_TYPE_HTTPS = 65 } DNStype; enum doh_slot_num { diff --git a/vendor/curl/lib/dynhds.c b/vendor/curl/lib/dynhds.c index 5c52d7411ac..dcb9193a8be 100644 --- a/vendor/curl/lib/dynhds.c +++ b/vendor/curl/lib/dynhds.c @@ -150,7 +150,7 @@ struct dynhds_entry *Curl_dynhds_get(struct dynhds *dynhds, const char *name, size_t i; for(i = 0; i < dynhds->hds_len; ++i) { if(dynhds->hds[i]->namelen == namelen && - strncasecompare(dynhds->hds[i]->name, name, namelen)) { + curl_strnequal(dynhds->hds[i]->name, name, namelen)) { return dynhds->hds[i]; } } @@ -297,7 +297,7 @@ size_t Curl_dynhds_count_name(struct dynhds *dynhds, size_t i; for(i = 0; i < dynhds->hds_len; ++i) { if((namelen == dynhds->hds[i]->namelen) && - strncasecompare(name, dynhds->hds[i]->name, namelen)) + curl_strnequal(name, dynhds->hds[i]->name, namelen)) ++n; } } @@ -325,7 +325,7 @@ size_t Curl_dynhds_remove(struct dynhds *dynhds, size_t i, len; for(i = 0; i < dynhds->hds_len; ++i) { if((namelen == dynhds->hds[i]->namelen) && - strncasecompare(name, dynhds->hds[i]->name, namelen)) { + curl_strnequal(name, dynhds->hds[i]->name, namelen)) { ++n; --dynhds->hds_len; dynhds->strs_len -= (dynhds->hds[i]->namelen + diff --git a/vendor/curl/lib/easy.c b/vendor/curl/lib/easy.c index 3f867862523..b526e6cff0a 100644 --- a/vendor/curl/lib/easy.c +++ b/vendor/curl/lib/easy.c @@ -67,6 +67,7 @@ #include "amigaos.h" #include "macos.h" #include "curlx/warnless.h" +#include "curlx/wait.h" #include "sigpipe.h" #include "vssh/ssh.h" #include "setopt.h" @@ -106,7 +107,7 @@ static curl_simple_lock s_lock = CURL_SIMPLE_LOCK_INIT; * ways, but at this point it must be defined as the system-supplied strdup * so the callback pointer is initialized correctly. */ -#if defined(UNDER_CE) +#ifdef UNDER_CE #define system_strdup _strdup #elif !defined(HAVE_STRDUP) #define system_strdup Curl_strdup @@ -128,9 +129,6 @@ curl_free_callback Curl_cfree = (curl_free_callback)free; curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc; curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup; curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc; -#if defined(_WIN32) && defined(UNICODE) -curl_wcsdup_callback Curl_cwcsdup = Curl_wcsdup; -#endif #if defined(_MSC_VER) && defined(_DLL) # pragma warning(pop) @@ -156,9 +154,6 @@ static CURLcode global_init(long flags, bool memoryfuncs) Curl_crealloc = (curl_realloc_callback)realloc; Curl_cstrdup = (curl_strdup_callback)system_strdup; Curl_ccalloc = (curl_calloc_callback)calloc; -#if defined(_WIN32) && defined(UNICODE) - Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup; -#endif } if(Curl_trc_init()) { @@ -470,8 +465,8 @@ static int events_socket(CURL *easy, /* easy handle */ bool found = FALSE; struct Curl_easy *data = easy; -#if defined(CURL_DISABLE_VERBOSE_STRINGS) - (void) easy; +#ifdef CURL_DISABLE_VERBOSE_STRINGS + (void)easy; #endif (void)socketp; @@ -611,7 +606,7 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev) #endif pollrc = 0; if(ev->ms > 0) - Curl_wait_ms(ev->ms); + curlx_wait_ms(ev->ms); } ev->msbump = FALSE; /* reset here */ @@ -733,7 +728,7 @@ static CURLcode easy_transfer(struct Curl_multi *multi) /* - * easy_perform() is the external interface that performs a blocking + * easy_perform() is the internal interface that performs a blocking * transfer as previously setup. * * CONCEPT: This function creates a multi handle, adds the easy handle to it, @@ -827,7 +822,6 @@ static CURLcode easy_perform(struct Curl_easy *data, bool events) return result; } - /* * curl_easy_perform() is the external interface that performs a blocking * transfer as previously setup. @@ -846,7 +840,6 @@ CURLcode curl_easy_perform_ev(struct Curl_easy *data) { return easy_perform(data, TRUE); } - #endif /* @@ -955,7 +948,11 @@ static void dupeasy_meta_freeentry(void *p) CURL *curl_easy_duphandle(CURL *d) { struct Curl_easy *data = d; - struct Curl_easy *outcurl = calloc(1, sizeof(struct Curl_easy)); + struct Curl_easy *outcurl = NULL; + + if(!GOOD_EASY_HANDLE(data)) + goto fail; + outcurl = calloc(1, sizeof(struct Curl_easy)); if(!outcurl) goto fail; @@ -1079,6 +1076,9 @@ CURL *curl_easy_duphandle(CURL *d) void curl_easy_reset(CURL *d) { struct Curl_easy *data = d; + if(!GOOD_EASY_HANDLE(data)) + return; + Curl_req_hard_reset(&data->req, data); Curl_hash_clean(&data->meta_hash); @@ -1102,6 +1102,7 @@ void curl_easy_reset(CURL *d) data->progress.hide = TRUE; data->state.current_speed = -1; /* init to negative == impossible */ data->state.retrycount = 0; /* reset the retry counter */ + data->state.recent_conn_id = -1; /* clear remembered connection id */ /* zero out authentication data: */ memset(&data->state.authhost, 0, sizeof(struct auth)); @@ -1128,13 +1129,12 @@ void curl_easy_reset(CURL *d) */ CURLcode curl_easy_pause(CURL *d, int action) { - struct SingleRequest *k; CURLcode result = CURLE_OK; - int oldstate; - int newstate; bool recursive = FALSE; - bool keep_changed, unpause_read, not_all_paused; + bool changed = FALSE; struct Curl_easy *data = d; + bool recv_paused, recv_paused_new; + bool send_paused, send_paused_new; if(!GOOD_EASY_HANDLE(data) || !data->conn) /* crazy input, do not continue */ @@ -1142,62 +1142,39 @@ CURLcode curl_easy_pause(CURL *d, int action) if(Curl_is_in_callback(data)) recursive = TRUE; - k = &data->req; - oldstate = k->keepon & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE); - - /* first switch off both pause bits then set the new pause bits */ - newstate = (k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) | - ((action & CURLPAUSE_RECV) ? KEEP_RECV_PAUSE : 0) | - ((action & CURLPAUSE_SEND) ? KEEP_SEND_PAUSE : 0); - - keep_changed = ((newstate & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) != oldstate); - not_all_paused = (newstate & (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) != - (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE); - unpause_read = ((k->keepon & ~newstate & KEEP_SEND_PAUSE) && - (data->mstate == MSTATE_PERFORMING || - data->mstate == MSTATE_RATELIMITING)); - /* Unpausing writes is detected on the next run in - * transfer.c:Curl_sendrecv(). This is because this may result - * in a transfer error if the application's callbacks fail */ - - /* Set the new keepon state, so it takes effect no matter what error - * may happen afterwards. */ - k->keepon = newstate; + + recv_paused = Curl_xfer_recv_is_paused(data); + recv_paused_new = (action & CURLPAUSE_RECV); + send_paused = Curl_xfer_send_is_paused(data); + send_paused_new = (action & CURLPAUSE_SEND); + + if(send_paused != send_paused_new) { + changed = TRUE; + result = Curl_1st_err(result, Curl_xfer_pause_send(data, send_paused_new)); + } + + if(recv_paused != recv_paused_new) { + changed = TRUE; + result = Curl_1st_err(result, Curl_xfer_pause_recv(data, recv_paused_new)); + } /* If not completely pausing both directions now, run again in any case. */ - if(not_all_paused) { - Curl_expire(data, 0, EXPIRE_RUN_NOW); + if(!Curl_xfer_is_blocked(data)) { /* reset the too-slow time keeper */ data->state.keeps_speed.tv_sec = 0; - /* Simulate socket events on next run for unpaused directions */ - if(!(newstate & KEEP_SEND_PAUSE)) - data->state.select_bits |= CURL_CSELECT_OUT; - if(!(newstate & KEEP_RECV_PAUSE)) - data->state.select_bits |= CURL_CSELECT_IN; - /* On changes, tell application to update its timers. */ - if(keep_changed && data->multi) { - if(Curl_update_timer(data->multi)) { - result = CURLE_ABORTED_BY_CALLBACK; - goto out; + if(data->multi) { + Curl_multi_mark_dirty(data); /* make it run */ + /* On changes, tell application to update its timers. */ + if(changed) { + if(Curl_update_timer(data->multi) && !result) + result = CURLE_ABORTED_BY_CALLBACK; } } } - if(unpause_read) { - result = Curl_creader_unpause(data); - if(result) - goto out; - } - - if(!(k->keepon & KEEP_RECV_PAUSE) && Curl_cwriter_is_paused(data)) { - Curl_conn_ev_data_pause(data, FALSE); - result = Curl_cwriter_unpause(data); - } - -out: - if(!result && !data->state.done && keep_changed && data->multi) + if(!result && changed && !data->state.done && data->multi) /* pause/unpausing may result in multi event changes */ - if(Curl_multi_ev_assess_xfer(data->multi, data)) + if(Curl_multi_ev_assess_xfer(data->multi, data) && !result) result = CURLE_ABORTED_BY_CALLBACK; if(recursive) @@ -1241,10 +1218,11 @@ static CURLcode easy_connection(struct Curl_easy *data, CURLcode curl_easy_recv(CURL *d, void *buffer, size_t buflen, size_t *n) { CURLcode result; - ssize_t n1; struct connectdata *c; struct Curl_easy *data = d; + if(!GOOD_EASY_HANDLE(data)) + return CURLE_BAD_FUNCTION_ARGUMENT; if(Curl_is_in_callback(data)) return CURLE_RECURSIVE_API_CALL; @@ -1258,13 +1236,7 @@ CURLcode curl_easy_recv(CURL *d, void *buffer, size_t buflen, size_t *n) Curl_attach_connection(data, c); *n = 0; - result = Curl_conn_recv(data, FIRSTSOCKET, buffer, buflen, &n1); - - if(result) - return result; - - *n = (size_t)n1; - return CURLE_OK; + return Curl_conn_recv(data, FIRSTSOCKET, buffer, buflen, n); } #ifndef CURL_DISABLE_WEBSOCKETS @@ -1326,6 +1298,8 @@ CURLcode curl_easy_send(CURL *d, const void *buffer, size_t buflen, size_t *n) size_t written = 0; CURLcode result; struct Curl_easy *data = d; + if(!GOOD_EASY_HANDLE(data)) + return CURLE_BAD_FUNCTION_ARGUMENT; if(Curl_is_in_callback(data)) return CURLE_RECURSIVE_API_CALL; @@ -1355,7 +1329,7 @@ CURLcode curl_easy_ssls_import(CURL *d, const char *session_key, const unsigned char *shmac, size_t shmac_len, const unsigned char *sdata, size_t sdata_len) { -#ifdef USE_SSLS_EXPORT +#if defined(USE_SSL) && defined(USE_SSLS_EXPORT) struct Curl_easy *data = d; if(!GOOD_EASY_HANDLE(data)) return CURLE_BAD_FUNCTION_ARGUMENT; @@ -1376,7 +1350,7 @@ CURLcode curl_easy_ssls_export(CURL *d, curl_ssls_export_cb *export_fn, void *userptr) { -#ifdef USE_SSLS_EXPORT +#if defined(USE_SSL) && defined(USE_SSLS_EXPORT) struct Curl_easy *data = d; if(!GOOD_EASY_HANDLE(data)) return CURLE_BAD_FUNCTION_ARGUMENT; diff --git a/vendor/curl/lib/easy_lock.h b/vendor/curl/lib/easy_lock.h index ec324cfc81a..909753f43aa 100644 --- a/vendor/curl/lib/easy_lock.h +++ b/vendor/curl/lib/easy_lock.h @@ -30,12 +30,6 @@ #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x600 -#ifdef __MINGW32__ -#ifndef SRWLOCK_INIT -#define SRWLOCK_INIT NULL -#endif -#endif /* __MINGW32__ */ - #define curl_simple_lock SRWLOCK #define CURL_SIMPLE_LOCK_INIT SRWLOCK_INIT @@ -44,7 +38,7 @@ #elif defined(HAVE_ATOMIC) && defined(HAVE_STDATOMIC_H) #include -#if defined(HAVE_SCHED_YIELD) +#ifdef HAVE_SCHED_YIELD #include #endif diff --git a/vendor/curl/lib/easygetopt.c b/vendor/curl/lib/easygetopt.c index 5d30d39a49f..7ac39bc634e 100644 --- a/vendor/curl/lib/easygetopt.c +++ b/vendor/curl/lib/easygetopt.c @@ -1,9 +1,9 @@ /*************************************************************************** * _ _ ____ _ - * Project ___| | | | _ | | + * Project ___| | | | _ \| | * / __| | | | |_) | | * | (__| |_| | _ <| |___ - * ___|___/|_| ______| + * \___|\___/|_| \_\_____| * * Copyright (C) Daniel Stenberg, , et al. * @@ -23,7 +23,6 @@ ***************************************************************************/ #include "curl_setup.h" -#include "strcase.h" #include "easyoptions.h" #ifndef CURL_DISABLE_GETOPTIONS @@ -37,7 +36,7 @@ static const struct curl_easyoption *lookup(const char *name, CURLoption id) const struct curl_easyoption *o = &Curl_easyopts[0]; do { if(name) { - if(strcasecompare(o->name, name)) + if(curl_strequal(o->name, name)) return o; } else { @@ -83,7 +82,7 @@ const struct curl_easyoption *curl_easy_option_by_name(const char *name) return NULL; } -const struct curl_easyoption *curl_easy_option_by_id (CURLoption id) +const struct curl_easyoption *curl_easy_option_by_id(CURLoption id) { (void)id; return NULL; diff --git a/vendor/curl/lib/escape.c b/vendor/curl/lib/escape.c index 3cd906dc6c2..a292ba3b625 100644 --- a/vendor/curl/lib/escape.c +++ b/vendor/curl/lib/escape.c @@ -85,7 +85,7 @@ char *curl_easy_escape(CURL *data, const char *string, else { /* encode it */ unsigned char out[3]={'%'}; - Curl_hexbyte(&out[1], in, FALSE); + Curl_hexbyte(&out[1], in); if(curlx_dyn_addn(&d, out, 3)) return NULL; } @@ -212,7 +212,8 @@ void Curl_hexencode(const unsigned char *src, size_t len, /* input length */ DEBUGASSERT(src && len && (olen >= 3)); if(src && len && (olen >= 3)) { while(len-- && (olen >= 3)) { - Curl_hexbyte(out, *src, TRUE); + out[0] = Curl_ldigits[*src >> 4]; + out[1] = Curl_ldigits[*src & 0x0F]; ++src; out += 2; olen -= 2; @@ -225,14 +226,11 @@ void Curl_hexencode(const unsigned char *src, size_t len, /* input length */ /* Curl_hexbyte * - * Output a single unsigned char as a two-digit hex number, lowercase or - * uppercase + * Output a single unsigned char as a two-digit UPPERCASE hex number. */ void Curl_hexbyte(unsigned char *dest, /* must fit two bytes */ - unsigned char val, - bool lowercase) + unsigned char val) { - const unsigned char *t = lowercase ? Curl_ldigits : Curl_udigits; - dest[0] = t[val >> 4]; - dest[1] = t[val & 0x0F]; + dest[0] = Curl_udigits[val >> 4]; + dest[1] = Curl_udigits[val & 0x0F]; } diff --git a/vendor/curl/lib/escape.h b/vendor/curl/lib/escape.h index 1f2bac8fac2..a43fc38ed32 100644 --- a/vendor/curl/lib/escape.h +++ b/vendor/curl/lib/escape.h @@ -42,7 +42,6 @@ void Curl_hexencode(const unsigned char *src, size_t len, /* input length */ unsigned char *out, size_t olen); /* output buffer size */ void Curl_hexbyte(unsigned char *dest, /* must fit two bytes */ - unsigned char val, - bool lowercase); + unsigned char val); #endif /* HEADER_CURL_ESCAPE_H */ diff --git a/vendor/curl/lib/file.c b/vendor/curl/lib/file.c index b88f6123056..0b44d2257d7 100644 --- a/vendor/curl/lib/file.c +++ b/vendor/curl/lib/file.c @@ -120,10 +120,10 @@ const struct Curl_handler Curl_handler_file = { file_connect, /* connect_it */ ZERO_NULL, /* connecting */ ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* proto_pollset */ + ZERO_NULL, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ file_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -348,7 +348,7 @@ static CURLcode file_upload(struct Curl_easy *data, mode |= O_TRUNC; #if (defined(ANDROID) || defined(__ANDROID__)) && \ - (defined(__i386__) || defined(__arm__)) + (defined(__i386__) || defined(__arm__)) fd = open(file->path, mode, (mode_t)data->set.new_file_perms); #else fd = open(file->path, mode, data->set.new_file_perms); @@ -358,7 +358,7 @@ static CURLcode file_upload(struct Curl_easy *data, return CURLE_WRITE_ERROR; } - if(-1 != data->state.infilesize) + if(data->state.infilesize != -1) /* known size of data to "upload" */ Curl_pgrsSetUploadSize(data, data->state.infilesize); @@ -470,7 +470,7 @@ static CURLcode file_do(struct Curl_easy *data, bool *done) fd = file->fd; /* VMS: This only works reliable for STREAMLF files */ - if(-1 != fstat(fd, &statbuf)) { + if(fstat(fd, &statbuf) != -1) { if(!S_ISDIR(statbuf.st_mode)) expected_size = statbuf.st_size; /* and store the modification time */ diff --git a/vendor/curl/lib/fileinfo.c b/vendor/curl/lib/fileinfo.c index c3439af341e..47cdb102e37 100644 --- a/vendor/curl/lib/fileinfo.c +++ b/vendor/curl/lib/fileinfo.c @@ -23,7 +23,9 @@ ***************************************************************************/ #include "curl_setup.h" + #ifndef CURL_DISABLE_FTP + #include "strdup.h" #include "fileinfo.h" #include "curl_memory.h" @@ -43,4 +45,5 @@ void Curl_fileinfo_cleanup(struct fileinfo *finfo) curlx_dyn_free(&finfo->buf); free(finfo); } + #endif diff --git a/vendor/curl/lib/fopen.c b/vendor/curl/lib/fopen.c index 38b87f326e3..b28977317a8 100644 --- a/vendor/curl/lib/fopen.c +++ b/vendor/curl/lib/fopen.c @@ -136,7 +136,7 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename, result = CURLE_WRITE_ERROR; #if (defined(ANDROID) || defined(__ANDROID__)) && \ - (defined(__i386__) || defined(__arm__)) + (defined(__i386__) || defined(__arm__)) fd = open(tempstore, O_WRONLY | O_CREAT | O_EXCL, (mode_t)(0600|sb.st_mode)); #else fd = open(tempstore, O_WRONLY | O_CREAT | O_EXCL, 0600|sb.st_mode); diff --git a/vendor/curl/lib/formdata.c b/vendor/curl/lib/formdata.c index 2aa8eee94aa..d8553e32569 100644 --- a/vendor/curl/lib/formdata.c +++ b/vendor/curl/lib/formdata.c @@ -34,7 +34,6 @@ struct Curl_easy; #include "urldata.h" /* for struct Curl_easy */ #include "mime.h" #include "vtls/vtls.h" -#include "strcase.h" #include "sendf.h" #include "strdup.h" #include "rand.h" @@ -187,22 +186,24 @@ static void free_formlist(struct FormInfo *ptr) * Examples: * * Simple name/value pair with copied contents: - * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", - * CURLFORM_COPYCONTENTS, "value", CURLFORM_END); + * curl_formadd(&post, &last, CURLFORM_COPYNAME, "name", + * CURLFORM_COPYCONTENTS, "value", CURLFORM_END); * * name/value pair where only the content pointer is remembered: - * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", - * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10, CURLFORM_END); + * curl_formadd(&post, &last, CURLFORM_COPYNAME, "name", + * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10, + * CURLFORM_END); * (if CURLFORM_CONTENTSLENGTH is missing strlen () is used) * * storing a filename (CONTENTTYPE is optional!): - * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", - * CURLFORM_FILE, "filename1", CURLFORM_CONTENTTYPE, "plain/text", - * CURLFORM_END); + * curl_formadd(&post, &last, CURLFORM_COPYNAME, "name", + * CURLFORM_FILE, "filename1", CURLFORM_CONTENTTYPE, "plain/text", + * CURLFORM_END); * * storing multiple filenames: - * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", - * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END); + * curl_formadd(&post, &last, CURLFORM_COPYNAME, "name", + * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", + * CURLFORM_END); * * Returns: * CURL_FORMADD_OK on success @@ -927,9 +928,9 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost, int curl_formget(struct curl_httppost *form, void *arg, curl_formget_callback append) { - (void) form; - (void) arg; - (void) append; + (void)form; + (void)arg; + (void)append; return CURL_FORMADD_DISABLED; } diff --git a/vendor/curl/lib/ftp.c b/vendor/curl/lib/ftp.c index 2c6138e9802..f088054b2df 100644 --- a/vendor/curl/lib/ftp.c +++ b/vendor/curl/lib/ftp.c @@ -60,7 +60,7 @@ #include "cf-socket.h" #include "connect.h" #include "strerror.h" -#include "inet_ntop.h" +#include "curlx/inet_ntop.h" #include "curlx/inet_pton.h" #include "select.h" #include "parsedate.h" /* for the week day and month names */ @@ -114,12 +114,14 @@ static const char * const ftp_state_names[]={ "QUOTE", "RETR_PREQUOTE", "STOR_PREQUOTE", + "LIST_PREQUOTE", "POSTQUOTE", "CWD", "MKD", "MDTM", "TYPE", "LIST_TYPE", + "RETR_LIST_TYPE", "RETR_TYPE", "STOR_TYPE", "SIZE", @@ -148,7 +150,8 @@ static void _ftp_state(struct Curl_easy *data, #endif ) { -#if defined(CURL_DISABLE_VERBOSE_STRINGS) +#ifdef CURL_DISABLE_VERBOSE_STRINGS + (void)data; #ifdef DEBUGBUILD (void)lineno; #endif @@ -211,10 +214,10 @@ static CURLcode ftp_disconnect(struct Curl_easy *data, struct connectdata *conn, bool dead_connection); static CURLcode ftp_do_more(struct Curl_easy *data, int *completed); static CURLcode ftp_multi_statemach(struct Curl_easy *data, bool *done); -static int ftp_getsock(struct Curl_easy *data, struct connectdata *conn, - curl_socket_t *socks); -static int ftp_domore_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks); +static CURLcode ftp_pollset(struct Curl_easy *data, + struct easy_pollset *ps); +static CURLcode ftp_domore_pollset(struct Curl_easy *data, + struct easy_pollset *ps); static CURLcode ftp_doing(struct Curl_easy *data, bool *dophase_done); static CURLcode ftp_setup_connection(struct Curl_easy *data, @@ -254,10 +257,10 @@ const struct Curl_handler Curl_handler_ftp = { ftp_connect, /* connect_it */ ftp_multi_statemach, /* connecting */ ftp_doing, /* doing */ - ftp_getsock, /* proto_getsock */ - ftp_getsock, /* doing_getsock */ - ftp_domore_getsock, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ftp_pollset, /* proto_pollset */ + ftp_pollset, /* doing_pollset */ + ftp_domore_pollset, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ ftp_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -287,10 +290,10 @@ const struct Curl_handler Curl_handler_ftps = { ftp_connect, /* connect_it */ ftp_multi_statemach, /* connecting */ ftp_doing, /* doing */ - ftp_getsock, /* proto_getsock */ - ftp_getsock, /* doing_getsock */ - ftp_domore_getsock, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ftp_pollset, /* proto_pollset */ + ftp_pollset, /* doing_pollset */ + ftp_domore_pollset, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ ftp_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -543,12 +546,13 @@ static CURLcode ftp_initiate_transfer(struct Curl_easy *data, /* FTP upload, shutdown DATA, ignore shutdown errors, as we rely * on the server response on the CONTROL connection. */ - Curl_xfer_setup2(data, CURL_XFER_SEND, -1, TRUE, TRUE); + Curl_xfer_setup_send(data, SECONDARYSOCKET); + Curl_xfer_set_shutdown(data, TRUE, TRUE); } else { /* FTP download, shutdown, do not ignore errors */ - Curl_xfer_setup2(data, CURL_XFER_RECV, - ftpc->retr_size_saved, TRUE, FALSE); + Curl_xfer_setup_recv(data, SECONDARYSOCKET, ftpc->retr_size_saved); + Curl_xfer_set_shutdown(data, TRUE, FALSE); } ftpc->pp.pending_resp = TRUE; /* expect server response */ @@ -612,7 +616,7 @@ static CURLcode ftp_readresp(struct Curl_easy *data, if(ftpcode) *ftpcode = code; - if(421 == code) { + if(code == 421) { /* 421 means "Service not available, closing control connection." and FTP * servers use it to signal that idle session timeout has been exceeded. * If we ignored the response, it could end up hanging in some cases. @@ -765,7 +769,12 @@ static CURLcode ftp_state_user(struct Curl_easy *data, static CURLcode ftp_state_pwd(struct Curl_easy *data, struct ftp_conn *ftpc) { - CURLcode result = Curl_pp_sendf(data, &ftpc->pp, "%s", "PWD"); + CURLcode result; +#ifdef DEBUGBUILD + if(!data->id && getenv("CURL_FTP_PWD_STOP")) + return CURLE_OK; +#endif + result = Curl_pp_sendf(data, &ftpc->pp, "%s", "PWD"); if(!result) ftp_state(data, ftpc, FTP_PWD); @@ -773,42 +782,39 @@ static CURLcode ftp_state_pwd(struct Curl_easy *data, } /* For the FTP "protocol connect" and "doing" phases only */ -static int ftp_getsock(struct Curl_easy *data, - struct connectdata *conn, - curl_socket_t *socks) +static CURLcode ftp_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { - struct ftp_conn *ftpc = Curl_conn_meta_get(conn, CURL_META_FTP_CONN); - return ftpc ? Curl_pp_getsock(data, &ftpc->pp, socks) : GETSOCK_BLANK; + struct ftp_conn *ftpc = Curl_conn_meta_get(data->conn, CURL_META_FTP_CONN); + return ftpc ? Curl_pp_pollset(data, &ftpc->pp, ps) : CURLE_OK; } /* For the FTP "DO_MORE" phase only */ -static int ftp_domore_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks) +static CURLcode ftp_domore_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { - struct ftp_conn *ftpc = Curl_conn_meta_get(conn, CURL_META_FTP_CONN); - (void)data; + struct ftp_conn *ftpc = Curl_conn_meta_get(data->conn, CURL_META_FTP_CONN); if(!ftpc) - return GETSOCK_BLANK; + return CURLE_OK; /* When in DO_MORE state, we could be either waiting for us to connect to a * remote site, or we could wait for that site to connect to us. Or just * handle ordinary commands. */ - CURL_TRC_FTP(data, "[%s] ftp_domore_getsock()", FTP_CSTATE(ftpc)); + CURL_TRC_FTP(data, "[%s] ftp_domore_pollset()", FTP_CSTATE(ftpc)); if(FTP_STOP == ftpc->state) { /* if stopped and still in this state, then we are also waiting for a connect on the secondary connection */ - DEBUGASSERT(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD || - (conn->cfilter[SECONDARYSOCKET] && - !Curl_conn_is_connected(conn, SECONDARYSOCKET))); - socks[0] = conn->sock[FIRSTSOCKET]; + DEBUGASSERT(data->conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD || + (data->conn->cfilter[SECONDARYSOCKET] && + !Curl_conn_is_connected(data->conn, SECONDARYSOCKET))); /* An unconnected SECONDARY will add its socket by itself * via its adjust_pollset() */ - return GETSOCK_READSOCK(0); + return Curl_pollset_add_in(data, ps, data->conn->sock[FIRSTSOCKET]); } - return Curl_pp_getsock(data, &ftpc->pp, socks); + return Curl_pp_pollset(data, &ftpc->pp, ps); } /* This is called after the FTP_QUOTE state is passed. @@ -978,6 +984,12 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data, port_min = port_max = 0; if(addrlen) { + const struct Curl_sockaddr_ex *remote_addr = + Curl_conn_get_remote_addr(data, FIRSTSOCKET); + + DEBUGASSERT(remote_addr); + if(!remote_addr) + goto out; DEBUGASSERT(addr); if(addrlen >= sizeof(ipstr)) goto out; @@ -985,9 +997,9 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data, ipstr[addrlen] = 0; /* attempt to get the address of the given interface name */ - switch(Curl_if2ip(conn->remote_addr->family, + switch(Curl_if2ip(remote_addr->family, #ifdef USE_IPV6 - Curl_ipv6_scope(&conn->remote_addr->curl_sa_addr), + Curl_ipv6_scope(&remote_addr->curl_sa_addr), conn->scope_id, #endif ipstr, hbuf, sizeof(hbuf))) { @@ -1020,11 +1032,11 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data, switch(sa->sa_family) { #ifdef USE_IPV6 case AF_INET6: - r = Curl_inet_ntop(sa->sa_family, &sa6->sin6_addr, hbuf, sizeof(hbuf)); + r = curlx_inet_ntop(sa->sa_family, &sa6->sin6_addr, hbuf, sizeof(hbuf)); break; #endif default: - r = Curl_inet_ntop(sa->sa_family, &sa4->sin_addr, hbuf, sizeof(hbuf)); + r = curlx_inet_ntop(sa->sa_family, &sa4->sin_addr, hbuf, sizeof(hbuf)); break; } if(!r) { @@ -1052,7 +1064,8 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data, /* step 2, create a socket for the requested address */ error = 0; for(ai = res; ai; ai = ai->ai_next) { - if(Curl_socket_open(data, ai, NULL, conn->transport, &portsock)) { + if(Curl_socket_open(data, ai, NULL, + Curl_conn_get_transport(data, conn), &portsock)) { error = SOCKERRNO; continue; } @@ -1245,7 +1258,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data, } data->conn->bits.do_more = FALSE; Curl_pgrsTime(data, TIMER_STARTACCEPT); - Curl_expire(data, data->set.accepttimeout ? + Curl_expire(data, (data->set.accepttimeout > 0) ? data->set.accepttimeout: DEFAULT_ACCEPT_TIMEOUT, EXPIRE_FTP_ACCEPT); } @@ -1448,6 +1461,14 @@ static CURLcode ftp_state_list(struct Curl_easy *data, return result; } +static CURLcode ftp_state_list_prequote(struct Curl_easy *data, + struct ftp_conn *ftpc, + struct FTP *ftp) +{ + /* We have sent the TYPE, now we must send the list of prequote strings */ + return ftp_state_quote(data, ftpc, ftp, TRUE, FTP_LIST_PREQUOTE); +} + static CURLcode ftp_state_retr_prequote(struct Curl_easy *data, struct ftp_conn *ftpc, struct FTP *ftp) @@ -1636,6 +1657,7 @@ static CURLcode ftp_state_quote(struct Curl_easy *data, break; case FTP_RETR_PREQUOTE: case FTP_STOR_PREQUOTE: + case FTP_LIST_PREQUOTE: item = data->set.prequote; break; case FTP_POSTQUOTE: @@ -1725,6 +1747,10 @@ static CURLcode ftp_state_quote(struct Curl_easy *data, break; case FTP_POSTQUOTE: break; + case FTP_LIST_PREQUOTE: + ftp_state(data, ftpc, FTP_LIST_TYPE); + result = ftp_state_list(data, ftpc, ftp); + break; } } @@ -1765,17 +1791,23 @@ static CURLcode ftp_epsv_disable(struct Curl_easy *data, } -static char *control_address(struct connectdata *conn) +static char *control_address_dup(struct Curl_easy *data, + struct connectdata *conn) { + struct ip_quadruple ipquad; + bool is_ipv6; + /* Returns the control connection IP address. If a proxy tunnel is used, returns the original hostname instead, because the effective control connection address is the proxy address, not the ftp host. */ #ifndef CURL_DISABLE_PROXY if(conn->bits.tunnel_proxy || conn->bits.socksproxy) - return conn->host.name; + return strdup(conn->host.name); #endif - return conn->primary.remote_ip; + if(!Curl_conn_get_ip_info(data, conn, FIRSTSOCKET, &is_ipv6, &ipquad)) + return strdup(ipquad.remote_ip); + return NULL; } static bool match_pasv_6nums(const char *p, @@ -1828,7 +1860,7 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data, return CURLE_FTP_WEIRD_PASV_REPLY; } ftpc->newport = (unsigned short)num; - ftpc->newhost = strdup(control_address(conn)); + ftpc->newhost = control_address_dup(data, conn); if(!ftpc->newhost) return CURLE_OUT_OF_MEMORY; } @@ -1872,7 +1904,7 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data, infof(data, "Skip %u.%u.%u.%u for data connection, reuse %s instead", ip[0], ip[1], ip[2], ip[3], conn->host.name); - ftpc->newhost = strdup(control_address(conn)); + ftpc->newhost = control_address_dup(data, conn); } else ftpc->newhost = aprintf("%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); @@ -1893,17 +1925,24 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data, #ifndef CURL_DISABLE_PROXY if(conn->bits.proxy) { - /* - * This connection uses a proxy and we need to connect to the proxy again + /* This connection uses a proxy and we need to connect to the proxy again * here. We do not want to rely on a former host lookup that might've - * expired now, instead we remake the lookup here and now! - */ + * expired now, instead we remake the lookup here and now! */ + struct ip_quadruple ipquad; + bool is_ipv6; const char * const host_name = conn->bits.socksproxy ? conn->socks_proxy.host.name : conn->http_proxy.host.name; - (void)Curl_resolv_blocking(data, host_name, conn->primary.remote_port, - conn->ip_version, &dns); + + result = Curl_conn_get_ip_info(data, data->conn, FIRSTSOCKET, + &is_ipv6, &ipquad); + if(result) + return result; + + (void)Curl_resolv_blocking(data, host_name, ipquad.remote_port, + is_ipv6 ? CURL_IPRESOLVE_V6 : CURL_IPRESOLVE_V4, + &dns); /* we connect to the proxy's port */ - connectport = (unsigned short)conn->primary.remote_port; + connectport = (unsigned short)ipquad.remote_port; if(!dns) { failf(data, "cannot resolve proxy host %s:%hu", host_name, connectport); @@ -1919,7 +1958,7 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data, /* postponed address resolution in case of tcp fastopen */ if(conn->bits.tcp_fastopen && !conn->bits.reuse && !ftpc->newhost[0]) { free(ftpc->newhost); - ftpc->newhost = strdup(control_address(conn)); + ftpc->newhost = control_address_dup(data, conn); if(!ftpc->newhost) return CURLE_OUT_OF_MEMORY; } @@ -2040,7 +2079,7 @@ static CURLcode client_write_header(struct Curl_easy *data, * the body write callback when data->set.include_header is set * via CURLOPT_HEADER. * For historic reasons, FTP never played this game and expects - * all its HEADERs to do that always. Set that flag during the + * all its headers to do that always. Set that flag during the * call to Curl_client_write() so it does the right thing. * * Notice that we cannot enable this flag for FTP in general, @@ -2198,6 +2237,8 @@ static CURLcode ftp_state_type_resp(struct Curl_easy *data, result = ftp_state_retr_prequote(data, ftpc, ftp); else if(instate == FTP_STOR_TYPE) result = ftp_state_stor_prequote(data, ftpc, ftp); + else if(instate == FTP_RETR_LIST_TYPE) + result = ftp_state_list_prequote(data, ftpc, ftp); return result; } @@ -2326,7 +2367,7 @@ static CURLcode ftp_state_size_resp(struct Curl_easy *data, if(instate == FTP_SIZE) { #ifdef CURL_FTP_HTTPSTYLE_HEAD - if(-1 != filesize) { + if(filesize != -1) { char clbuf[128]; int clbuflen = msnprintf(clbuf, sizeof(clbuf), "Content-Length: %" FMT_OFF_T "\r\n", filesize); @@ -2719,7 +2760,7 @@ static CURLcode ftp_pp_statemachine(struct Curl_easy *data, requested. Try an FTPS connection now */ ftpc->count3 = 0; - switch(data->set.ftpsslauth) { + switch((long)data->set.ftpsslauth) { case CURLFTPAUTH_DEFAULT: case CURLFTPAUTH_SSL: ftpc->count2 = 1; /* add one to get next */ @@ -2838,7 +2879,7 @@ static CURLcode ftp_pp_statemachine(struct Curl_easy *data, * server, but we do not send one. Let's hope other servers do * the same... */ result = Curl_ssl_cfilter_remove(data, FIRSTSOCKET, - (data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)); + (data->set.ftp_ccc == (unsigned char)CURLFTPSSL_CCC_ACTIVE)); if(result) failf(data, "Failed to clear the command channel (CCC)"); @@ -2961,7 +3002,7 @@ static CURLcode ftp_pp_statemachine(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; /* Check for special servers here. */ - if(strcasecompare(os, "OS/400")) { + if(curl_strequal(os, "OS/400")) { /* Force OS400 name format 1. */ result = Curl_pp_sendf(data, &ftpc->pp, "%s", "SITE NAMEFMT 1"); if(result) { @@ -3002,6 +3043,7 @@ static CURLcode ftp_pp_statemachine(struct Curl_easy *data, case FTP_POSTQUOTE: case FTP_RETR_PREQUOTE: case FTP_STOR_PREQUOTE: + case FTP_LIST_PREQUOTE: if((ftpcode >= 400) && !ftpc->count2) { /* failure response code, and not allowed to fail */ failf(data, "QUOT command failed with %03d", ftpcode); @@ -3071,6 +3113,7 @@ static CURLcode ftp_pp_statemachine(struct Curl_easy *data, case FTP_LIST_TYPE: case FTP_RETR_TYPE: case FTP_STOR_TYPE: + case FTP_RETR_LIST_TYPE: result = ftp_state_type_resp(data, ftpc, ftp, ftpcode, ftpc->state); break; @@ -3125,8 +3168,8 @@ static CURLcode ftp_pp_statemachine(struct Curl_easy *data, /* called repeatedly until done from multi.c */ static CURLcode ftp_statemach(struct Curl_easy *data, - struct ftp_conn *ftpc, - bool *done) + struct ftp_conn *ftpc, + bool *done) { CURLcode result = Curl_pp_statemach(data, &ftpc->pp, FALSE, FALSE); @@ -3407,7 +3450,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status, } } else { - if((-1 != data->req.size) && + if((data->req.size != -1) && (data->req.size != data->req.bytecount) && (data->req.maxdownload != data->req.bytecount)) { failf(data, "Received only partial file: %" FMT_OFF_T " bytes", @@ -3675,7 +3718,8 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) if(result) ; - else if(data->state.list_only || !ftpc->file) { + else if((data->state.list_only || !ftpc->file) && + !(data->set.prequote)) { /* The specified path ends with a slash, and therefore we think this is a directory that is requested, use LIST. But before that we need to set ASCII transfer mode. */ @@ -3689,8 +3733,14 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) /* otherwise just fall through */ } else { - result = ftp_nb_type(data, ftpc, ftp, data->state.prefer_ascii, - FTP_RETR_TYPE); + if(data->set.prequote && !ftpc->file) { + result = ftp_nb_type(data, ftpc, ftp, TRUE, + FTP_RETR_LIST_TYPE); + } + else { + result = ftp_nb_type(data, ftpc, ftp, data->state.prefer_ascii, + FTP_RETR_TYPE); + } if(result) return result; } @@ -4117,7 +4167,7 @@ static CURLcode ftp_disconnect(struct Curl_easy *data, will try to send the QUIT command, otherwise it will just return. */ ftpc->shutdown = TRUE; - if(dead_connection) + if(dead_connection || Curl_pp_needs_flush(data, &ftpc->pp)) ftpc->ctl_valid = FALSE; /* The FTP session may or may not have been allocated/setup at this point! */ diff --git a/vendor/curl/lib/ftp.h b/vendor/curl/lib/ftp.h index c31aa932861..52661981ef3 100644 --- a/vendor/curl/lib/ftp.h +++ b/vendor/curl/lib/ftp.h @@ -62,12 +62,14 @@ enum { FTP_QUOTE, /* waiting for a response to a command sent in a quote list */ FTP_RETR_PREQUOTE, FTP_STOR_PREQUOTE, + FTP_LIST_PREQUOTE, FTP_POSTQUOTE, FTP_CWD, /* change dir */ FTP_MKD, /* if the dir did not exist */ FTP_MDTM, /* to figure out the datestamp */ FTP_TYPE, /* to set type when doing a head-like request */ FTP_LIST_TYPE, /* set type when about to do a dir list */ + FTP_RETR_LIST_TYPE, FTP_RETR_TYPE, /* set type when about to RETR a file */ FTP_STOR_TYPE, /* set type when about to STOR a file */ FTP_SIZE, /* get the remote file's size for head-like request */ diff --git a/vendor/curl/lib/ftplistparser.c b/vendor/curl/lib/ftplistparser.c index 70939d6a76f..360f7ae4fca 100644 --- a/vendor/curl/lib/ftplistparser.c +++ b/vendor/curl/lib/ftplistparser.c @@ -396,407 +396,500 @@ static CURLcode unix_filetype(const char c, curlfiletype *t) return CURLE_OK; } -static CURLcode parse_unix(struct Curl_easy *data, - struct ftp_parselist_data *parser, - struct fileinfo *infop, - const char c) +static CURLcode parse_unix_totalsize(struct ftp_parselist_data *parser, + struct fileinfo *infop, + const char c) { - struct curl_fileinfo *finfo = &infop->info; size_t len = curlx_dyn_len(&infop->buf); char *mem = curlx_dyn_ptr(&infop->buf); - CURLcode result = CURLE_OK; - - switch(parser->state.UNIX.main) { - case PL_UNIX_TOTALSIZE: - switch(parser->state.UNIX.sub.total_dirsize) { - case PL_UNIX_TOTALSIZE_INIT: - if(c == 't') { - parser->state.UNIX.sub.total_dirsize = PL_UNIX_TOTALSIZE_READING; - parser->item_length++; - } - else { - parser->state.UNIX.main = PL_UNIX_FILETYPE; - /* continue to fall through */ - } - break; - case PL_UNIX_TOTALSIZE_READING: + switch(parser->state.UNIX.sub.total_dirsize) { + case PL_UNIX_TOTALSIZE_INIT: + if(c == 't') { + parser->state.UNIX.sub.total_dirsize = PL_UNIX_TOTALSIZE_READING; parser->item_length++; - if(c == '\r') { - parser->item_length--; - if(len) - curlx_dyn_setlen(&infop->buf, --len); - } - else if(c == '\n') { - mem[parser->item_length - 1] = 0; - if(!strncmp("total ", mem, 6)) { - const char *endptr = mem + 6; - /* here we can deal with directory size, pass the leading - whitespace and then the digits */ - curlx_str_passblanks(&endptr); - while(ISDIGIT(*endptr)) - endptr++; - if(*endptr) { - return CURLE_FTP_BAD_FILE_LIST; - } - parser->state.UNIX.main = PL_UNIX_FILETYPE; - curlx_dyn_reset(&infop->buf); - } - else + } + else { + parser->state.UNIX.main = PL_UNIX_FILETYPE; + /* continue to fall through */ + } + break; + case PL_UNIX_TOTALSIZE_READING: + parser->item_length++; + if(c == '\r') { + parser->item_length--; + if(len) + curlx_dyn_setlen(&infop->buf, --len); + } + else if(c == '\n') { + mem[parser->item_length - 1] = 0; + if(!strncmp("total ", mem, 6)) { + const char *endptr = mem + 6; + /* here we can deal with directory size, pass the leading + whitespace and then the digits */ + curlx_str_passblanks(&endptr); + while(ISDIGIT(*endptr)) + endptr++; + if(*endptr) { return CURLE_FTP_BAD_FILE_LIST; - + } + parser->state.UNIX.main = PL_UNIX_FILETYPE; + curlx_dyn_reset(&infop->buf); } - break; + else + return CURLE_FTP_BAD_FILE_LIST; + } - if(parser->state.UNIX.main != PL_UNIX_FILETYPE) - break; - FALLTHROUGH(); - case PL_UNIX_FILETYPE: - result = unix_filetype(c, &finfo->filetype); - if(result) - return result; - parser->state.UNIX.main = PL_UNIX_PERMISSION; - parser->item_length = 0; - parser->item_offset = 1; break; - case PL_UNIX_PERMISSION: - parser->item_length++; - if((parser->item_length <= 9) && !strchr("rwx-tTsS", c)) + } + return CURLE_OK; +} + +static CURLcode parse_unix_permission(struct ftp_parselist_data *parser, + struct fileinfo *infop, + const char c) +{ + char *mem = curlx_dyn_ptr(&infop->buf); + parser->item_length++; + if((parser->item_length <= 9) && !strchr("rwx-tTsS", c)) + return CURLE_FTP_BAD_FILE_LIST; + + else if(parser->item_length == 10) { + unsigned int perm; + if(c != ' ') return CURLE_FTP_BAD_FILE_LIST; - else if(parser->item_length == 10) { - unsigned int perm; - if(c != ' ') - return CURLE_FTP_BAD_FILE_LIST; + mem[10] = 0; /* terminate permissions */ + perm = ftp_pl_get_permission(mem + parser->item_offset); + if(perm & FTP_LP_MALFORMATED_PERM) + return CURLE_FTP_BAD_FILE_LIST; - mem[10] = 0; /* terminate permissions */ - perm = ftp_pl_get_permission(mem + parser->item_offset); - if(perm & FTP_LP_MALFORMATED_PERM) - return CURLE_FTP_BAD_FILE_LIST; + parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_PERM; + parser->file_data->info.perm = perm; + parser->offsets.perm = parser->item_offset; - parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_PERM; - parser->file_data->info.perm = perm; - parser->offsets.perm = parser->item_offset; + parser->item_length = 0; + parser->state.UNIX.main = PL_UNIX_HLINKS; + parser->state.UNIX.sub.hlinks = PL_UNIX_HLINKS_PRESPACE; + } + return CURLE_OK; +} - parser->item_length = 0; - parser->state.UNIX.main = PL_UNIX_HLINKS; - parser->state.UNIX.sub.hlinks = PL_UNIX_HLINKS_PRESPACE; +static CURLcode parse_unix_hlinks(struct ftp_parselist_data *parser, + struct fileinfo *infop, + const char c) +{ + size_t len = curlx_dyn_len(&infop->buf); + char *mem = curlx_dyn_ptr(&infop->buf); + + switch(parser->state.UNIX.sub.hlinks) { + case PL_UNIX_HLINKS_PRESPACE: + if(c != ' ') { + if(ISDIGIT(c) && len) { + parser->item_offset = len - 1; + parser->item_length = 1; + parser->state.UNIX.sub.hlinks = PL_UNIX_HLINKS_NUMBER; + } + else + return CURLE_FTP_BAD_FILE_LIST; } break; - case PL_UNIX_HLINKS: - switch(parser->state.UNIX.sub.hlinks) { - case PL_UNIX_HLINKS_PRESPACE: - if(c != ' ') { - if(ISDIGIT(c) && len) { - parser->item_offset = len - 1; - parser->item_length = 1; - parser->state.UNIX.sub.hlinks = PL_UNIX_HLINKS_NUMBER; - } - else - return CURLE_FTP_BAD_FILE_LIST; + case PL_UNIX_HLINKS_NUMBER: + parser->item_length ++; + if(c == ' ') { + const char *p = &mem[parser->item_offset]; + curl_off_t hlinks; + mem[parser->item_offset + parser->item_length - 1] = 0; + + if(!curlx_str_number(&p, &hlinks, LONG_MAX)) { + parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_HLINKCOUNT; + parser->file_data->info.hardlinks = (long)hlinks; } - break; - case PL_UNIX_HLINKS_NUMBER: - parser->item_length ++; - if(c == ' ') { - const char *p = &mem[parser->item_offset]; - curl_off_t hlinks; - mem[parser->item_offset + parser->item_length - 1] = 0; + parser->item_length = 0; + parser->item_offset = 0; + parser->state.UNIX.main = PL_UNIX_USER; + parser->state.UNIX.sub.user = PL_UNIX_USER_PRESPACE; + } + else if(!ISDIGIT(c)) + return CURLE_FTP_BAD_FILE_LIST; - if(!curlx_str_number(&p, &hlinks, LONG_MAX)) { - parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_HLINKCOUNT; - parser->file_data->info.hardlinks = (long)hlinks; - } - parser->item_length = 0; - parser->item_offset = 0; - parser->state.UNIX.main = PL_UNIX_USER; - parser->state.UNIX.sub.user = PL_UNIX_USER_PRESPACE; - } - else if(!ISDIGIT(c)) - return CURLE_FTP_BAD_FILE_LIST; + break; + } + return CURLE_OK; +} - break; +static CURLcode parse_unix_user(struct ftp_parselist_data *parser, + struct fileinfo *infop, + const char c) +{ + size_t len = curlx_dyn_len(&infop->buf); + char *mem = curlx_dyn_ptr(&infop->buf); + switch(parser->state.UNIX.sub.user) { + case PL_UNIX_USER_PRESPACE: + if(c != ' ' && len) { + parser->item_offset = len - 1; + parser->item_length = 1; + parser->state.UNIX.sub.user = PL_UNIX_USER_PARSING; } break; - case PL_UNIX_USER: - switch(parser->state.UNIX.sub.user) { - case PL_UNIX_USER_PRESPACE: - if(c != ' ' && len) { - parser->item_offset = len - 1; - parser->item_length = 1; - parser->state.UNIX.sub.user = PL_UNIX_USER_PARSING; - } - break; - case PL_UNIX_USER_PARSING: - parser->item_length++; - if(c == ' ') { - mem[parser->item_offset + parser->item_length - 1] = 0; - parser->offsets.user = parser->item_offset; - parser->state.UNIX.main = PL_UNIX_GROUP; - parser->state.UNIX.sub.group = PL_UNIX_GROUP_PRESPACE; - parser->item_offset = 0; - parser->item_length = 0; - } - break; + case PL_UNIX_USER_PARSING: + parser->item_length++; + if(c == ' ') { + mem[parser->item_offset + parser->item_length - 1] = 0; + parser->offsets.user = parser->item_offset; + parser->state.UNIX.main = PL_UNIX_GROUP; + parser->state.UNIX.sub.group = PL_UNIX_GROUP_PRESPACE; + parser->item_offset = 0; + parser->item_length = 0; } break; - case PL_UNIX_GROUP: - switch(parser->state.UNIX.sub.group) { - case PL_UNIX_GROUP_PRESPACE: - if(c != ' ' && len) { + } + return CURLE_OK; +} + +static CURLcode parse_unix_group(struct ftp_parselist_data *parser, + struct fileinfo *infop, + const char c) +{ + size_t len = curlx_dyn_len(&infop->buf); + char *mem = curlx_dyn_ptr(&infop->buf); + switch(parser->state.UNIX.sub.group) { + case PL_UNIX_GROUP_PRESPACE: + if(c != ' ' && len) { + parser->item_offset = len - 1; + parser->item_length = 1; + parser->state.UNIX.sub.group = PL_UNIX_GROUP_NAME; + } + break; + case PL_UNIX_GROUP_NAME: + parser->item_length++; + if(c == ' ') { + mem[parser->item_offset + parser->item_length - 1] = 0; + parser->offsets.group = parser->item_offset; + parser->state.UNIX.main = PL_UNIX_SIZE; + parser->state.UNIX.sub.size = PL_UNIX_SIZE_PRESPACE; + parser->item_offset = 0; + parser->item_length = 0; + } + break; + } + return CURLE_OK; +} + +static CURLcode parse_unix_size(struct ftp_parselist_data *parser, + struct fileinfo *infop, + const char c) +{ + size_t len = curlx_dyn_len(&infop->buf); + char *mem = curlx_dyn_ptr(&infop->buf); + switch(parser->state.UNIX.sub.size) { + case PL_UNIX_SIZE_PRESPACE: + if(c != ' ') { + if(ISDIGIT(c) && len) { parser->item_offset = len - 1; parser->item_length = 1; - parser->state.UNIX.sub.group = PL_UNIX_GROUP_NAME; + parser->state.UNIX.sub.size = PL_UNIX_SIZE_NUMBER; } - break; - case PL_UNIX_GROUP_NAME: - parser->item_length++; - if(c == ' ') { - mem[parser->item_offset + parser->item_length - 1] = 0; - parser->offsets.group = parser->item_offset; - parser->state.UNIX.main = PL_UNIX_SIZE; - parser->state.UNIX.sub.size = PL_UNIX_SIZE_PRESPACE; - parser->item_offset = 0; - parser->item_length = 0; - } - break; + else + return CURLE_FTP_BAD_FILE_LIST; } break; - case PL_UNIX_SIZE: - switch(parser->state.UNIX.sub.size) { - case PL_UNIX_SIZE_PRESPACE: - if(c != ' ') { - if(ISDIGIT(c) && len) { - parser->item_offset = len - 1; - parser->item_length = 1; - parser->state.UNIX.sub.size = PL_UNIX_SIZE_NUMBER; + case PL_UNIX_SIZE_NUMBER: + parser->item_length++; + if(c == ' ') { + const char *p = mem + parser->item_offset; + curl_off_t fsize; + mem[parser->item_offset + parser->item_length - 1] = 0; + if(!curlx_str_numblanks(&p, &fsize)) { + if(p[0] == '\0' && fsize != CURL_OFF_T_MAX) { + parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_SIZE; + parser->file_data->info.size = fsize; } - else - return CURLE_FTP_BAD_FILE_LIST; + parser->item_length = 0; + parser->item_offset = 0; + parser->state.UNIX.main = PL_UNIX_TIME; + parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART1; } - break; - case PL_UNIX_SIZE_NUMBER: - parser->item_length++; - if(c == ' ') { - const char *p = mem + parser->item_offset; - curl_off_t fsize; - mem[parser->item_offset + parser->item_length - 1] = 0; - if(!curlx_str_numblanks(&p, &fsize)) { - if(p[0] == '\0' && fsize != CURL_OFF_T_MAX) { - parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_SIZE; - parser->file_data->info.size = fsize; - } - parser->item_length = 0; - parser->item_offset = 0; - parser->state.UNIX.main = PL_UNIX_TIME; - parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART1; - } + } + else if(!ISDIGIT(c)) + return CURLE_FTP_BAD_FILE_LIST; + + break; + } + return CURLE_OK; +} + +static CURLcode parse_unix_time(struct ftp_parselist_data *parser, + struct fileinfo *infop, + const char c) +{ + size_t len = curlx_dyn_len(&infop->buf); + char *mem = curlx_dyn_ptr(&infop->buf); + struct curl_fileinfo *finfo = &infop->info; + + switch(parser->state.UNIX.sub.time) { + case PL_UNIX_TIME_PREPART1: + if(c != ' ') { + if(ISALNUM(c) && len) { + parser->item_offset = len -1; + parser->item_length = 1; + parser->state.UNIX.sub.time = PL_UNIX_TIME_PART1; } - else if(!ISDIGIT(c)) + else return CURLE_FTP_BAD_FILE_LIST; - - break; } break; - case PL_UNIX_TIME: - switch(parser->state.UNIX.sub.time) { - case PL_UNIX_TIME_PREPART1: - if(c != ' ') { - if(ISALNUM(c) && len) { - parser->item_offset = len -1; - parser->item_length = 1; - parser->state.UNIX.sub.time = PL_UNIX_TIME_PART1; - } - else - return CURLE_FTP_BAD_FILE_LIST; - } - break; - case PL_UNIX_TIME_PART1: - parser->item_length++; - if(c == ' ') - parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART2; + case PL_UNIX_TIME_PART1: + parser->item_length++; + if(c == ' ') + parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART2; - else if(!ISALNUM(c) && c != '.') - return CURLE_FTP_BAD_FILE_LIST; + else if(!ISALNUM(c) && c != '.') + return CURLE_FTP_BAD_FILE_LIST; - break; - case PL_UNIX_TIME_PREPART2: - parser->item_length++; - if(c != ' ') { - if(ISALNUM(c)) - parser->state.UNIX.sub.time = PL_UNIX_TIME_PART2; - else - return CURLE_FTP_BAD_FILE_LIST; - } - break; - case PL_UNIX_TIME_PART2: - parser->item_length++; - if(c == ' ') - parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART3; - else if(!ISALNUM(c) && c != '.') + break; + case PL_UNIX_TIME_PREPART2: + parser->item_length++; + if(c != ' ') { + if(ISALNUM(c)) + parser->state.UNIX.sub.time = PL_UNIX_TIME_PART2; + else return CURLE_FTP_BAD_FILE_LIST; - break; - case PL_UNIX_TIME_PREPART3: - parser->item_length++; - if(c != ' ') { - if(ISALNUM(c)) - parser->state.UNIX.sub.time = PL_UNIX_TIME_PART3; - else - return CURLE_FTP_BAD_FILE_LIST; - } - break; - case PL_UNIX_TIME_PART3: - parser->item_length++; - if(c == ' ') { - mem[parser->item_offset + parser->item_length -1] = 0; - parser->offsets.time = parser->item_offset; - if(finfo->filetype == CURLFILETYPE_SYMLINK) { - parser->state.UNIX.main = PL_UNIX_SYMLINK; - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRESPACE; - } - else { - parser->state.UNIX.main = PL_UNIX_FILENAME; - parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_PRESPACE; - } - } - else if(!ISALNUM(c) && c != '.' && c != ':') + } + break; + case PL_UNIX_TIME_PART2: + parser->item_length++; + if(c == ' ') + parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART3; + else if(!ISALNUM(c) && c != '.') + return CURLE_FTP_BAD_FILE_LIST; + break; + case PL_UNIX_TIME_PREPART3: + parser->item_length++; + if(c != ' ') { + if(ISALNUM(c)) + parser->state.UNIX.sub.time = PL_UNIX_TIME_PART3; + else return CURLE_FTP_BAD_FILE_LIST; - break; } break; - case PL_UNIX_FILENAME: - switch(parser->state.UNIX.sub.filename) { - case PL_UNIX_FILENAME_PRESPACE: - if(c != ' ' && len) { - parser->item_offset = len - 1; - parser->item_length = 1; - parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_NAME; - } - break; - case PL_UNIX_FILENAME_NAME: - parser->item_length++; - if(c == '\r') - parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_WINDOWSEOL; - - else if(c == '\n') { - mem[parser->item_offset + parser->item_length - 1] = 0; - parser->offsets.filename = parser->item_offset; - parser->state.UNIX.main = PL_UNIX_FILETYPE; - result = ftp_pl_insert_finfo(data, infop); - if(result) - return result; + case PL_UNIX_TIME_PART3: + parser->item_length++; + if(c == ' ') { + mem[parser->item_offset + parser->item_length -1] = 0; + parser->offsets.time = parser->item_offset; + if(finfo->filetype == CURLFILETYPE_SYMLINK) { + parser->state.UNIX.main = PL_UNIX_SYMLINK; + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRESPACE; } - break; - case PL_UNIX_FILENAME_WINDOWSEOL: - if(c == '\n') { - mem[parser->item_offset + parser->item_length - 1] = 0; - parser->offsets.filename = parser->item_offset; - parser->state.UNIX.main = PL_UNIX_FILETYPE; - result = ftp_pl_insert_finfo(data, infop); - if(result) - return result; + else { + parser->state.UNIX.main = PL_UNIX_FILENAME; + parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_PRESPACE; } - else - return CURLE_FTP_BAD_FILE_LIST; + } + else if(!ISALNUM(c) && c != '.' && c != ':') + return CURLE_FTP_BAD_FILE_LIST; + break; + } + return CURLE_OK; +} - break; +static CURLcode parse_unix_filename(struct Curl_easy *data, + struct ftp_parselist_data *parser, + struct fileinfo *infop, + const char c) +{ + size_t len = curlx_dyn_len(&infop->buf); + char *mem = curlx_dyn_ptr(&infop->buf); + CURLcode result = CURLE_OK; + + switch(parser->state.UNIX.sub.filename) { + case PL_UNIX_FILENAME_PRESPACE: + if(c != ' ' && len) { + parser->item_offset = len - 1; + parser->item_length = 1; + parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_NAME; } break; - case PL_UNIX_SYMLINK: - switch(parser->state.UNIX.sub.symlink) { - case PL_UNIX_SYMLINK_PRESPACE: - if(c != ' ' && len) { - parser->item_offset = len - 1; - parser->item_length = 1; - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; - } - break; - case PL_UNIX_SYMLINK_NAME: - parser->item_length++; - if(c == ' ') - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET1; + case PL_UNIX_FILENAME_NAME: + parser->item_length++; + if(c == '\r') + parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_WINDOWSEOL; + + else if(c == '\n') { + mem[parser->item_offset + parser->item_length - 1] = 0; + parser->offsets.filename = parser->item_offset; + parser->state.UNIX.main = PL_UNIX_FILETYPE; + result = ftp_pl_insert_finfo(data, infop); + } + break; + case PL_UNIX_FILENAME_WINDOWSEOL: + if(c == '\n') { + mem[parser->item_offset + parser->item_length - 1] = 0; + parser->offsets.filename = parser->item_offset; + parser->state.UNIX.main = PL_UNIX_FILETYPE; + result = ftp_pl_insert_finfo(data, infop); + } + else + result = CURLE_FTP_BAD_FILE_LIST; + break; + } + return result; +} - else if(c == '\r' || c == '\n') - return CURLE_FTP_BAD_FILE_LIST; +static CURLcode parse_unix_symlink(struct Curl_easy *data, + struct ftp_parselist_data *parser, + struct fileinfo *infop, + const char c) +{ + size_t len = curlx_dyn_len(&infop->buf); + char *mem = curlx_dyn_ptr(&infop->buf); + CURLcode result = CURLE_OK; - break; - case PL_UNIX_SYMLINK_PRETARGET1: - parser->item_length++; - if(c == '-') - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET2; + switch(parser->state.UNIX.sub.symlink) { + case PL_UNIX_SYMLINK_PRESPACE: + if(c != ' ' && len) { + parser->item_offset = len - 1; + parser->item_length = 1; + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; + } + break; + case PL_UNIX_SYMLINK_NAME: + parser->item_length++; + if(c == ' ') + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET1; - else if(c == '\r' || c == '\n') - return CURLE_FTP_BAD_FILE_LIST; - else - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; - break; - case PL_UNIX_SYMLINK_PRETARGET2: - parser->item_length++; - if(c == '>') - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET3; - else if(c == '\r' || c == '\n') - return CURLE_FTP_BAD_FILE_LIST; - else - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; + else if(c == '\r' || c == '\n') + return CURLE_FTP_BAD_FILE_LIST; - break; - case PL_UNIX_SYMLINK_PRETARGET3: - parser->item_length++; - if(c == ' ') { - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET4; - /* now place where is symlink following */ - mem[parser->item_offset + parser->item_length - 4] = 0; - parser->offsets.filename = parser->item_offset; - parser->item_length = 0; - parser->item_offset = 0; - } - else if(c == '\r' || c == '\n') - return CURLE_FTP_BAD_FILE_LIST; - else - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; - break; - case PL_UNIX_SYMLINK_PRETARGET4: - if(c != '\r' && c != '\n' && len) { - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_TARGET; - parser->item_offset = len - 1; - parser->item_length = 1; - } - else - return CURLE_FTP_BAD_FILE_LIST; + break; + case PL_UNIX_SYMLINK_PRETARGET1: + parser->item_length++; + if(c == '-') + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET2; - break; - case PL_UNIX_SYMLINK_TARGET: - parser->item_length++; - if(c == '\r') - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_WINDOWSEOL; + else if(c == '\r' || c == '\n') + return CURLE_FTP_BAD_FILE_LIST; + else + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; + break; + case PL_UNIX_SYMLINK_PRETARGET2: + parser->item_length++; + if(c == '>') + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET3; + else if(c == '\r' || c == '\n') + return CURLE_FTP_BAD_FILE_LIST; + else + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; - else if(c == '\n') { - mem[parser->item_offset + parser->item_length - 1] = 0; - parser->offsets.symlink_target = parser->item_offset; - result = ftp_pl_insert_finfo(data, infop); - if(result) - return result; + break; + case PL_UNIX_SYMLINK_PRETARGET3: + parser->item_length++; + if(c == ' ') { + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET4; + /* now place where is symlink following */ + mem[parser->item_offset + parser->item_length - 4] = 0; + parser->offsets.filename = parser->item_offset; + parser->item_length = 0; + parser->item_offset = 0; + } + else if(c == '\r' || c == '\n') + return CURLE_FTP_BAD_FILE_LIST; + else + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; + break; + case PL_UNIX_SYMLINK_PRETARGET4: + if(c != '\r' && c != '\n' && len) { + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_TARGET; + parser->item_offset = len - 1; + parser->item_length = 1; + } + else + return CURLE_FTP_BAD_FILE_LIST; - parser->state.UNIX.main = PL_UNIX_FILETYPE; - } - break; - case PL_UNIX_SYMLINK_WINDOWSEOL: - if(c == '\n') { - mem[parser->item_offset + parser->item_length - 1] = 0; - parser->offsets.symlink_target = parser->item_offset; - result = ftp_pl_insert_finfo(data, infop); - if(result) - return result; + break; + case PL_UNIX_SYMLINK_TARGET: + parser->item_length++; + if(c == '\r') + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_WINDOWSEOL; - parser->state.UNIX.main = PL_UNIX_FILETYPE; - } - else - return CURLE_FTP_BAD_FILE_LIST; + else if(c == '\n') { + mem[parser->item_offset + parser->item_length - 1] = 0; + parser->offsets.symlink_target = parser->item_offset; + result = ftp_pl_insert_finfo(data, infop); + if(result) + break; + + parser->state.UNIX.main = PL_UNIX_FILETYPE; + } + break; + case PL_UNIX_SYMLINK_WINDOWSEOL: + if(c == '\n') { + mem[parser->item_offset + parser->item_length - 1] = 0; + parser->offsets.symlink_target = parser->item_offset; + result = ftp_pl_insert_finfo(data, infop); + if(result) + break; + + parser->state.UNIX.main = PL_UNIX_FILETYPE; + } + else + result = CURLE_FTP_BAD_FILE_LIST; + + break; + } + return result; +} + +static CURLcode parse_unix(struct Curl_easy *data, + struct ftp_parselist_data *parser, + struct fileinfo *infop, + const char c) +{ + struct curl_fileinfo *finfo = &infop->info; + CURLcode result = CURLE_OK; + switch(parser->state.UNIX.main) { + case PL_UNIX_TOTALSIZE: + result = parse_unix_totalsize(parser, infop, c); + if(result) break; + if(parser->state.UNIX.main != PL_UNIX_FILETYPE) + break; + FALLTHROUGH(); + case PL_UNIX_FILETYPE: + result = unix_filetype(c, &finfo->filetype); + if(!result) { + parser->state.UNIX.main = PL_UNIX_PERMISSION; + parser->item_length = 0; + parser->item_offset = 1; } break; + case PL_UNIX_PERMISSION: + result = parse_unix_permission(parser, infop, c); + break; + case PL_UNIX_HLINKS: + result = parse_unix_hlinks(parser, infop, c); + break; + case PL_UNIX_USER: + result = parse_unix_user(parser, infop, c); + break; + case PL_UNIX_GROUP: + result = parse_unix_group(parser, infop, c); + break; + case PL_UNIX_SIZE: + result = parse_unix_size(parser, infop, c); + break; + case PL_UNIX_TIME: + result = parse_unix_time(parser, infop, c); + break; + case PL_UNIX_FILENAME: + result = parse_unix_filename(data, parser, infop, c); + break; + case PL_UNIX_SYMLINK: + result = parse_unix_symlink(data, parser, infop, c); + break; } - return CURLE_OK; + return result; } static CURLcode parse_winnt(struct Curl_easy *data, diff --git a/vendor/curl/lib/getinfo.c b/vendor/curl/lib/getinfo.c index 388646bf751..7ff78d2d6d7 100644 --- a/vendor/curl/lib/getinfo.c +++ b/vendor/curl/lib/getinfo.c @@ -28,6 +28,7 @@ #include "urldata.h" #include "getinfo.h" +#include "cfilters.h" #include "vtls/vtls.h" #include "connect.h" /* Curl_getconnectinfo() */ #include "progress.h" @@ -579,19 +580,14 @@ static CURLcode getinfo_slist(struct Curl_easy *data, CURLINFO info, struct curl_tlssessioninfo **tsip = (struct curl_tlssessioninfo **) param_slistp; struct curl_tlssessioninfo *tsi = &data->tsi; -#ifdef USE_SSL - struct connectdata *conn = data->conn; -#endif + /* we are exposing a pointer to internal memory with unknown + * lifetime here. */ *tsip = tsi; - tsi->backend = Curl_ssl_backend(); - tsi->internals = NULL; - -#ifdef USE_SSL - if(conn && tsi->backend != CURLSSLBACKEND_NONE) { - tsi->internals = Curl_ssl_get_internals(data, FIRSTSOCKET, info, 0); + if(!Curl_conn_get_ssl_info(data, data->conn, FIRSTSOCKET, tsi)) { + tsi->backend = Curl_ssl_backend(); + tsi->internals = NULL; } -#endif } break; default: diff --git a/vendor/curl/lib/gopher.c b/vendor/curl/lib/gopher.c index 68ccb59e408..93db85e9d02 100644 --- a/vendor/curl/lib/gopher.c +++ b/vendor/curl/lib/gopher.c @@ -70,10 +70,10 @@ const struct Curl_handler Curl_handler_gopher = { ZERO_NULL, /* connect_it */ ZERO_NULL, /* connecting */ ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* proto_pollset */ + ZERO_NULL, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ ZERO_NULL, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -96,10 +96,10 @@ const struct Curl_handler Curl_handler_gophers = { gopher_connect, /* connect_it */ gopher_connecting, /* connecting */ ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* proto_pollset */ + ZERO_NULL, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ ZERO_NULL, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -240,7 +240,7 @@ static CURLcode gopher_do(struct Curl_easy *data, bool *done) if(result) return result; - Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); return CURLE_OK; } #endif /* CURL_DISABLE_GOPHER */ diff --git a/vendor/curl/lib/hash.c b/vendor/curl/lib/hash.c index 8d13aae483a..89f47ed71e2 100644 --- a/vendor/curl/lib/hash.c +++ b/vendor/curl/lib/hash.c @@ -353,7 +353,7 @@ size_t Curl_hash_str(void *key, size_t key_length, size_t slots_num) } size_t curlx_str_key_compare(void *k1, size_t key1_len, - void *k2, size_t key2_len) + void *k2, size_t key2_len) { if((key1_len == key2_len) && !memcmp(k1, k2, key1_len)) return 1; diff --git a/vendor/curl/lib/hash.h b/vendor/curl/lib/hash.h index 314b811e4a4..fcd92db6645 100644 --- a/vendor/curl/lib/hash.h +++ b/vendor/curl/lib/hash.h @@ -99,7 +99,7 @@ void Curl_hash_clean_with_criterium(struct Curl_hash *h, void *user, int (*comp)(void *, void *)); size_t Curl_hash_str(void *key, size_t key_length, size_t slots_num); size_t curlx_str_key_compare(void *k1, size_t key1_len, void *k2, - size_t key2_len); + size_t key2_len); void Curl_hash_start_iterate(struct Curl_hash *hash, struct Curl_hash_iterator *iter); struct Curl_hash_element * diff --git a/vendor/curl/lib/headers.c b/vendor/curl/lib/headers.c index 71592a9c737..426d0e57b77 100644 --- a/vendor/curl/lib/headers.c +++ b/vendor/curl/lib/headers.c @@ -26,7 +26,6 @@ #include "urldata.h" #include "strdup.h" -#include "strcase.h" #include "sendf.h" #include "headers.h" #include "curlx/strparse.h" @@ -88,7 +87,7 @@ CURLHcode curl_easy_header(CURL *easy, /* we need a first round to count amount of this header */ for(e = Curl_llist_head(&data->state.httphdrs); e; e = Curl_node_next(e)) { hs = Curl_node_elem(e); - if(strcasecompare(hs->name, name) && + if(curl_strequal(hs->name, name) && (hs->type & type) && (hs->request == request)) { amount++; @@ -107,7 +106,7 @@ CURLHcode curl_easy_header(CURL *easy, else { for(e = Curl_llist_head(&data->state.httphdrs); e; e = Curl_node_next(e)) { hs = Curl_node_elem(e); - if(strcasecompare(hs->name, name) && + if(curl_strequal(hs->name, name) && (hs->type & type) && (hs->request == request) && (match++ == nameindex)) { @@ -173,7 +172,7 @@ struct curl_header *curl_easy_nextheader(CURL *easy, the index for the currently selected entry */ for(e = Curl_llist_head(&data->state.httphdrs); e; e = Curl_node_next(e)) { struct Curl_header_store *check = Curl_node_elem(e); - if(strcasecompare(hs->name, check->name) && + if(curl_strequal(hs->name, check->name) && (check->request == request) && (check->type & type)) amount++; diff --git a/vendor/curl/lib/hmac.c b/vendor/curl/lib/hmac.c index 3af1f292dac..5e7dd0df0c2 100644 --- a/vendor/curl/lib/hmac.c +++ b/vendor/curl/lib/hmac.c @@ -73,7 +73,8 @@ Curl_HMAC_init(const struct HMAC_params *hashparams, /* If the key is too long, replace it by its hash digest. */ if(keylen > hashparams->maxkeylen) { - hashparams->hinit(ctxt->hashctxt1); + if(hashparams->hinit(ctxt->hashctxt1)) + return NULL; hashparams->hupdate(ctxt->hashctxt1, key, keylen); hkey = (unsigned char *) ctxt->hashctxt2 + hashparams->ctxtsize; hashparams->hfinal(hkey, ctxt->hashctxt1); @@ -82,8 +83,9 @@ Curl_HMAC_init(const struct HMAC_params *hashparams, } /* Prime the two hash contexts with the modified key. */ - hashparams->hinit(ctxt->hashctxt1); - hashparams->hinit(ctxt->hashctxt2); + if(hashparams->hinit(ctxt->hashctxt1) || + hashparams->hinit(ctxt->hashctxt2)) + return NULL; for(i = 0; i < keylen; i++) { b = (unsigned char)(*key ^ hmac_ipad); diff --git a/vendor/curl/lib/hostip.c b/vendor/curl/lib/hostip.c index ca6724ed55d..74ed5c02778 100644 --- a/vendor/curl/lib/hostip.c +++ b/vendor/curl/lib/hostip.c @@ -54,7 +54,7 @@ #include "rand.h" #include "share.h" #include "url.h" -#include "inet_ntop.h" +#include "curlx/inet_ntop.h" #include "curlx/inet_pton.h" #include "multiif.h" #include "doh.h" @@ -145,14 +145,14 @@ void Curl_printable_address(const struct Curl_addrinfo *ai, char *buf, case AF_INET: { const struct sockaddr_in *sa4 = (const void *)ai->ai_addr; const struct in_addr *ipaddr4 = &sa4->sin_addr; - (void)Curl_inet_ntop(ai->ai_family, (const void *)ipaddr4, buf, bufsize); + (void)curlx_inet_ntop(ai->ai_family, (const void *)ipaddr4, buf, bufsize); break; } #ifdef USE_IPV6 case AF_INET6: { const struct sockaddr_in6 *sa6 = (const void *)ai->ai_addr; const struct in6_addr *ipaddr6 = &sa6->sin6_addr; - (void)Curl_inet_ntop(ai->ai_family, (const void *)ipaddr6, buf, bufsize); + (void)curlx_inet_ntop(ai->ai_family, (const void *)ipaddr6, buf, bufsize); break; } #endif @@ -180,9 +180,9 @@ create_dnscache_id(const char *name, } struct dnscache_prune_data { - time_t now; - time_t oldest; /* oldest time in cache not pruned. */ - int max_age_sec; + struct curltime now; + timediff_t oldest_ms; /* oldest time in cache not pruned. */ + timediff_t max_age_ms; }; /* @@ -199,36 +199,38 @@ dnscache_entry_is_stale(void *datap, void *hc) (struct dnscache_prune_data *) datap; struct Curl_dns_entry *dns = (struct Curl_dns_entry *) hc; - if(dns->timestamp) { - /* age in seconds */ - time_t age = prune->now - dns->timestamp; - if(age >= (time_t)prune->max_age_sec) + if(dns->timestamp.tv_sec || dns->timestamp.tv_usec) { + /* get age in milliseconds */ + timediff_t age = curlx_timediff(prune->now, dns->timestamp); + if(!dns->addr) + age *= 2; /* negative entries age twice as fast */ + if(age >= prune->max_age_ms) return TRUE; - if(age > prune->oldest) - prune->oldest = age; + if(age > prune->oldest_ms) + prune->oldest_ms = age; } return FALSE; } /* * Prune the DNS cache. This assumes that a lock has already been taken. - * Returns the 'age' of the oldest still kept entry. + * Returns the 'age' of the oldest still kept entry - in milliseconds. */ -static time_t -dnscache_prune(struct Curl_hash *hostcache, int cache_timeout, - time_t now) +static timediff_t +dnscache_prune(struct Curl_hash *hostcache, timediff_t cache_timeout_ms, + struct curltime now) { struct dnscache_prune_data user; - user.max_age_sec = cache_timeout; + user.max_age_ms = cache_timeout_ms; user.now = now; - user.oldest = 0; + user.oldest_ms = 0; Curl_hash_clean_with_criterium(hostcache, (void *) &user, dnscache_entry_is_stale); - return user.oldest; + return user.oldest_ms; } static struct Curl_dnscache *dnscache_get(struct Curl_easy *data) @@ -261,35 +263,49 @@ static void dnscache_unlock(struct Curl_easy *data, void Curl_dnscache_prune(struct Curl_easy *data) { struct Curl_dnscache *dnscache = dnscache_get(data); - time_t now; + struct curltime now; /* the timeout may be set -1 (forever) */ - int timeout = data->set.dns_cache_timeout; + timediff_t timeout_ms = data->set.dns_cache_timeout_ms; - if(!dnscache) + if(!dnscache || (timeout_ms == -1)) /* NULL hostcache means we cannot do it */ return; dnscache_lock(data, dnscache); - now = time(NULL); + now = curlx_now(); do { /* Remove outdated and unused entries from the hostcache */ - time_t oldest = dnscache_prune(&dnscache->entries, timeout, now); + timediff_t oldest_ms = dnscache_prune(&dnscache->entries, timeout_ms, now); - if(oldest < INT_MAX) - timeout = (int)oldest; /* we know it fits */ + if(Curl_hash_count(&dnscache->entries) > MAX_DNS_CACHE_SIZE) { + if(oldest_ms < INT_MAX) + /* prune the ones over half this age */ + timeout_ms = (int)oldest_ms / 2; + else + timeout_ms = INT_MAX/2; + } else - timeout = INT_MAX - 1; + break; - /* if the cache size is still too big, use the oldest age as new - prune limit */ - } while(timeout && - (Curl_hash_count(&dnscache->entries) > MAX_DNS_CACHE_SIZE)); + /* if the cache size is still too big, use the oldest age as new prune + limit */ + } while(timeout_ms); dnscache_unlock(data, dnscache); } +void Curl_dnscache_clear(struct Curl_easy *data) +{ + struct Curl_dnscache *dnscache = dnscache_get(data); + if(dnscache) { + dnscache_lock(data, dnscache); + Curl_hash_clean(&dnscache->entries); + dnscache_unlock(data, dnscache); + } +} + #ifdef USE_ALARM_TIMEOUT /* Beware this is a global and unique instance. This is used to store the return address that we can jump back to from inside a signal handler. This @@ -327,13 +343,13 @@ static struct Curl_dns_entry *fetch_addr(struct Curl_easy *data, dns = Curl_hash_pick(&dnscache->entries, entry_id, entry_len + 1); } - if(dns && (data->set.dns_cache_timeout != -1)) { + if(dns && (data->set.dns_cache_timeout_ms != -1)) { /* See whether the returned entry is stale. Done before we release lock */ struct dnscache_prune_data user; - user.now = time(NULL); - user.max_age_sec = data->set.dns_cache_timeout; - user.oldest = 0; + user.now = curlx_now(); + user.max_age_ms = data->set.dns_cache_timeout_ms; + user.oldest_ms = 0; if(dnscache_entry_is_stale(&user, dns)) { infof(data, "Hostname in DNS cache was stale, zapped"); @@ -505,6 +521,8 @@ Curl_dnscache_mk_entry(struct Curl_easy *data, return NULL; } } +#else + (void)data; #endif if(!hostlen) hostlen = strlen(hostname); @@ -518,12 +536,12 @@ Curl_dnscache_mk_entry(struct Curl_easy *data, dns->refcount = 1; /* the cache has the first reference */ dns->addr = addr; /* this is the address(es) */ - if(permanent) - dns->timestamp = 0; /* an entry that never goes stale */ + if(permanent) { + dns->timestamp.tv_sec = 0; /* an entry that never goes stale */ + dns->timestamp.tv_usec = 0; /* an entry that never goes stale */ + } else { - dns->timestamp = time(NULL); - if(dns->timestamp == 0) - dns->timestamp = 1; + dns->timestamp = curlx_now(); } dns->hostport = port; if(hostlen) @@ -730,7 +748,7 @@ static bool tailmatch(const char *full, size_t flen, { if(plen > flen) return FALSE; - return strncasecompare(part, &full[flen - plen], plen); + return curl_strnequal(part, &full[flen - plen], plen); } static struct Curl_addrinfo * @@ -782,6 +800,28 @@ static bool can_resolve_ip_version(struct Curl_easy *data, int ip_version) return TRUE; } +static CURLcode store_negative_resolve(struct Curl_easy *data, + const char *host, + int port) +{ + struct Curl_dnscache *dnscache = dnscache_get(data); + struct Curl_dns_entry *dns; + DEBUGASSERT(dnscache); + if(!dnscache) + return CURLE_FAILED_INIT; + + /* put this new host in the cache */ + dns = dnscache_add_addr(data, dnscache, NULL, host, 0, port, FALSE); + if(dns) { + /* release the returned reference; the cache itself will keep the + * entry alive: */ + dns->refcount--; + infof(data, "Store negative name resolve for %s:%d", host, port); + return CURLE_OK; + } + return CURLE_OUT_OF_MEMORY; +} + /* * Curl_resolv() is the main name resolve function within libcurl. It resolves * a name and returns a pointer to the entry in the 'entry' argument (if one @@ -872,8 +912,8 @@ CURLcode Curl_resolv(struct Curl_easy *data, goto error; if(!is_ipaddr && - (strcasecompare(hostname, "localhost") || - strcasecompare(hostname, "localhost.") || + (curl_strequal(hostname, "localhost") || + curl_strequal(hostname, "localhost.") || tailmatch(hostname, hostname_len, STRCONST(".localhost")) || tailmatch(hostname, hostname_len, STRCONST(".localhost.")))) { addr = get_localhost(port, hostname); @@ -901,6 +941,11 @@ CURLcode Curl_resolv(struct Curl_easy *data, * or `respwait` is set for an async operation. * Everything else is a failure to resolve. */ if(dns) { + if(!dns->addr) { + infof(data, "Negative DNS entry"); + dns->refcount--; + return CURLE_COULDNT_RESOLVE_HOST; + } *entry = dns; return CURLE_OK; } @@ -926,6 +971,7 @@ CURLcode Curl_resolv(struct Curl_easy *data, Curl_resolv_unlink(data, &dns); *entry = NULL; Curl_async_shutdown(data); + store_negative_resolve(data, hostname, port); return CURLE_COULDNT_RESOLVE_HOST; } @@ -1256,7 +1302,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) struct Curl_addrinfo *head = NULL, *tail = NULL; size_t entry_len; char address[64]; -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) +#ifndef CURL_DISABLE_VERBOSE_STRINGS const char *addresses = NULL; #endif curl_off_t port = 0; @@ -1281,7 +1327,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) curlx_str_single(&host, ':')) goto err; -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) +#ifndef CURL_DISABLE_VERBOSE_STRINGS addresses = host; #endif @@ -1501,31 +1547,36 @@ CURLcode Curl_resolv_check(struct Curl_easy *data, #ifndef CURL_DISABLE_DOH if(data->conn->bits.doh) { result = Curl_doh_is_resolved(data, dns); + if(result) + Curl_resolver_error(data); } else #endif result = Curl_async_is_resolved(data, dns); if(*dns) show_resolve_info(data, *dns); + if(result) + store_negative_resolve(data, data->state.async.hostname, + data->state.async.port); return result; } #endif -int Curl_resolv_getsock(struct Curl_easy *data, - curl_socket_t *socks) +CURLcode Curl_resolv_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { #ifdef CURLRES_ASYNCH #ifndef CURL_DISABLE_DOH if(data->conn->bits.doh) /* nothing to wait for during DoH resolve, those handles have their own sockets */ - return GETSOCK_BLANK; + return CURLE_OK; #endif - return Curl_async_getsock(data, socks); + return Curl_async_pollset(data, ps); #else (void)data; - (void)socks; - return GETSOCK_BLANK; + (void)ps; + return CURLE_OK; #endif } diff --git a/vendor/curl/lib/hostip.h b/vendor/curl/lib/hostip.h index cd3d957e1e7..633157782b0 100644 --- a/vendor/curl/lib/hostip.h +++ b/vendor/curl/lib/hostip.h @@ -47,12 +47,11 @@ #define CURL_TIMEOUT_RESOLVE 300 /* when using asynch methods, we allow this many seconds for a name resolve */ -#define CURL_ASYNC_SUCCESS CURLE_OK - struct addrinfo; struct hostent; struct Curl_easy; struct connectdata; +struct easy_pollset; enum alpnid { ALPN_none = 0, @@ -67,7 +66,7 @@ struct Curl_dns_entry { struct Curl_https_rrinfo *hinfo; #endif /* timestamp == 0 -- permanent CURLOPT_RESOLVE entry (does not time out) */ - time_t timestamp; + struct curltime timestamp; /* reference counter, entry is freed on reaching 0 */ size_t refcount; /* hostname port number that resolved to addr. */ @@ -130,6 +129,9 @@ void Curl_dnscache_destroy(struct Curl_dnscache *dns); /* prune old entries from the DNS cache */ void Curl_dnscache_prune(struct Curl_easy *data); +/* clear the DNS cache */ +void Curl_dnscache_clear(struct Curl_easy *data); + /* IPv4 threadsafe resolve function used for synch and asynch builds */ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port); @@ -196,8 +198,8 @@ CURLcode Curl_resolv_check(struct Curl_easy *data, #else #define Curl_resolv_check(x,y) CURLE_NOT_BUILT_IN #endif -int Curl_resolv_getsock(struct Curl_easy *data, - curl_socket_t *socks); +CURLcode Curl_resolv_pollset(struct Curl_easy *data, + struct easy_pollset *ps); CURLcode Curl_resolver_error(struct Curl_easy *data); diff --git a/vendor/curl/lib/hostip4.c b/vendor/curl/lib/hostip4.c index 14e4d98a866..2c356f3464e 100644 --- a/vendor/curl/lib/hostip4.c +++ b/vendor/curl/lib/hostip4.c @@ -94,8 +94,7 @@ struct Curl_addrinfo *Curl_sync_getaddrinfo(struct Curl_easy *data, #endif /* CURLRES_SYNCH */ #endif /* CURLRES_IPV4 */ -#if defined(CURLRES_IPV4) && \ - !defined(CURLRES_ARES) && !defined(CURLRES_AMIGA) +#if defined(CURLRES_IPV4) && !defined(CURLRES_ARES) && !defined(CURLRES_AMIGA) /* * Curl_ipv4_resolve_r() - ipv4 threadsafe resolver function. @@ -108,7 +107,7 @@ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port) { #if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE)) && \ - defined(HAVE_GETHOSTBYNAME_R_3) + defined(HAVE_GETHOSTBYNAME_R_3) int res; #endif struct Curl_addrinfo *ai = NULL; @@ -145,11 +144,11 @@ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, return NULL; /* major failure */ /* * The clearing of the buffer is a workaround for a gethostbyname_r bug in - * qnx nto and it is also _required_ for some of these functions on some + * QNX Neutrino and it is also _required_ for some of these functions on some * platforms. */ -#if defined(HAVE_GETHOSTBYNAME_R_5) +#ifdef HAVE_GETHOSTBYNAME_R_5 /* Solaris, IRIX and more */ h = gethostbyname_r(hostname, (struct hostent *)buf, @@ -287,5 +286,4 @@ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, return ai; } -#endif /* defined(CURLRES_IPV4) && !defined(CURLRES_ARES) && - !defined(CURLRES_AMIGA) */ +#endif /* CURLRES_IPV4 && !CURLRES_ARES && !CURLRES_AMIGA */ diff --git a/vendor/curl/lib/hostip6.c b/vendor/curl/lib/hostip6.c index 35cc2d737bb..4c05f0247e1 100644 --- a/vendor/curl/lib/hostip6.c +++ b/vendor/curl/lib/hostip6.c @@ -44,6 +44,7 @@ #endif #include "urldata.h" +#include "cfilters.h" #include "sendf.h" #include "hostip.h" #include "hash.h" @@ -56,7 +57,7 @@ #include "curl_memory.h" #include "memdebug.h" -#if defined(CURLRES_SYNCH) +#ifdef CURLRES_SYNCH #ifdef DEBUG_ADDRINFO static void dump_addrinfo(const struct Curl_addrinfo *ai) @@ -104,7 +105,8 @@ struct Curl_addrinfo *Curl_sync_getaddrinfo(struct Curl_easy *data, memset(&hints, 0, sizeof(hints)); hints.ai_family = pf; - hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP) ? + hints.ai_socktype = + (Curl_conn_get_transport(data, data->conn) == TRNSPRT_TCP) ? SOCK_STREAM : SOCK_DGRAM; #ifndef USE_RESOLVE_ON_IPS @@ -112,8 +114,8 @@ struct Curl_addrinfo *Curl_sync_getaddrinfo(struct Curl_easy *data, * The AI_NUMERICHOST must not be set to get synthesized IPv6 address from * an IPv4 address on iOS and macOS. */ - if((1 == curlx_inet_pton(AF_INET, hostname, addrbuf)) || - (1 == curlx_inet_pton(AF_INET6, hostname, addrbuf))) { + if((curlx_inet_pton(AF_INET, hostname, addrbuf) == 1) || + (curlx_inet_pton(AF_INET6, hostname, addrbuf) == 1)) { /* the given address is numerical only, prevent a reverse lookup */ hints.ai_flags = AI_NUMERICHOST; } diff --git a/vendor/curl/lib/hsts.c b/vendor/curl/lib/hsts.c index 62a3f890589..91f32276f95 100644 --- a/vendor/curl/lib/hsts.c +++ b/vendor/curl/lib/hsts.c @@ -33,7 +33,6 @@ #include "llist.h" #include "hsts.h" #include "curl_get_line.h" -#include "strcase.h" #include "sendf.h" #include "parsedate.h" #include "fopen.h" @@ -155,7 +154,7 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname, do { curlx_str_passblanks(&p); - if(strncasecompare("max-age", p, 7)) { + if(curl_strnequal("max-age", p, 7)) { bool quoted = FALSE; int rc; @@ -185,7 +184,7 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname, } gotma = TRUE; } - else if(strncasecompare("includesubdomains", p, 17)) { + else if(curl_strnequal("includesubdomains", p, 17)) { if(gotinc) return CURLE_BAD_FUNCTION_ARGUMENT; subdomains = TRUE; @@ -272,15 +271,15 @@ struct stsentry *Curl_hsts(struct hsts *h, const char *hostname, if((subdomain && sts->includeSubDomains) && (ntail < hlen)) { size_t offs = hlen - ntail; if((hostname[offs-1] == '.') && - strncasecompare(&hostname[offs], sts->host, ntail) && + curl_strnequal(&hostname[offs], sts->host, ntail) && (ntail > blen)) { /* save the tail match with the longest tail */ bestsub = sts; blen = ntail; } } - /* avoid strcasecompare because the host name is not null-terminated */ - if((hlen == ntail) && strncasecompare(hostname, sts->host, hlen)) + /* avoid curl_strequal because the host name is not null-terminated */ + if((hlen == ntail) && curl_strnequal(hostname, sts->host, hlen)) return sts; } } @@ -581,4 +580,8 @@ void Curl_hsts_loadfiles(struct Curl_easy *data) } } +#if defined(DEBUGBUILD) || defined(UNITTESTS) +#undef time +#endif + #endif /* CURL_DISABLE_HTTP || CURL_DISABLE_HSTS */ diff --git a/vendor/curl/lib/http.c b/vendor/curl/lib/http.c index 5942d313b87..06ab3f16459 100644 --- a/vendor/curl/lib/http.c +++ b/vendor/curl/lib/http.c @@ -137,10 +137,10 @@ const struct Curl_handler Curl_handler_http = { Curl_http_connect, /* connect_it */ ZERO_NULL, /* connecting */ ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - Curl_http_getsock_do, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* proto_pollset */ + Curl_http_do_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ ZERO_NULL, /* disconnect */ Curl_http_write_resp, /* write_resp */ Curl_http_write_resp_hd, /* write_resp_hd */ @@ -167,10 +167,10 @@ const struct Curl_handler Curl_handler_https = { Curl_http_connect, /* connect_it */ NULL, /* connecting */ ZERO_NULL, /* doing */ - NULL, /* proto_getsock */ - Curl_http_getsock_do, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + NULL, /* proto_pollset */ + Curl_http_do_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ ZERO_NULL, /* disconnect */ Curl_http_write_resp, /* write_resp */ Curl_http_write_resp_hd, /* write_resp_hd */ @@ -232,7 +232,7 @@ CURLcode Curl_http_setup_conn(struct Curl_easy *data, connkeep(conn, "HTTP default"); if(data->state.http_neg.wanted == CURL_HTTP_V3x) { /* only HTTP/3, needs to work */ - CURLcode result = Curl_conn_may_http3(data, conn); + CURLcode result = Curl_conn_may_http3(data, conn, conn->transport_wanted); if(result) return result; } @@ -259,7 +259,7 @@ char *Curl_checkProxyheaders(struct Curl_easy *data, for(head = (conn->bits.proxy && data->set.sep_headers) ? data->set.proxyheaders : data->set.headers; head; head = head->next) { - if(strncasecompare(head->data, thisheader, thislen) && + if(curl_strnequal(head->data, thisheader, thislen) && Curl_headersep(head->data[thislen])) return head->data; } @@ -474,7 +474,7 @@ static CURLcode http_perhapsrewind(struct Curl_easy *data, if(abort_upload) { /* We'd like to abort the upload - but should we? */ -#if defined(USE_NTLM) +#ifdef USE_NTLM if((data->state.authproxy.picked == CURLAUTH_NTLM) || (data->state.authhost.picked == CURLAUTH_NTLM)) { ongoing_auth = "NTLM"; @@ -486,7 +486,7 @@ static CURLcode http_perhapsrewind(struct Curl_easy *data, } } #endif -#if defined(USE_SPNEGO) +#ifdef USE_SPNEGO /* There is still data left to send */ if((data->state.authproxy.picked == CURLAUTH_NEGOTIATE) || (data->state.authhost.picked == CURLAUTH_NEGOTIATE)) { @@ -862,7 +862,7 @@ static bool authcmp(const char *auth, const char *line) { /* the auth string must not have an alnum following */ size_t n = strlen(auth); - return strncasecompare(auth, line, n) && !ISALNUM(line[n]); + return curl_strnequal(auth, line, n) && !ISALNUM(line[n]); } #endif @@ -1077,7 +1077,9 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, } return result; #else - (void) proxy; + (void)data; + (void)proxy; + (void)auth; /* nothing to do when disabled */ return CURLE_OK; #endif @@ -1321,7 +1323,7 @@ CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl, data->info.wouldredirect = follow_url; if(reachedmax) { - failf(data, "Maximum (%ld) redirects followed", data->set.maxredirs); + failf(data, "Maximum (%d) redirects followed", data->set.maxredirs); return CURLE_TOO_MANY_REDIRECTS; } return CURLE_OK; @@ -1482,7 +1484,7 @@ Curl_compareheader(const char *headerline, /* line to check */ DEBUGASSERT(header); DEBUGASSERT(content); - if(!strncasecompare(headerline, header, hlen)) + if(!curl_strnequal(headerline, header, hlen)) return FALSE; /* does not start with header */ /* pass the header */ @@ -1497,7 +1499,7 @@ Curl_compareheader(const char *headerline, /* line to check */ size_t len; p = curlx_str(&val); for(len = curlx_strlen(&val); len >= curlx_strlen(&val); len--, p++) { - if(strncasecompare(p, content, clen)) + if(curl_strnequal(p, content, clen)) return TRUE; /* match! */ } } @@ -1522,14 +1524,11 @@ CURLcode Curl_http_connect(struct Curl_easy *data, bool *done) /* this returns the socket to wait for in the DO and DOING state for the multi interface and then we are always _sending_ a request and thus we wait for the single socket to become writable only */ -int Curl_http_getsock_do(struct Curl_easy *data, - struct connectdata *conn, - curl_socket_t *socks) +CURLcode Curl_http_do_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { /* write mode */ - (void)conn; - socks[0] = Curl_conn_get_socket(data, FIRSTSOCKET); - return GETSOCK_WRITESOCK(0); + return Curl_pollset_add_out(data, ps, data->conn->sock[FIRSTSOCKET]); } /* @@ -1823,7 +1822,9 @@ void Curl_http_method(struct Curl_easy *data, struct connectdata *conn, { Curl_HttpReq httpreq = (Curl_HttpReq)data->state.httpreq; const char *request; - if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) && + if(conn->handler->protocol&(CURLPROTO_WS|CURLPROTO_WSS)) + httpreq = HTTPREQ_GET; + else if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) && data->state.upload) httpreq = HTTPREQ_PUT; @@ -1893,8 +1894,8 @@ static CURLcode http_host(struct Curl_easy *data, struct connectdata *conn) ptr = Curl_checkheaders(data, STRCONST("Host")); if(ptr && (!data->state.this_is_a_follow || - strcasecompare(data->state.first_host, conn->host.name))) { -#if !defined(CURL_DISABLE_COOKIES) + curl_strequal(data->state.first_host, conn->host.name))) { +#ifndef CURL_DISABLE_COOKIES /* If we have a given custom Host: header, we extract the hostname in order to possibly use it for cookie reasons later on. We only allow the custom Host: header if this is NOT a redirect, as setting Host: in the @@ -1929,7 +1930,7 @@ static CURLcode http_host(struct Curl_easy *data, struct connectdata *conn) } #endif - if(!strcasecompare("Host:", ptr)) { + if(!curl_strequal("Host:", ptr)) { aptr->host = aprintf("Host:%s\r\n", &ptr[5]); if(!aptr->host) return CURLE_OUT_OF_MEMORY; @@ -2005,7 +2006,7 @@ static CURLcode http_target(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; } - if(strcasecompare("http", data->state.up.scheme)) { + if(curl_strequal("http", data->state.up.scheme)) { /* when getting HTTP, we do not want the userinfo the URL */ uc = curl_url_set(h, CURLUPART_USER, NULL, 0); if(uc) { @@ -2034,7 +2035,7 @@ static CURLcode http_target(struct Curl_easy *data, if(result) return result; - if(strcasecompare("ftp", data->state.up.scheme)) { + if(curl_strequal("ftp", data->state.up.scheme)) { if(data->set.proxy_transfer_mode) { /* when doing ftp, append ;type= if not present */ char *type = strstr(path, ";type="); @@ -2415,12 +2416,12 @@ static CURLcode http_req_complete(struct Curl_easy *data, out: if(!result) { /* setup variables for the upcoming transfer */ - Curl_xfer_setup1(data, CURL_XFER_SENDRECV, -1, TRUE); + Curl_xfer_setup_sendrecv(data, FIRSTSOCKET, -1); } return result; } -#if !defined(CURL_DISABLE_COOKIES) +#ifndef CURL_DISABLE_COOKIES static CURLcode http_cookies(struct Curl_easy *data, struct connectdata *conn, @@ -2443,7 +2444,7 @@ static CURLcode http_cookies(struct Curl_easy *data, data->state.aptr.cookiehost : conn->host.name; const bool secure_context = conn->handler->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS) || - strcasecompare("localhost", host) || + curl_strequal("localhost", host) || !strcmp(host, "127.0.0.1") || !strcmp(host, "::1"); Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); @@ -2671,43 +2672,49 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) char *altused = NULL; const char *p_accept; /* Accept: string */ unsigned char httpversion; + const char *alpn; + const char *info_version = NULL; /* Always consider the DO phase done after this function call, even if there may be parts of the request that are not yet sent, since we can deal with the rest of the request in the PERFORM phase. */ *done = TRUE; - - switch(conn->alpn) { - case CURL_HTTP_VERSION_3: + alpn = Curl_conn_get_alpn_negotiated(data, conn); + if(alpn && !strcmp("h3", alpn)) { DEBUGASSERT(Curl_conn_http_version(data, conn) == 30); - break; - case CURL_HTTP_VERSION_2: + info_version = "HTTP/3"; + } + else if(alpn && !strcmp("h2", alpn)) { #ifndef CURL_DISABLE_PROXY if((Curl_conn_http_version(data, conn) != 20) && - conn->bits.proxy && !conn->bits.tunnel_proxy - ) { + conn->bits.proxy && !conn->bits.tunnel_proxy) { result = Curl_http2_switch(data); if(result) goto fail; } else #endif - DEBUGASSERT(Curl_conn_http_version(data, conn) == 20); - break; - case CURL_HTTP_VERSION_1_1: - /* continue with HTTP/1.x when explicitly requested */ - break; - default: + DEBUGASSERT(Curl_conn_http_version(data, conn) == 20); + info_version = "HTTP/2"; + } + else { /* Check if user wants to use HTTP/2 with clear TCP */ if(Curl_http2_may_switch(data)) { DEBUGF(infof(data, "HTTP/2 over clean TCP")); result = Curl_http2_switch(data); if(result) goto fail; + info_version = "HTTP/2"; + /* There is no ALPN here, but the connection is now definitely h2 */ + conn->httpversion_seen = 20; } - break; + else + info_version = "HTTP/1.x"; } + if(info_version && !data->conn->bits.reuse) + infof(data, "using %s", info_version); + /* Add collecting of headers written to client. For a new connection, * we might have done that already, but reuse * or multiplex needs it here as well. */ @@ -3001,376 +3008,488 @@ checkprotoprefix(struct Curl_easy *data, struct connectdata *conn, Curl_compareheader(hd, STRCONST(n), STRCONST(v))) /* - * http_header() parses a single response header. + * http_header_a() parses a single response header starting with A. */ -static CURLcode http_header(struct Curl_easy *data, - const char *hd, size_t hdlen) +static CURLcode http_header_a(struct Curl_easy *data, + const char *hd, size_t hdlen) { - struct connectdata *conn = data->conn; - CURLcode result; - struct SingleRequest *k = &data->req; - const char *v; - - switch(hd[0]) { - case 'a': - case 'A': #ifndef CURL_DISABLE_ALTSVC - v = (data->asi && - (Curl_conn_is_ssl(data->conn, FIRSTSOCKET) || + const char *v; + struct connectdata *conn = data->conn; + v = (data->asi && + (Curl_conn_is_ssl(data->conn, FIRSTSOCKET) || #ifdef DEBUGBUILD - /* allow debug builds to circumvent the HTTPS restriction */ - getenv("CURL_ALTSVC_HTTP") + /* allow debug builds to circumvent the HTTPS restriction */ + getenv("CURL_ALTSVC_HTTP") #else - 0 + 0 #endif - )) ? HD_VAL(hd, hdlen, "Alt-Svc:") : NULL; - if(v) { - /* the ALPN of the current request */ - enum alpnid id = (k->httpversion == 30) ? ALPN_h3 : - (k->httpversion == 20) ? ALPN_h2 : ALPN_h1; - return Curl_altsvc_parse(data, data->asi, v, id, conn->host.name, - curlx_uitous((unsigned int)conn->remote_port)); - } + )) ? HD_VAL(hd, hdlen, "Alt-Svc:") : NULL; + if(v) { + /* the ALPN of the current request */ + struct SingleRequest *k = &data->req; + enum alpnid id = (k->httpversion == 30) ? ALPN_h3 : + (k->httpversion == 20) ? ALPN_h2 : ALPN_h1; + return Curl_altsvc_parse(data, data->asi, v, id, conn->host.name, + curlx_uitous((unsigned int)conn->remote_port)); + } +#else + (void)data; + (void)hd; + (void)hdlen; #endif - break; - case 'c': - case 'C': - /* Check for Content-Length: header lines to get size */ - v = (!k->http_bodyless && !data->set.ignorecl) ? - HD_VAL(hd, hdlen, "Content-Length:") : NULL; - if(v) { - curl_off_t contentlength; - int offt = curlx_str_numblanks(&v, &contentlength); - - if(offt == STRE_OK) { - k->size = contentlength; - k->maxdownload = k->size; - } - else if(offt == STRE_OVERFLOW) { - /* out of range */ - if(data->set.max_filesize) { - failf(data, "Maximum file size exceeded"); - return CURLE_FILESIZE_EXCEEDED; - } - streamclose(conn, "overflow content-length"); - infof(data, "Overflow Content-Length: value"); - } - else { - /* negative or just rubbish - bad HTTP */ - failf(data, "Invalid Content-Length: value"); - return CURLE_WEIRD_SERVER_REPLY; - } - return CURLE_OK; - } - v = (!k->http_bodyless && data->set.str[STRING_ENCODING]) ? - HD_VAL(hd, hdlen, "Content-Encoding:") : NULL; - if(v) { - /* - * Process Content-Encoding. Look for the values: identity, - * gzip, deflate, compress, x-gzip and x-compress. x-gzip and - * x-compress are the same as gzip and compress. (Sec 3.5 RFC - * 2616). zlib cannot handle compress. However, errors are - * handled further down when the response body is processed - */ - return Curl_build_unencoding_stack(data, v, FALSE); + return CURLE_OK; +} + +/* + * http_header_c() parses a single response header starting with C. + */ +static CURLcode http_header_c(struct Curl_easy *data, + const char *hd, size_t hdlen) +{ + struct connectdata *conn = data->conn; + struct SingleRequest *k = &data->req; + const char *v; + + /* Check for Content-Length: header lines to get size */ + v = (!k->http_bodyless && !data->set.ignorecl) ? + HD_VAL(hd, hdlen, "Content-Length:") : NULL; + if(v) { + curl_off_t contentlength; + int offt = curlx_str_numblanks(&v, &contentlength); + + if(offt == STRE_OK) { + k->size = contentlength; + k->maxdownload = k->size; } - /* check for Content-Type: header lines to get the MIME-type */ - v = HD_VAL(hd, hdlen, "Content-Type:"); - if(v) { - char *contenttype = Curl_copy_header_value(hd); - if(!contenttype) - return CURLE_OUT_OF_MEMORY; - if(!*contenttype) - /* ignore empty data */ - free(contenttype); - else { - free(data->info.contenttype); - data->info.contenttype = contenttype; + else if(offt == STRE_OVERFLOW) { + /* out of range */ + if(data->set.max_filesize) { + failf(data, "Maximum file size exceeded"); + return CURLE_FILESIZE_EXCEEDED; } - return CURLE_OK; + streamclose(conn, "overflow content-length"); + infof(data, "Overflow Content-Length: value"); } - if(HD_IS_AND_SAYS(hd, hdlen, "Connection:", "close")) { - /* - * [RFC 2616, section 8.1.2.1] - * "Connection: close" is HTTP/1.1 language and means that - * the connection will close when this request has been - * served. - */ - streamclose(conn, "Connection: close used"); - return CURLE_OK; - } - if((k->httpversion == 10) && - HD_IS_AND_SAYS(hd, hdlen, "Connection:", "keep-alive")) { - /* - * An HTTP/1.0 reply with the 'Connection: keep-alive' line - * tells us the connection will be kept alive for our - * pleasure. Default action for 1.0 is to close. - * - * [RFC2068, section 19.7.1] */ - connkeep(conn, "Connection keep-alive"); - infof(data, "HTTP/1.0 connection set to keep alive"); - return CURLE_OK; + else { + /* negative or just rubbish - bad HTTP */ + failf(data, "Invalid Content-Length: value"); + return CURLE_WEIRD_SERVER_REPLY; } - v = !k->http_bodyless ? HD_VAL(hd, hdlen, "Content-Range:") : NULL; - if(v) { - /* Content-Range: bytes [num]- - Content-Range: bytes: [num]- - Content-Range: [num]- - Content-Range: [asterisk]/[total] - - The second format was added since Sun's webserver - JavaWebServer/1.1.1 obviously sends the header this way! - The third added since some servers use that! - The fourth means the requested range was unsatisfied. - */ - - const char *ptr = v; - - /* Move forward until first digit or asterisk */ - while(*ptr && !ISDIGIT(*ptr) && *ptr != '*') - ptr++; - - /* if it truly stopped on a digit */ - if(ISDIGIT(*ptr)) { - if(!curlx_str_number(&ptr, &k->offset, CURL_OFF_T_MAX) && - (data->state.resume_from == k->offset)) - /* we asked for a resume and we got it */ - k->content_range = TRUE; - } - else if(k->httpcode < 300) - data->state.resume_from = 0; /* get everything */ + return CURLE_OK; + } + v = (!k->http_bodyless && data->set.str[STRING_ENCODING]) ? + HD_VAL(hd, hdlen, "Content-Encoding:") : NULL; + if(v) { + /* + * Process Content-Encoding. Look for the values: identity, + * gzip, deflate, compress, x-gzip and x-compress. x-gzip and + * x-compress are the same as gzip and compress. (Sec 3.5 RFC + * 2616). zlib cannot handle compress. However, errors are + * handled further down when the response body is processed + */ + return Curl_build_unencoding_stack(data, v, FALSE); + } + /* check for Content-Type: header lines to get the MIME-type */ + v = HD_VAL(hd, hdlen, "Content-Type:"); + if(v) { + char *contenttype = Curl_copy_header_value(hd); + if(!contenttype) + return CURLE_OUT_OF_MEMORY; + if(!*contenttype) + /* ignore empty data */ + free(contenttype); + else { + free(data->info.contenttype); + data->info.contenttype = contenttype; } - break; - case 'l': - case 'L': - v = (!k->http_bodyless && - (data->set.timecondition || data->set.get_filetime)) ? - HD_VAL(hd, hdlen, "Last-Modified:") : NULL; - if(v) { - k->timeofdoc = Curl_getdate_capped(v); - if(data->set.get_filetime) - data->info.filetime = k->timeofdoc; - return CURLE_OK; + return CURLE_OK; + } + if(HD_IS_AND_SAYS(hd, hdlen, "Connection:", "close")) { + /* + * [RFC 2616, section 8.1.2.1] + * "Connection: close" is HTTP/1.1 language and means that + * the connection will close when this request has been + * served. + */ + streamclose(conn, "Connection: close used"); + return CURLE_OK; + } + if((k->httpversion == 10) && + HD_IS_AND_SAYS(hd, hdlen, "Connection:", "keep-alive")) { + /* + * An HTTP/1.0 reply with the 'Connection: keep-alive' line + * tells us the connection will be kept alive for our + * pleasure. Default action for 1.0 is to close. + * + * [RFC2068, section 19.7.1] */ + connkeep(conn, "Connection keep-alive"); + infof(data, "HTTP/1.0 connection set to keep alive"); + return CURLE_OK; + } + v = !k->http_bodyless ? HD_VAL(hd, hdlen, "Content-Range:") : NULL; + if(v) { + /* Content-Range: bytes [num]- + Content-Range: bytes: [num]- + Content-Range: [num]- + Content-Range: [asterisk]/[total] + + The second format was added since Sun's webserver + JavaWebServer/1.1.1 obviously sends the header this way! + The third added since some servers use that! + The fourth means the requested range was unsatisfied. + */ + + const char *ptr = v; + + /* Move forward until first digit or asterisk */ + while(*ptr && !ISDIGIT(*ptr) && *ptr != '*') + ptr++; + + /* if it truly stopped on a digit */ + if(ISDIGIT(*ptr)) { + if(!curlx_str_number(&ptr, &k->offset, CURL_OFF_T_MAX) && + (data->state.resume_from == k->offset)) + /* we asked for a resume and we got it */ + k->content_range = TRUE; } - if((k->httpcode >= 300 && k->httpcode < 400) && - HD_IS(hd, hdlen, "Location:") && - !data->req.location) { - /* this is the URL that the server advises us to use instead */ - char *location = Curl_copy_header_value(hd); - if(!location) - return CURLE_OUT_OF_MEMORY; - if(!*location) - /* ignore empty data */ - free(location); - else { - data->req.location = location; + else if(k->httpcode < 300) + data->state.resume_from = 0; /* get everything */ + } + return CURLE_OK; +} - if(data->set.http_follow_mode) { - DEBUGASSERT(!data->req.newurl); - data->req.newurl = strdup(data->req.location); /* clone */ - if(!data->req.newurl) - return CURLE_OUT_OF_MEMORY; +/* + * http_header_l() parses a single response header starting with L. + */ +static CURLcode http_header_l(struct Curl_easy *data, + const char *hd, size_t hdlen) +{ + struct connectdata *conn = data->conn; + struct SingleRequest *k = &data->req; + const char *v = (!k->http_bodyless && + (data->set.timecondition || data->set.get_filetime)) ? + HD_VAL(hd, hdlen, "Last-Modified:") : NULL; + if(v) { + k->timeofdoc = Curl_getdate_capped(v); + if(data->set.get_filetime) + data->info.filetime = k->timeofdoc; + return CURLE_OK; + } + if((k->httpcode >= 300 && k->httpcode < 400) && + HD_IS(hd, hdlen, "Location:") && + !data->req.location) { + /* this is the URL that the server advises us to use instead */ + char *location = Curl_copy_header_value(hd); + if(!location) + return CURLE_OUT_OF_MEMORY; + if(!*location) + /* ignore empty data */ + free(location); + else { + data->req.location = location; - /* some cases of POST and PUT etc needs to rewind the data - stream at this point */ - result = http_perhapsrewind(data, conn); - if(result) - return result; + if(data->set.http_follow_mode) { + CURLcode result; + DEBUGASSERT(!data->req.newurl); + data->req.newurl = strdup(data->req.location); /* clone */ + if(!data->req.newurl) + return CURLE_OUT_OF_MEMORY; - /* mark the next request as a followed location: */ - data->state.this_is_a_follow = TRUE; - } + /* some cases of POST and PUT etc needs to rewind the data + stream at this point */ + result = http_perhapsrewind(data, conn); + if(result) + return result; + + /* mark the next request as a followed location: */ + data->state.this_is_a_follow = TRUE; } } - break; - case 'p': - case 'P': + } + return CURLE_OK; +} + +/* + * http_header_p() parses a single response header starting with P. + */ +static CURLcode http_header_p(struct Curl_easy *data, + const char *hd, size_t hdlen) +{ + struct SingleRequest *k = &data->req; + #ifndef CURL_DISABLE_PROXY - v = HD_VAL(hd, hdlen, "Proxy-Connection:"); - if(v) { - if((k->httpversion == 10) && conn->bits.httpproxy && - HD_IS_AND_SAYS(hd, hdlen, "Proxy-Connection:", "keep-alive")) { - /* - * When an HTTP/1.0 reply comes when using a proxy, the - * 'Proxy-Connection: keep-alive' line tells us the - * connection will be kept alive for our pleasure. - * Default action for 1.0 is to close. - */ - connkeep(conn, "Proxy-Connection keep-alive"); /* do not close */ - infof(data, "HTTP/1.0 proxy connection set to keep alive"); - } - else if((k->httpversion == 11) && conn->bits.httpproxy && - HD_IS_AND_SAYS(hd, hdlen, "Proxy-Connection:", "close")) { - /* - * We get an HTTP/1.1 response from a proxy and it says it will - * close down after this transfer. - */ - connclose(conn, "Proxy-Connection: asked to close after done"); - infof(data, "HTTP/1.1 proxy connection set close"); - } - return CURLE_OK; + const char *v = HD_VAL(hd, hdlen, "Proxy-Connection:"); + if(v) { + struct connectdata *conn = data->conn; + if((k->httpversion == 10) && conn->bits.httpproxy && + HD_IS_AND_SAYS(hd, hdlen, "Proxy-Connection:", "keep-alive")) { + /* + * When an HTTP/1.0 reply comes when using a proxy, the + * 'Proxy-Connection: keep-alive' line tells us the + * connection will be kept alive for our pleasure. + * Default action for 1.0 is to close. + */ + connkeep(conn, "Proxy-Connection keep-alive"); /* do not close */ + infof(data, "HTTP/1.0 proxy connection set to keep alive"); } -#endif - if((407 == k->httpcode) && HD_IS(hd, hdlen, "Proxy-authenticate:")) { - char *auth = Curl_copy_header_value(hd); - if(!auth) - return CURLE_OUT_OF_MEMORY; - result = Curl_http_input_auth(data, TRUE, auth); - free(auth); - return result; + else if((k->httpversion == 11) && conn->bits.httpproxy && + HD_IS_AND_SAYS(hd, hdlen, "Proxy-Connection:", "close")) { + /* + * We get an HTTP/1.1 response from a proxy and it says it will + * close down after this transfer. + */ + connclose(conn, "Proxy-Connection: asked to close after done"); + infof(data, "HTTP/1.1 proxy connection set close"); } + return CURLE_OK; + } +#endif + if((407 == k->httpcode) && HD_IS(hd, hdlen, "Proxy-authenticate:")) { + char *auth = Curl_copy_header_value(hd); + CURLcode result; + if(!auth) + return CURLE_OUT_OF_MEMORY; + result = Curl_http_input_auth(data, TRUE, auth); + free(auth); + return result; + } #ifdef USE_SPNEGO - if(HD_IS(hd, hdlen, "Persistent-Auth:")) { - struct negotiatedata *negdata = &conn->negotiate; - struct auth *authp = &data->state.authhost; - if(authp->picked == CURLAUTH_NEGOTIATE) { - char *persistentauth = Curl_copy_header_value(hd); - if(!persistentauth) - return CURLE_OUT_OF_MEMORY; - negdata->noauthpersist = !!checkprefix("false", persistentauth); - negdata->havenoauthpersist = TRUE; - infof(data, "Negotiate: noauthpersist -> %d, header part: %s", - negdata->noauthpersist, persistentauth); - free(persistentauth); - } + if(HD_IS(hd, hdlen, "Persistent-Auth:")) { + struct connectdata *conn = data->conn; + struct negotiatedata *negdata = Curl_auth_nego_get(conn, FALSE); + struct auth *authp = &data->state.authhost; + if(!negdata) + return CURLE_OUT_OF_MEMORY; + if(authp->picked == CURLAUTH_NEGOTIATE) { + char *persistentauth = Curl_copy_header_value(hd); + if(!persistentauth) + return CURLE_OUT_OF_MEMORY; + negdata->noauthpersist = !!checkprefix("false", persistentauth); + negdata->havenoauthpersist = TRUE; + infof(data, "Negotiate: noauthpersist -> %d, header part: %s", + negdata->noauthpersist, persistentauth); + free(persistentauth); } + } #endif - break; - case 'r': - case 'R': - v = HD_VAL(hd, hdlen, "Retry-After:"); - if(v) { - /* Retry-After = HTTP-date / delay-seconds */ - curl_off_t retry_after = 0; /* zero for unknown or "now" */ - time_t date; - curlx_str_passblanks(&v); - - /* try it as a date first, because a date can otherwise start with and - get treated as a number */ - date = Curl_getdate_capped(v); - - if((time_t)-1 != date) { - time_t current = time(NULL); - if(date >= current) - /* convert date to number of seconds into the future */ - retry_after = date - current; - } - else - /* Try it as a decimal number */ - curlx_str_number(&v, &retry_after, CURL_OFF_T_MAX); - /* limit to 6 hours max. this is not documented so that it can be changed - in the future if necessary. */ - if(retry_after > 21600) - retry_after = 21600; - data->info.retry_after = retry_after; - return CURLE_OK; - } - break; - case 's': - case 'S': -#if !defined(CURL_DISABLE_COOKIES) - v = (data->cookies && data->state.cookie_engine) ? - HD_VAL(hd, hdlen, "Set-Cookie:") : NULL; - if(v) { - /* If there is a custom-set Host: name, use it here, or else use - * real peer hostname. */ - const char *host = data->state.aptr.cookiehost ? - data->state.aptr.cookiehost : conn->host.name; - const bool secure_context = - conn->handler->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS) || - strcasecompare("localhost", host) || - !strcmp(host, "127.0.0.1") || - !strcmp(host, "::1"); + return CURLE_OK; +} - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, - CURL_LOCK_ACCESS_SINGLE); - Curl_cookie_add(data, data->cookies, TRUE, FALSE, v, host, - data->state.up.path, secure_context); - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - return CURLE_OK; +/* + * http_header_r() parses a single response header starting with R. + */ +static CURLcode http_header_r(struct Curl_easy *data, + const char *hd, size_t hdlen) +{ + const char *v = HD_VAL(hd, hdlen, "Retry-After:"); + if(v) { + /* Retry-After = HTTP-date / delay-seconds */ + curl_off_t retry_after = 0; /* zero for unknown or "now" */ + time_t date; + curlx_str_passblanks(&v); + + /* try it as a date first, because a date can otherwise start with and + get treated as a number */ + date = Curl_getdate_capped(v); + + if((time_t)-1 != date) { + time_t current = time(NULL); + if(date >= current) + /* convert date to number of seconds into the future */ + retry_after = date - current; } + else + /* Try it as a decimal number, ignore errors */ + (void)curlx_str_number(&v, &retry_after, CURL_OFF_T_MAX); + /* limit to 6 hours max. this is not documented so that it can be changed + in the future if necessary. */ + if(retry_after > 21600) + retry_after = 21600; + data->info.retry_after = retry_after; + } + return CURLE_OK; +} + +/* + * http_header_s() parses a single response header starting with S. + */ +static CURLcode http_header_s(struct Curl_easy *data, + const char *hd, size_t hdlen) +{ +#if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_HSTS) + struct connectdata *conn = data->conn; + const char *v; +#else + (void)data; + (void)hd; + (void)hdlen; +#endif + +#ifndef CURL_DISABLE_COOKIES + v = (data->cookies && data->state.cookie_engine) ? + HD_VAL(hd, hdlen, "Set-Cookie:") : NULL; + if(v) { + /* If there is a custom-set Host: name, use it here, or else use + * real peer hostname. */ + const char *host = data->state.aptr.cookiehost ? + data->state.aptr.cookiehost : conn->host.name; + const bool secure_context = + conn->handler->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS) || + curl_strequal("localhost", host) || + !strcmp(host, "127.0.0.1") || + !strcmp(host, "::1"); + + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, + CURL_LOCK_ACCESS_SINGLE); + Curl_cookie_add(data, data->cookies, TRUE, FALSE, v, host, + data->state.up.path, secure_context); + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); + return CURLE_OK; + } #endif #ifndef CURL_DISABLE_HSTS - /* If enabled, the header is incoming and this is over HTTPS */ - v = (data->hsts && - (Curl_conn_is_ssl(conn, FIRSTSOCKET) || + /* If enabled, the header is incoming and this is over HTTPS */ + v = (data->hsts && + (Curl_conn_is_ssl(conn, FIRSTSOCKET) || #ifdef DEBUGBUILD - /* allow debug builds to circumvent the HTTPS restriction */ - getenv("CURL_HSTS_HTTP") + /* allow debug builds to circumvent the HTTPS restriction */ + getenv("CURL_HSTS_HTTP") #else - 0 + 0 #endif - ) - ) ? HD_VAL(hd, hdlen, "Strict-Transport-Security:") : NULL; - if(v) { - CURLcode check = - Curl_hsts_parse(data->hsts, conn->host.name, v); - if(check) - infof(data, "Illegal STS header skipped"); + ) + ) ? HD_VAL(hd, hdlen, "Strict-Transport-Security:") : NULL; + if(v) { + CURLcode check = + Curl_hsts_parse(data->hsts, conn->host.name, v); + if(check) + infof(data, "Illegal STS header skipped"); #ifdef DEBUGBUILD - else - infof(data, "Parsed STS header fine (%zu entries)", - Curl_llist_count(&data->hsts->list)); + else + infof(data, "Parsed STS header fine (%zu entries)", + Curl_llist_count(&data->hsts->list)); #endif - } + } #endif + + return CURLE_OK; +} + +/* + * http_header_t() parses a single response header starting with T. + */ +static CURLcode http_header_t(struct Curl_easy *data, + const char *hd, size_t hdlen) +{ + struct connectdata *conn = data->conn; + struct SingleRequest *k = &data->req; + + /* RFC 9112, ch. 6.1 + * "Transfer-Encoding MAY be sent in a response to a HEAD request or + * in a 304 (Not Modified) response (Section 15.4.5 of [HTTP]) to a + * GET request, neither of which includes a message body, to indicate + * that the origin server would have applied a transfer coding to the + * message body if the request had been an unconditional GET." + * + * Read: in these cases the 'Transfer-Encoding' does not apply + * to any data following the response headers. Do not add any decoders. + */ + const char *v = (!k->http_bodyless && + (data->state.httpreq != HTTPREQ_HEAD) && + (k->httpcode != 304)) ? + HD_VAL(hd, hdlen, "Transfer-Encoding:") : NULL; + if(v) { + /* One or more encodings. We check for chunked and/or a compression + algorithm. */ + CURLcode result = Curl_build_unencoding_stack(data, v, TRUE); + if(result) + return result; + if(!k->chunk && data->set.http_transfer_encoding) { + /* if this is not chunked, only close can signal the end of this + * transfer as Content-Length is said not to be trusted for + * transfer-encoding! */ + connclose(conn, "HTTP/1.1 transfer-encoding without chunks"); + k->ignore_cl = TRUE; + } + return CURLE_OK; + } + v = HD_VAL(hd, hdlen, "Trailer:"); + if(v) { + data->req.resp_trailer = TRUE; + return CURLE_OK; + } + return CURLE_OK; +} + +/* + * http_header_w() parses a single response header starting with W. + */ +static CURLcode http_header_w(struct Curl_easy *data, + const char *hd, size_t hdlen) +{ + struct SingleRequest *k = &data->req; + CURLcode result = CURLE_OK; + + if((401 == k->httpcode) && HD_IS(hd, hdlen, "WWW-Authenticate:")) { + char *auth = Curl_copy_header_value(hd); + if(!auth) + return CURLE_OUT_OF_MEMORY; + result = Curl_http_input_auth(data, FALSE, auth); + free(auth); + } + return result; +} + +/* + * http_header() parses a single response header. + */ +static CURLcode http_header(struct Curl_easy *data, + const char *hd, size_t hdlen) +{ + CURLcode result = CURLE_OK; + + switch(hd[0]) { + case 'a': + case 'A': + result = http_header_a(data, hd, hdlen); + break; + case 'c': + case 'C': + result = http_header_c(data, hd, hdlen); + break; + case 'l': + case 'L': + result = http_header_l(data, hd, hdlen); + break; + case 'p': + case 'P': + result = http_header_p(data, hd, hdlen); + break; + case 'r': + case 'R': + result = http_header_r(data, hd, hdlen); + break; + case 's': + case 'S': + result = http_header_s(data, hd, hdlen); break; case 't': case 'T': - /* RFC 9112, ch. 6.1 - * "Transfer-Encoding MAY be sent in a response to a HEAD request or - * in a 304 (Not Modified) response (Section 15.4.5 of [HTTP]) to a - * GET request, neither of which includes a message body, to indicate - * that the origin server would have applied a transfer coding to the - * message body if the request had been an unconditional GET." - * - * Read: in these cases the 'Transfer-Encoding' does not apply - * to any data following the response headers. Do not add any decoders. - */ - v = (!k->http_bodyless && - (data->state.httpreq != HTTPREQ_HEAD) && - (k->httpcode != 304)) ? - HD_VAL(hd, hdlen, "Transfer-Encoding:") : NULL; - if(v) { - /* One or more encodings. We check for chunked and/or a compression - algorithm. */ - result = Curl_build_unencoding_stack(data, v, TRUE); - if(result) - return result; - if(!k->chunk && data->set.http_transfer_encoding) { - /* if this is not chunked, only close can signal the end of this - * transfer as Content-Length is said not to be trusted for - * transfer-encoding! */ - connclose(conn, "HTTP/1.1 transfer-encoding without chunks"); - k->ignore_cl = TRUE; - } - return CURLE_OK; - } - v = HD_VAL(hd, hdlen, "Trailer:"); - if(v) { - data->req.resp_trailer = TRUE; - return CURLE_OK; - } + result = http_header_t(data, hd, hdlen); break; case 'w': case 'W': - if((401 == k->httpcode) && HD_IS(hd, hdlen, "WWW-Authenticate:")) { - char *auth = Curl_copy_header_value(hd); - if(!auth) - return CURLE_OUT_OF_MEMORY; - result = Curl_http_input_auth(data, FALSE, auth); - free(auth); - return result; - } + result = http_header_w(data, hd, hdlen); break; } - if(conn->handler->protocol & CURLPROTO_RTSP) { - result = Curl_rtsp_parseheader(data, hd); - if(result) - return result; + if(!result) { + struct connectdata *conn = data->conn; + if(conn->handler->protocol & CURLPROTO_RTSP) + result = Curl_rtsp_parseheader(data, hd); } - return CURLE_OK; + return result; } /* @@ -3654,9 +3773,6 @@ static CURLcode http_on_response(struct Curl_easy *data, if(result) goto out; *pconsumed += blen; /* ws accept handled the data */ - k->header = FALSE; /* we will not get more responses */ - if(data->set.connect_only) - k->keepon &= ~KEEP_RECV; /* read no more content */ } #endif else { @@ -3701,7 +3817,7 @@ static CURLcode http_on_response(struct Curl_easy *data, /* At this point we have some idea about the fate of the connection. If we are closing the connection it may result auth failure. */ -#if defined(USE_NTLM) +#ifdef USE_NTLM if(conn->bits.close && (((data->req.httpcode == 401) && (conn->http_ntlm_state == NTLMSTATE_TYPE2)) || @@ -3711,7 +3827,7 @@ static CURLcode http_on_response(struct Curl_easy *data, data->state.authproblem = TRUE; } #endif -#if defined(USE_SPNEGO) +#ifdef USE_SPNEGO if(conn->bits.close && (((data->req.httpcode == 401) && (conn->http_negotiate_state == GSS_AUTHRECV)) || @@ -3835,7 +3951,7 @@ static CURLcode http_on_response(struct Curl_easy *data, like to call http2_handle_stream_close to properly close a stream. In order to do this, we keep reading until we close the stream. */ - if((0 == k->maxdownload) && (k->httpversion_sent < 20)) + if((k->maxdownload == 0) && (k->httpversion_sent < 20)) k->download_done = TRUE; /* final response without error, prepare to receive the body */ @@ -3850,9 +3966,8 @@ static CURLcode http_on_response(struct Curl_easy *data, out: if(last_hd) { /* if not written yet, write it now */ - CURLcode r2 = http_write_header(data, last_hd, last_hd_len); - if(!result) - result = r2; + result = Curl_1st_err( + result, http_write_header(data, last_hd, last_hd_len)); } return result; } @@ -4257,7 +4372,17 @@ CURLcode Curl_http_req_make(struct httpreq **preq, req = calloc(1, sizeof(*req) + m_len); if(!req) goto out; +#if defined(__GNUC__) && __GNUC__ >= 13 +#pragma GCC diagnostic push +/* error: 'memcpy' offset [137, 142] from the object at 'req' is out of + the bounds of referenced subobject 'method' with type 'char[1]' at + offset 136 */ +#pragma GCC diagnostic ignored "-Warray-bounds" +#endif memcpy(req->method, method, m_len); +#if defined(__GNUC__) && __GNUC__ >= 13 +#pragma GCC diagnostic pop +#endif if(scheme) { req->scheme = Curl_memdup0(scheme, s_len); if(!req->scheme) @@ -4458,7 +4583,7 @@ struct name_const { }; /* keep them sorted by length! */ -static struct name_const H2_NON_FIELD[] = { +static const struct name_const H2_NON_FIELD[] = { { STRCONST("Host") }, { STRCONST("Upgrade") }, { STRCONST("Connection") }, @@ -4474,7 +4599,7 @@ static bool h2_permissible_field(struct dynhds_entry *e) if(e->namelen < H2_NON_FIELD[i].namelen) return TRUE; if(e->namelen == H2_NON_FIELD[i].namelen && - strcasecompare(H2_NON_FIELD[i].name, e->name)) + curl_strequal(H2_NON_FIELD[i].name, e->name)) return FALSE; } return TRUE; @@ -4565,7 +4690,7 @@ CURLcode Curl_http_req_to_h2(struct dynhds *h2_headers, e = Curl_dynhds_getn(&req->headers, i); /* "TE" is special in that it is only permissible when it * has only value "trailers". RFC 9113 ch. 8.2.2 */ - if(e->namelen == 2 && strcasecompare("TE", e->name)) { + if(e->namelen == 2 && curl_strequal("TE", e->name)) { if(http_TE_has_token(e->value, "trailers")) result = Curl_dynhds_add(h2_headers, e->name, e->namelen, "trailers", sizeof("trailers") - 1); @@ -4660,7 +4785,7 @@ static CURLcode cr_exp100_read(struct Curl_easy *data, /* We are now waiting for a reply from the server or * a timeout on our side IFF the request has been fully sent. */ DEBUGF(infof(data, "cr_exp100_read, start AWAITING_CONTINUE, " - "timeout %ldms", data->set.expect_100_timeout)); + "timeout %dms", data->set.expect_100_timeout)); ctx->state = EXP100_AWAITING_CONTINUE; ctx->start = curlx_now(); Curl_expire(data, data->set.expect_100_timeout, EXPIRE_100_TIMEOUT); diff --git a/vendor/curl/lib/http.h b/vendor/curl/lib/http.h index 8876f380447..50279aedfaa 100644 --- a/vendor/curl/lib/http.h +++ b/vendor/curl/lib/http.h @@ -25,10 +25,6 @@ ***************************************************************************/ #include "curl_setup.h" -#if defined(USE_MSH3) && !defined(_WIN32) -#include -#endif - #include "bufq.h" #include "dynhds.h" #include "ws.h" @@ -62,7 +58,7 @@ typedef unsigned char http_majors; #ifndef CURL_DISABLE_HTTP -#if defined(USE_HTTP3) +#ifdef USE_HTTP3 #include #endif @@ -119,8 +115,8 @@ CURLcode Curl_http_setup_conn(struct Curl_easy *data, CURLcode Curl_http(struct Curl_easy *data, bool *done); CURLcode Curl_http_done(struct Curl_easy *data, CURLcode, bool premature); CURLcode Curl_http_connect(struct Curl_easy *data, bool *done); -int Curl_http_getsock_do(struct Curl_easy *data, struct connectdata *conn, - curl_socket_t *socks); +CURLcode Curl_http_do_pollset(struct Curl_easy *data, + struct easy_pollset *ps); CURLcode Curl_http_write_resp(struct Curl_easy *data, const char *buf, size_t blen, bool is_eos); diff --git a/vendor/curl/lib/http2.c b/vendor/curl/lib/http2.c index dd82aa963ec..e550abc8f84 100644 --- a/vendor/curl/lib/http2.c +++ b/vendor/curl/lib/http2.c @@ -24,7 +24,7 @@ #include "curl_setup.h" -#ifdef USE_NGHTTP2 +#if !defined(CURL_DISABLE_HTTP) && defined(USE_NGHTTP2) #include #include #include "urldata.h" @@ -36,7 +36,6 @@ #include "sendf.h" #include "select.h" #include "curlx/base64.h" -#include "strcase.h" #include "multiif.h" #include "url.h" #include "urlapi-int.h" @@ -205,6 +204,9 @@ static void cf_h2_ctx_close(struct cf_h2_ctx *ctx) } } +static CURLcode nw_out_flush(struct Curl_cfilter *cf, + struct Curl_easy *data); + static CURLcode h2_progress_egress(struct Curl_cfilter *cf, struct Curl_easy *data); @@ -374,27 +376,6 @@ static CURLcode cf_h2_update_local_win(struct Curl_cfilter *cf, } #endif /* !NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE */ -/* - * Mark this transfer to get "drained". - */ -static void drain_stream(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h2_stream_ctx *stream) -{ - unsigned char bits; - - (void)cf; - bits = CURL_CSELECT_IN; - if(!stream->closed && - (!stream->body_eos || !Curl_bufq_is_empty(&stream->sendbuf))) - bits |= CURL_CSELECT_OUT; - if(stream->closed || (data->state.select_bits != bits)) { - CURL_TRC_CF(data, cf, "[%d] DRAIN select_bits=%x", - stream->id, bits); - data->state.select_bits = bits; - Curl_expire(data, 0, EXPIRE_RUN_NOW); - } -} static CURLcode http2_data_setup(struct Curl_cfilter *cf, struct Curl_easy *data, @@ -449,8 +430,10 @@ static void http2_data_done(struct Curl_cfilter *cf, struct Curl_easy *data) flush_egress = TRUE; } - if(flush_egress) - nghttp2_session_send(ctx->h2); + if(flush_egress) { + (void)nghttp2_session_send(ctx->h2); + (void)nw_out_flush(cf, data); + } } Curl_uint_hash_remove(&ctx->streams, data->mid); @@ -480,33 +463,6 @@ static int h2_client_new(struct Curl_cfilter *cf, return rc; } -static ssize_t nw_in_reader(void *reader_ctx, - unsigned char *buf, size_t buflen, - CURLcode *err) -{ - struct Curl_cfilter *cf = reader_ctx; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - - return Curl_conn_cf_recv(cf->next, data, (char *)buf, buflen, err); -} - -static ssize_t nw_out_writer(void *writer_ctx, - const unsigned char *buf, size_t buflen, - CURLcode *err) -{ - struct Curl_cfilter *cf = writer_ctx; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - - if(data) { - ssize_t nwritten = Curl_conn_cf_send(cf->next, data, (const char *)buf, - buflen, FALSE, err); - if(nwritten > 0) - CURL_TRC_CF(data, cf, "[0] egress: wrote %zd bytes", nwritten); - return nwritten; - } - return 0; -} - static ssize_t send_callback(nghttp2_session *h2, const uint8_t *mem, size_t length, int flags, void *userp); @@ -532,7 +488,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *value, size_t valuelen, uint8_t flags, void *userp); -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) +#ifndef CURL_DISABLE_VERBOSE_STRINGS static int error_callback(nghttp2_session *session, const char *msg, size_t len, void *userp); #endif @@ -567,7 +523,7 @@ static CURLcode cf_h2_ctx_open(struct Curl_cfilter *cf, nghttp2_session_callbacks_set_on_begin_headers_callback( cbs, on_begin_headers); nghttp2_session_callbacks_set_on_header_callback(cbs, on_header); -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) +#ifndef CURL_DISABLE_VERBOSE_STRINGS nghttp2_session_callbacks_set_error_callback(cbs, error_callback); #endif @@ -727,12 +683,12 @@ static bool http2_connisalive(struct Curl_cfilter *cf, struct Curl_easy *data, not in use by any other transfer, there should not be any data here, only "protocol frames" */ CURLcode result; - ssize_t nread = -1; + size_t nread; *input_pending = FALSE; - nread = Curl_bufq_slurp(&ctx->inbufq, nw_in_reader, cf, &result); - if(nread != -1) { - CURL_TRC_CF(data, cf, "%zd bytes stray data read before trying " + result = Curl_cf_recv_bufq(cf->next, data, &ctx->inbufq, 0, &nread); + if(!result) { + CURL_TRC_CF(data, cf, "%zu bytes stray data read before trying " "h2 connection", nread); if(h2_process_pending_input(cf, data, &result) < 0) /* immediate error, considered dead */ @@ -785,15 +741,16 @@ static CURLcode nw_out_flush(struct Curl_cfilter *cf, struct Curl_easy *data) { struct cf_h2_ctx *ctx = cf->ctx; - ssize_t nwritten; + size_t nwritten; CURLcode result; (void)data; if(Curl_bufq_is_empty(&ctx->outbufq)) return CURLE_OK; - nwritten = Curl_bufq_pass(&ctx->outbufq, nw_out_writer, cf, &result); - if(nwritten < 0) { + result = Curl_cf_send_bufq(cf->next, data, &ctx->outbufq, NULL, 0, + &nwritten); + if(result) { if(result == CURLE_AGAIN) { CURL_TRC_CF(data, cf, "flush nw send buffer(%zu) -> EAGAIN", Curl_bufq_len(&ctx->outbufq)); @@ -816,7 +773,7 @@ static ssize_t send_callback(nghttp2_session *h2, struct Curl_cfilter *cf = userp; struct cf_h2_ctx *ctx = cf->ctx; struct Curl_easy *data = CF_DATA_CURRENT(cf); - ssize_t nwritten; + size_t nwritten; CURLcode result = CURLE_OK; (void)h2; @@ -824,11 +781,12 @@ static ssize_t send_callback(nghttp2_session *h2, DEBUGASSERT(data); if(!cf->connected) - nwritten = Curl_bufq_write(&ctx->outbufq, buf, blen, &result); + result = Curl_bufq_write(&ctx->outbufq, buf, blen, &nwritten); else - nwritten = Curl_bufq_write_pass(&ctx->outbufq, buf, blen, - nw_out_writer, cf, &result); - if(nwritten < 0) { + result = Curl_cf_send_bufq(cf->next, data, &ctx->outbufq, buf, blen, + &nwritten); + + if(result) { if(result == CURLE_AGAIN) { ctx->nw_out_blocked = 1; return NGHTTP2_ERR_WOULDBLOCK; @@ -841,7 +799,8 @@ static ssize_t send_callback(nghttp2_session *h2, ctx->nw_out_blocked = 1; return NGHTTP2_ERR_WOULDBLOCK; } - return nwritten; + return (nwritten > SSIZE_T_MAX) ? + NGHTTP2_ERR_CALLBACK_FAILURE : (ssize_t)nwritten; } @@ -1191,7 +1150,7 @@ static CURLcode on_stream_frame(struct Curl_cfilter *cf, if(stream->status_code / 100 != 1) { stream->resp_hds_complete = TRUE; } - drain_stream(cf, data, stream); + Curl_multi_mark_dirty(data); break; case NGHTTP2_PUSH_PROMISE: rv = push_promise(cf, data, &frame->push_promise); @@ -1214,12 +1173,12 @@ static CURLcode on_stream_frame(struct Curl_cfilter *cf, if(frame->rst_stream.error_code) { stream->reset = TRUE; } - drain_stream(cf, data, stream); + Curl_multi_mark_dirty(data); break; case NGHTTP2_WINDOW_UPDATE: if(CURL_WANT_SEND(data) && Curl_bufq_is_empty(&stream->sendbuf)) { /* need more data, force processing of transfer */ - drain_stream(cf, data, stream); + Curl_multi_mark_dirty(data); } else if(!Curl_bufq_is_empty(&stream->sendbuf)) { /* resume the potentially suspended stream */ @@ -1245,7 +1204,7 @@ static CURLcode on_stream_frame(struct Curl_cfilter *cf, stream->id, NGHTTP2_STREAM_CLOSED); stream->closed = TRUE; } - drain_stream(cf, data, stream); + Curl_multi_mark_dirty(data); } return CURLE_OK; } @@ -1394,11 +1353,8 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, * 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(CURL_WANT_SEND(data)) { - struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data); - if(stream) - drain_stream(cf, data, stream); - } + if(CURL_WANT_SEND(data)) + Curl_multi_mark_dirty(data); } break; } @@ -1543,7 +1499,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id, stream_id, nghttp2_http2_strerror(error_code), error_code); else CURL_TRC_CF(data_s, cf, "[%d] CLOSED", stream_id); - drain_stream(cf, data_s, stream); + Curl_multi_mark_dirty(data_s); /* remove `data_s` from the nghttp2 stream */ rv = nghttp2_session_set_stream_user_data(session, stream_id, 0); @@ -1641,9 +1597,9 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, if(!check) /* no memory */ return NGHTTP2_ERR_CALLBACK_FAILURE; - if(!strcasecompare(check, (const char *)value) && + if(!curl_strequal(check, (const char *)value) && ((cf->conn->remote_port != cf->conn->given->defport) || - !strcasecompare(cf->conn->host.name, (const char *)value))) { + !curl_strequal(cf->conn->host.name, (const char *)value))) { /* This is push is not for the same authority that was asked for in * the URL. RFC 7540 section 8.2 says: "A client MUST treat a * PUSH_PROMISE for which the server is not authoritative as a stream @@ -1737,7 +1693,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, } /* if we receive data for another handle, wake that up */ if(CF_DATA_CURRENT(cf) != data_s) - Curl_expire(data_s, 0, EXPIRE_RUN_NOW); + Curl_multi_mark_dirty(data_s); CURL_TRC_CF(data_s, cf, "[%d] status: HTTP/2 %03d", stream->id, stream->status_code); @@ -1764,7 +1720,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, } /* if we receive data for another handle, wake that up */ if(CF_DATA_CURRENT(cf) != data_s) - Curl_expire(data_s, 0, EXPIRE_RUN_NOW); + Curl_multi_mark_dirty(data_s); CURL_TRC_CF(data_s, cf, "[%d] header: %.*s: %.*s", stream->id, (int)namelen, name, (int)valuelen, value); @@ -1785,6 +1741,7 @@ static ssize_t req_body_read_callback(nghttp2_session *session, struct h2_stream_ctx *stream = NULL; CURLcode result; ssize_t nread; + size_t n; (void)source; (void)cf; @@ -1803,12 +1760,14 @@ static ssize_t req_body_read_callback(nghttp2_session *session, if(!stream) return NGHTTP2_ERR_CALLBACK_FAILURE; - nread = Curl_bufq_read(&stream->sendbuf, buf, length, &result); - if(nread < 0) { + result = Curl_bufq_read(&stream->sendbuf, buf, length, &n); + if(result) { if(result != CURLE_AGAIN) return NGHTTP2_ERR_CALLBACK_FAILURE; nread = 0; } + else + nread = (ssize_t)n; CURL_TRC_CF(data_s, cf, "[%d] req_body_read(len=%zu) eos=%d -> %zd, %d", stream_id, length, stream->body_eos, nread, result); @@ -1820,7 +1779,7 @@ static ssize_t req_body_read_callback(nghttp2_session *session, return (nread == 0) ? NGHTTP2_ERR_DEFERRED : nread; } -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) +#ifndef CURL_DISABLE_VERBOSE_STRINGS static int error_callback(nghttp2_session *session, const char *msg, size_t len, @@ -1874,20 +1833,20 @@ CURLcode Curl_http2_request_upgrade(struct dynbuf *req, return result; } -static ssize_t http2_handle_stream_close(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h2_stream_ctx *stream, - CURLcode *err) +static CURLcode http2_handle_stream_close(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct h2_stream_ctx *stream, + size_t *pnlen) { - ssize_t rv = 0; + CURLcode result; + *pnlen = 0; if(stream->error == NGHTTP2_REFUSED_STREAM) { CURL_TRC_CF(data, cf, "[%d] REFUSED_STREAM, try again on a new " "connection", stream->id); connclose(cf->conn, "REFUSED_STREAM"); /* do not use this anymore */ data->state.refused_stream = TRUE; - *err = CURLE_RECV_ERROR; /* trigger Curl_retry_request() later */ - return -1; + return CURLE_RECV_ERROR; /* trigger Curl_retry_request() later */ } else if(stream->error != NGHTTP2_NO_ERROR) { if(stream->resp_hds_complete && data->req.no_body) { @@ -1896,27 +1855,23 @@ static ssize_t http2_handle_stream_close(struct Curl_cfilter *cf, stream->id, nghttp2_http2_strerror(stream->error), stream->error); stream->close_handled = TRUE; - *err = CURLE_OK; - goto out; + return CURLE_OK; } failf(data, "HTTP/2 stream %u was not closed cleanly: %s (err %u)", stream->id, nghttp2_http2_strerror(stream->error), stream->error); - *err = CURLE_HTTP2_STREAM; - return -1; + return CURLE_HTTP2_STREAM; } else if(stream->reset) { failf(data, "HTTP/2 stream %u was reset", stream->id); - *err = data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP2; - return -1; + return data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP2; } if(!stream->bodystarted) { failf(data, "HTTP/2 stream %u was closed cleanly, but before getting " " all response header fields, treated as error", stream->id); - *err = CURLE_HTTP2_STREAM; - return -1; + return CURLE_HTTP2_STREAM; } if(Curl_dynhds_count(&stream->resp_trailers)) { @@ -1924,37 +1879,36 @@ static ssize_t http2_handle_stream_close(struct Curl_cfilter *cf, struct dynbuf dbuf; size_t i; - *err = CURLE_OK; + result = CURLE_OK; curlx_dyn_init(&dbuf, DYN_TRAILERS); for(i = 0; i < Curl_dynhds_count(&stream->resp_trailers); ++i) { e = Curl_dynhds_getn(&stream->resp_trailers, i); if(!e) break; curlx_dyn_reset(&dbuf); - *err = curlx_dyn_addf(&dbuf, "%.*s: %.*s\x0d\x0a", + result = curlx_dyn_addf(&dbuf, "%.*s: %.*s\x0d\x0a", (int)e->namelen, e->name, (int)e->valuelen, e->value); - if(*err) + if(result) break; Curl_debug(data, CURLINFO_HEADER_IN, curlx_dyn_ptr(&dbuf), curlx_dyn_len(&dbuf)); - *err = Curl_client_write(data, CLIENTWRITE_HEADER|CLIENTWRITE_TRAILER, - curlx_dyn_ptr(&dbuf), curlx_dyn_len(&dbuf)); - if(*err) + result = Curl_client_write(data, CLIENTWRITE_HEADER|CLIENTWRITE_TRAILER, + curlx_dyn_ptr(&dbuf), curlx_dyn_len(&dbuf)); + if(result) break; } curlx_dyn_free(&dbuf); - if(*err) + if(result) goto out; } stream->close_handled = TRUE; - *err = CURLE_OK; - rv = 0; + result = CURLE_OK; out: - CURL_TRC_CF(data, cf, "handle_stream_close -> %zd, %d", rv, *err); - return rv; + CURL_TRC_CF(data, cf, "handle_stream_close -> %d, %zu", result, *pnlen); + return result; } static int sweight_wanted(const struct Curl_easy *data) @@ -1997,7 +1951,7 @@ static void h2_pri_spec(struct cf_h2_ctx *ctx, * Flush any out data pending in the network buffer. */ static CURLcode h2_progress_egress(struct Curl_cfilter *cf, - struct Curl_easy *data) + struct Curl_easy *data) { struct cf_h2_ctx *ctx = cf->ctx; struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data); @@ -2037,36 +1991,36 @@ static CURLcode h2_progress_egress(struct Curl_cfilter *cf, return nw_out_flush(cf, data); } -static ssize_t stream_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - struct h2_stream_ctx *stream, - char *buf, size_t len, CURLcode *err) +static CURLcode stream_recv(struct Curl_cfilter *cf, struct Curl_easy *data, + struct h2_stream_ctx *stream, + char *buf, size_t len, size_t *pnread) { struct cf_h2_ctx *ctx = cf->ctx; - ssize_t nread = -1; + CURLcode result = CURLE_AGAIN; (void)buf; - *err = CURLE_AGAIN; + (void)len; + *pnread = 0; + if(stream->xfer_result) { CURL_TRC_CF(data, cf, "[%d] xfer write failed", stream->id); - *err = stream->xfer_result; - nread = -1; + result = stream->xfer_result; } else if(stream->closed) { CURL_TRC_CF(data, cf, "[%d] returning CLOSE", stream->id); - nread = http2_handle_stream_close(cf, data, stream, err); + result = http2_handle_stream_close(cf, data, stream, pnread); } else if(stream->reset || (ctx->conn_closed && Curl_bufq_is_empty(&ctx->inbufq)) || (ctx->rcvd_goaway && ctx->remote_max_sid < stream->id)) { CURL_TRC_CF(data, cf, "[%d] returning ERR", stream->id); - *err = data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP2; - nread = -1; + result = data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP2; } - if(nread < 0 && *err != CURLE_AGAIN) - CURL_TRC_CF(data, cf, "[%d] stream_recv(len=%zu) -> %zd, %d", - stream->id, len, nread, *err); - return nread; + if(result && (result != CURLE_AGAIN)) + CURL_TRC_CF(data, cf, "[%d] stream_recv(len=%zu) -> %d, %zu", + stream->id, len, result, *pnread); + return result; } static CURLcode h2_progress_ingress(struct Curl_cfilter *cf, @@ -2076,7 +2030,7 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf, struct cf_h2_ctx *ctx = cf->ctx; struct h2_stream_ctx *stream; CURLcode result = CURLE_OK; - ssize_t nread; + size_t nread; if(should_close_session(ctx)) { CURL_TRC_CF(data, cf, "progress ingress, session is closed"); @@ -2102,12 +2056,12 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf, * this may leave data in underlying buffers that will not * be consumed. */ if(!cf->next || !cf->next->cft->has_data_pending(cf->next, data)) - drain_stream(cf, data, stream); + Curl_multi_mark_dirty(data); break; } - nread = Curl_bufq_sipn(&ctx->inbufq, 0, nw_in_reader, cf, &result); - if(nread < 0) { + result = Curl_cf_recv_bufq(cf->next, data, &ctx->inbufq, 0, &nread); + if(result) { if(result != CURLE_AGAIN) { failf(data, "Failed receiving HTTP2 data: %d(%s)", result, curl_easy_strerror(result)); @@ -2121,9 +2075,8 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf, break; } else { - CURL_TRC_CF(data, cf, "[0] ingress: read %zd bytes", nread); - data_max_bytes = (data_max_bytes > (size_t)nread) ? - (data_max_bytes - (size_t)nread) : 0; + CURL_TRC_CF(data, cf, "[0] ingress: read %zu bytes", nread); + data_max_bytes = (data_max_bytes > nread) ? (data_max_bytes - nread) : 0; } if(h2_process_pending_input(cf, data, &result)) @@ -2140,15 +2093,15 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf, return CURLE_OK; } -static ssize_t cf_h2_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t len, CURLcode *err) +static CURLcode cf_h2_recv(struct Curl_cfilter *cf, struct Curl_easy *data, + char *buf, size_t len, size_t *pnread) { struct cf_h2_ctx *ctx = cf->ctx; struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data); - ssize_t nread = -1; - CURLcode result; + CURLcode result, r2; struct cf_call_data save; + *pnread = 0; if(!stream) { /* Abnormal call sequence: either this transfer has never opened a stream * (unlikely) or the transfer has been done, cleaned up its resources, but @@ -2156,51 +2109,49 @@ static ssize_t cf_h2_recv(struct Curl_cfilter *cf, struct Curl_easy *data, * is for such a case. */ failf(data, "http/2 recv on a transfer never opened " "or already cleared, mid=%u", data->mid); - *err = CURLE_HTTP2; - return -1; + return CURLE_HTTP2; } CF_DATA_SAVE(save, cf, data); - nread = stream_recv(cf, data, stream, buf, len, err); - if(nread < 0 && *err != CURLE_AGAIN) + result = stream_recv(cf, data, stream, buf, len, pnread); + if(result && (result != CURLE_AGAIN)) goto out; - if(nread < 0) { - *err = h2_progress_ingress(cf, data, len); - if(*err) + if(result) { + result = h2_progress_ingress(cf, data, len); + if(result) goto out; - nread = stream_recv(cf, data, stream, buf, len, err); + result = stream_recv(cf, data, stream, buf, len, pnread); } - if(nread > 0) { + if(*pnread > 0) { /* Now that we transferred this to the upper layer, we report * the actual amount of DATA consumed to the H2 session, so * that it adjusts stream flow control */ - nghttp2_session_consume(ctx->h2, stream->id, (size_t)nread); + nghttp2_session_consume(ctx->h2, stream->id, *pnread); if(stream->closed) { CURL_TRC_CF(data, cf, "[%d] DRAIN closed stream", stream->id); - drain_stream(cf, data, stream); + Curl_multi_mark_dirty(data); } } out: - result = h2_progress_egress(cf, data); - if(result == CURLE_AGAIN) { + r2 = h2_progress_egress(cf, data); + if(r2 == CURLE_AGAIN) { /* pending data to send, need to be called again. Ideally, we * monitor the socket for POLLOUT, but when not SENDING * any more, we force processing of the transfer. */ if(!CURL_WANT_SEND(data)) - drain_stream(cf, data, stream); + Curl_multi_mark_dirty(data); } - else if(result) { - *err = result; - nread = -1; + else if(r2) { + result = r2; } - CURL_TRC_CF(data, cf, "[%d] cf_recv(len=%zu) -> %zd %d, " + CURL_TRC_CF(data, cf, "[%d] cf_recv(len=%zu) -> %d, %zu, " "window=%d/%d, connection %d/%d", - stream->id, len, nread, *err, + stream->id, len, result, *pnread, nghttp2_session_get_stream_effective_recv_data_length( ctx->h2, stream->id), nghttp2_session_get_stream_effective_local_window_size( @@ -2209,7 +2160,7 @@ static ssize_t cf_h2_recv(struct Curl_cfilter *cf, struct Curl_easy *data, HTTP2_HUGE_WINDOW_SIZE); CF_DATA_RESTORE(cf, save); - return nread; + return result; } static ssize_t cf_h2_body_send(struct Curl_cfilter *cf, @@ -2219,7 +2170,7 @@ static ssize_t cf_h2_body_send(struct Curl_cfilter *cf, CURLcode *err) { struct cf_h2_ctx *ctx = cf->ctx; - ssize_t nwritten; + size_t nwritten; if(stream->closed) { if(stream->resp_hds_complete) { @@ -2241,11 +2192,11 @@ static ssize_t cf_h2_body_send(struct Curl_cfilter *cf, return -1; } - nwritten = Curl_bufq_write(&stream->sendbuf, buf, blen, err); - if(nwritten < 0) + *err = Curl_bufq_write(&stream->sendbuf, buf, blen, &nwritten); + if(*err) return -1; - if(eos && (blen == (size_t)nwritten)) + if(eos && (blen == nwritten)) stream->body_eos = TRUE; if(eos || !Curl_bufq_is_empty(&stream->sendbuf)) { @@ -2256,54 +2207,52 @@ static ssize_t cf_h2_body_send(struct Curl_cfilter *cf, return -1; } } - return nwritten; + return (ssize_t)nwritten; } -static ssize_t h2_submit(struct h2_stream_ctx **pstream, - struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, - bool eos, CURLcode *err) +static CURLcode h2_submit(struct h2_stream_ctx **pstream, + struct Curl_cfilter *cf, struct Curl_easy *data, + const void *buf, size_t len, + bool eos, size_t *pnwritten) { struct cf_h2_ctx *ctx = cf->ctx; struct h2_stream_ctx *stream = NULL; struct dynhds h2_headers; nghttp2_nv *nva = NULL; const void *body = NULL; - size_t nheader, bodylen, i; + size_t nheader, bodylen; nghttp2_data_provider data_prd; int32_t stream_id; nghttp2_priority_spec pri_spec; ssize_t nwritten; + CURLcode result = CURLE_OK; + *pnwritten = 0; Curl_dynhds_init(&h2_headers, 0, DYN_HTTP_REQUEST); - *err = http2_data_setup(cf, data, &stream); - if(*err) { - nwritten = -1; + result = http2_data_setup(cf, data, &stream); + if(result) goto out; - } - nwritten = Curl_h1_req_parse_read(&stream->h1, buf, len, NULL, 0, err); + nwritten = Curl_h1_req_parse_read(&stream->h1, buf, len, NULL, 0, &result); if(nwritten < 0) goto out; + *pnwritten = (size_t)nwritten; if(!stream->h1.done) { /* need more data */ goto out; } DEBUGASSERT(stream->h1.req); - *err = Curl_http_req_to_h2(&h2_headers, stream->h1.req, data); - if(*err) { - nwritten = -1; + result = Curl_http_req_to_h2(&h2_headers, stream->h1.req, data); + if(result) goto out; - } /* no longer needed */ Curl_h1_req_parse_free(&stream->h1); nva = Curl_dynhds_to_nva(&h2_headers, &nheader); if(!nva) { - *err = CURLE_OUT_OF_MEMORY; - nwritten = -1; + result = CURLE_OUT_OF_MEMORY; goto out; } @@ -2329,14 +2278,14 @@ static ssize_t h2_submit(struct h2_stream_ctx **pstream, if(stream_id < 0) { CURL_TRC_CF(data, cf, "send: nghttp2_submit_request error (%s)%u", nghttp2_strerror(stream_id), stream_id); - *err = CURLE_SEND_ERROR; - nwritten = -1; + result = CURLE_SEND_ERROR; goto out; } +#ifndef CURL_DISABLE_VERBOSE_STRINGS #define MAX_ACC 60000 /* <64KB to account for some overhead */ if(Curl_trc_is_verbose(data)) { - size_t acc = 0; + size_t acc = 0, i; infof(data, "[HTTP/2] [%d] OPENED stream for %s", stream_id, data->state.url); @@ -2354,88 +2303,87 @@ static ssize_t h2_submit(struct h2_stream_ctx **pstream, "stream to be rejected.", MAX_ACC); } } +#endif stream->id = stream_id; - body = (const char *)buf + nwritten; - bodylen = len - nwritten; + body = (const char *)buf + *pnwritten; + bodylen = len - *pnwritten; if(bodylen || eos) { - ssize_t n = cf_h2_body_send(cf, data, stream, body, bodylen, eos, err); + ssize_t n = cf_h2_body_send(cf, data, stream, body, bodylen, eos, &result); if(n >= 0) - nwritten += n; - else if(*err == CURLE_AGAIN) - *err = CURLE_OK; - else if(*err != CURLE_AGAIN) { - *err = CURLE_SEND_ERROR; - nwritten = -1; - goto out; + *pnwritten += n; + else if(result == CURLE_AGAIN) + result = CURLE_OK; + else { + result = CURLE_SEND_ERROR; } } out: - CURL_TRC_CF(data, cf, "[%d] submit -> %zd, %d", - stream ? stream->id : -1, nwritten, *err); + CURL_TRC_CF(data, cf, "[%d] submit -> %d, %zu", + stream ? stream->id : -1, result, *pnwritten); Curl_safefree(nva); *pstream = stream; Curl_dynhds_free(&h2_headers); - return nwritten; + return result; } -static ssize_t cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, bool eos, - CURLcode *err) +static CURLcode cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data, + const void *buf, size_t len, bool eos, + size_t *pnwritten) { struct cf_h2_ctx *ctx = cf->ctx; struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data); struct cf_call_data save; ssize_t nwritten; - CURLcode result; + CURLcode result = CURLE_OK, r2; CF_DATA_SAVE(save, cf, data); + *pnwritten = 0; if(!stream || stream->id == -1) { - nwritten = h2_submit(&stream, cf, data, buf, len, eos, err); - if(nwritten < 0) { + result = h2_submit(&stream, cf, data, buf, len, eos, pnwritten); + if(result) goto out; - } DEBUGASSERT(stream); } else if(stream->body_eos) { - /* We already wrote this, but CURLE_AGAINed the call due to not + /* We already wrote this, but CURLE_AGAIN-ed the call due to not * being able to flush stream->sendbuf. Make a 0-length write * to trigger flushing again. * If this works, we report to have written `len` bytes. */ DEBUGASSERT(eos); - nwritten = cf_h2_body_send(cf, data, stream, buf, 0, eos, err); + nwritten = cf_h2_body_send(cf, data, stream, buf, 0, eos, &result); CURL_TRC_CF(data, cf, "[%d] cf_body_send last CHUNK -> %zd, %d, eos=%d", - stream->id, nwritten, *err, eos); + stream->id, nwritten, result, eos); if(nwritten < 0) { goto out; } - nwritten = len; + *pnwritten = len; } else { - nwritten = cf_h2_body_send(cf, data, stream, buf, len, eos, err); + nwritten = cf_h2_body_send(cf, data, stream, buf, len, eos, &result); CURL_TRC_CF(data, cf, "[%d] cf_body_send(len=%zu) -> %zd, %d, eos=%d", - stream->id, len, nwritten, *err, eos); + stream->id, len, nwritten, result, eos); + if(nwritten >= 0) + *pnwritten = (size_t)nwritten; } /* Call the nghttp2 send loop and flush to write ALL buffered data, * headers and/or request body completely out to the network */ - result = h2_progress_egress(cf, data); + r2 = h2_progress_egress(cf, data); /* if the stream has been closed in egress handling (nghttp2 does that * when it does not like the headers, for example */ if(stream && stream->closed) { infof(data, "stream %u closed", stream->id); - *err = CURLE_SEND_ERROR; - nwritten = -1; + result = CURLE_SEND_ERROR; goto out; } - else if(result && (result != CURLE_AGAIN)) { - *err = result; - nwritten = -1; + else if(r2 && (r2 != CURLE_AGAIN)) { + result = r2; goto out; } @@ -2443,21 +2391,20 @@ static ssize_t cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data, /* nghttp2 thinks this session is done. If the stream has not been * closed, this is an error state for out transfer */ if(stream && stream->closed) { - nwritten = http2_handle_stream_close(cf, data, stream, err); + result = http2_handle_stream_close(cf, data, stream, pnwritten); } else { CURL_TRC_CF(data, cf, "send: nothing to do in this session"); - *err = CURLE_HTTP2; - nwritten = -1; + result = CURLE_HTTP2; } } out: if(stream) { - CURL_TRC_CF(data, cf, "[%d] cf_send(len=%zu) -> %zd, %d, " + CURL_TRC_CF(data, cf, "[%d] cf_send(len=%zu) -> %d, %zu, " "eos=%d, h2 windows %d-%d (stream-conn), " "buffers %zu-%zu (stream-conn)", - stream->id, len, nwritten, *err, + stream->id, len, result, *pnwritten, stream->body_eos, nghttp2_session_get_stream_remote_window_size( ctx->h2, stream->id), @@ -2466,14 +2413,14 @@ static ssize_t cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data, Curl_bufq_len(&ctx->outbufq)); } else { - CURL_TRC_CF(data, cf, "cf_send(len=%zu) -> %zd, %d, " + CURL_TRC_CF(data, cf, "cf_send(len=%zu) -> %d, %zu, " "connection-window=%d, nw_send_buffer(%zu)", - len, nwritten, *err, + len, result, *pnwritten, nghttp2_session_get_remote_window_size(ctx->h2), Curl_bufq_len(&ctx->outbufq)); } CF_DATA_RESTORE(cf, save); - return nwritten; + return result; } static CURLcode cf_h2_flush(struct Curl_cfilter *cf, @@ -2518,17 +2465,18 @@ static CURLcode cf_h2_flush(struct Curl_cfilter *cf, return result; } -static void cf_h2_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) +static CURLcode cf_h2_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { struct cf_h2_ctx *ctx = cf->ctx; struct cf_call_data save; curl_socket_t sock; bool want_recv, want_send; + CURLcode result = CURLE_OK; if(!ctx->h2) - return; + return CURLE_OK; sock = Curl_conn_cf_get_socket(cf, data); Curl_pollset_check(data, ps, sock, &want_recv, &want_send); @@ -2546,7 +2494,7 @@ static void cf_h2_adjust_pollset(struct Curl_cfilter *cf, (!c_exhaust && nghttp2_session_want_write(ctx->h2)) || !Curl_bufq_is_empty(&ctx->outbufq); - Curl_pollset_set(data, ps, sock, want_recv, want_send); + result = Curl_pollset_set(data, ps, sock, want_recv, want_send); CF_DATA_RESTORE(cf, save); } else if(ctx->sent_goaway && !cf->shutdown) { @@ -2555,9 +2503,10 @@ static void cf_h2_adjust_pollset(struct Curl_cfilter *cf, want_send = nghttp2_session_want_write(ctx->h2) || !Curl_bufq_is_empty(&ctx->outbufq); want_recv = nghttp2_session_want_read(ctx->h2); - Curl_pollset_set(data, ps, sock, want_recv, want_send); + result = Curl_pollset_set(data, ps, sock, want_recv, want_send); CF_DATA_RESTORE(cf, save); } + return result; } static CURLcode cf_h2_connect(struct Curl_cfilter *cf, @@ -2716,8 +2665,7 @@ static CURLcode http2_data_pause(struct Curl_cfilter *cf, * not. We may have already buffered and exhausted the new window * by operating on things in flight during the handling of other * transfers. */ - drain_stream(cf, data, stream); - Curl_expire(data, 0, EXPIRE_RUN_NOW); + Curl_multi_mark_dirty(data); } CURL_TRC_CF(data, cf, "[%d] stream now %spaused", stream->id, pause ? "" : "un"); @@ -2769,15 +2717,16 @@ static bool cf_h2_is_alive(struct Curl_cfilter *cf, bool *input_pending) { struct cf_h2_ctx *ctx = cf->ctx; - CURLcode result; + bool alive; struct cf_call_data save; + *input_pending = FALSE; CF_DATA_SAVE(save, cf, data); - result = (ctx && ctx->h2 && http2_connisalive(cf, data, input_pending)); + alive = (ctx && ctx->h2 && http2_connisalive(cf, data, input_pending)); CURL_TRC_CF(data, cf, "conn alive -> %d, input_pending=%d", - result, *input_pending); + alive, *input_pending); CF_DATA_RESTORE(cf, save); - return result; + return alive; } static CURLcode cf_h2_keep_alive(struct Curl_cfilter *cf, @@ -2805,7 +2754,7 @@ static CURLcode cf_h2_query(struct Curl_cfilter *cf, DEBUGASSERT(pres1); CF_DATA_SAVE(save, cf, data); - if(nghttp2_session_check_request_allowed(ctx->h2) == 0) { + if(!ctx->h2 || !nghttp2_session_check_request_allowed(ctx->h2)) { /* the limit is what we have in use right now */ effective_max = CONN_ATTACHED(cf->conn); } @@ -2848,7 +2797,6 @@ struct Curl_cftype Curl_cft_nghttp2 = { cf_h2_connect, cf_h2_close, cf_h2_shutdown, - Curl_cf_def_get_host, cf_h2_adjust_pollset, cf_h2_data_pending, cf_h2_send, @@ -3001,17 +2949,17 @@ CURLcode Curl_http2_upgrade(struct Curl_easy *data, /* Remaining data from the protocol switch reply is already using * the switched protocol, ie. HTTP/2. We add that to the network * inbufq. */ - ssize_t copied; + size_t copied; - copied = Curl_bufq_write(&ctx->inbufq, - (const unsigned char *)mem, nread, &result); - if(copied < 0) { + result = Curl_bufq_write(&ctx->inbufq, + (const unsigned char *)mem, nread, &copied); + if(result) { failf(data, "error on copying HTTP Upgrade response: %d", result); return CURLE_RECV_ERROR; } - if((size_t)copied < nread) { + if(copied < nread) { failf(data, "connection buffer size could not take all data " - "from HTTP Upgrade response header: copied=%zd, datalen=%zu", + "from HTTP Upgrade response header: copied=%zu, datalen=%zu", copied, nread); return CURLE_HTTP2; } @@ -3064,23 +3012,23 @@ void *Curl_nghttp2_realloc(void *ptr, size_t size, void *user_data) return Curl_crealloc(ptr, size); } -#else /* !USE_NGHTTP2 */ +#else /* CURL_DISABLE_HTTP || !USE_NGHTTP2 */ /* Satisfy external references even if http2 is not compiled in. */ #include char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num) { - (void) h; - (void) num; + (void)h; + (void)num; return NULL; } char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header) { - (void) h; - (void) header; + (void)h; + (void)header; return NULL; } -#endif /* USE_NGHTTP2 */ +#endif /* !CURL_DISABLE_HTTP && USE_NGHTTP2 */ diff --git a/vendor/curl/lib/http_aws_sigv4.c b/vendor/curl/lib/http_aws_sigv4.c index 74253823591..850b7ae1125 100644 --- a/vendor/curl/lib/http_aws_sigv4.c +++ b/vendor/curl/lib/http_aws_sigv4.c @@ -537,8 +537,8 @@ static int compare_func(const void *a, const void *b) } UNITTEST CURLcode canon_path(const char *q, size_t len, - struct dynbuf *new_path, - bool do_uri_encode) + struct dynbuf *new_path, + bool do_uri_encode) { CURLcode result = CURLE_OK; @@ -1149,4 +1149,4 @@ static bool should_urlencode(struct Curl_str *service_name) return true; } -#endif /* !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_AWS) */ +#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_AWS */ diff --git a/vendor/curl/lib/http_chunks.c b/vendor/curl/lib/http_chunks.c index 63e477c48a6..f014a256ab8 100644 --- a/vendor/curl/lib/http_chunks.c +++ b/vendor/curl/lib/http_chunks.c @@ -159,7 +159,7 @@ static CURLcode httpchunk_readwrite(struct Curl_easy *data, } else { const char *p; - if(0 == ch->hexindex) { + if(ch->hexindex == 0) { /* This is illegal data, we received junk where we expected a hexadecimal digit. */ failf(data, "chunk hex-length char not a hex digit: 0x%x", *buf); @@ -184,7 +184,7 @@ static CURLcode httpchunk_readwrite(struct Curl_easy *data, /* waiting for the LF after a chunk size */ if(*buf == 0x0a) { /* we are now expecting data to come, unless size was zero! */ - if(0 == ch->datasize) { + if(ch->datasize == 0) { ch->state = CHUNK_TRAILER; /* now check for trailers */ } else { @@ -229,7 +229,7 @@ static CURLcode httpchunk_readwrite(struct Curl_easy *data, FMT_OFF_T " bytes in chunk remain", piece, ch->datasize); - if(0 == ch->datasize) + if(ch->datasize == 0) /* end of data this round, we now expect a trailing CRLF */ ch->state = CHUNK_POSTLF; break; diff --git a/vendor/curl/lib/http_digest.c b/vendor/curl/lib/http_digest.c index 651bb834037..dbc6023eb32 100644 --- a/vendor/curl/lib/http_digest.c +++ b/vendor/curl/lib/http_digest.c @@ -120,7 +120,7 @@ CURLcode Curl_output_digest(struct Curl_easy *data, if(!passwdp) passwdp = ""; -#if defined(USE_WINDOWS_SSPI) +#ifdef USE_WINDOWS_SSPI have_chlg = !!digest->input_token; #else have_chlg = !!digest->nonce; diff --git a/vendor/curl/lib/http_negotiate.c b/vendor/curl/lib/http_negotiate.c index 5bec3b39ff5..2c0b7e16d76 100644 --- a/vendor/curl/lib/http_negotiate.c +++ b/vendor/curl/lib/http_negotiate.c @@ -39,6 +39,20 @@ #include "curl_memory.h" #include "memdebug.h" + +static void http_auth_nego_reset(struct connectdata *conn, + struct negotiatedata *neg_ctx, + bool proxy) +{ + if(proxy) + conn->proxy_negotiate_state = GSS_AUTHNONE; + else + conn->http_negotiate_state = GSS_AUTHNONE; + if(neg_ctx) + Curl_auth_cleanup_spnego(neg_ctx); +} + + CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn, bool proxy, const char *header) { @@ -62,7 +76,6 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn, service = data->set.str[STRING_PROXY_SERVICE_NAME] ? data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP"; host = conn->http_proxy.host.name; - neg_ctx = &conn->proxyneg; state = conn->proxy_negotiate_state; #else return CURLE_NOT_BUILT_IN; @@ -74,10 +87,13 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn, service = data->set.str[STRING_SERVICE_NAME] ? data->set.str[STRING_SERVICE_NAME] : "HTTP"; host = conn->host.name; - neg_ctx = &conn->negotiate; state = conn->http_negotiate_state; } + neg_ctx = Curl_auth_nego_get(conn, proxy); + if(!neg_ctx) + return CURLE_OUT_OF_MEMORY; + /* Not set means empty */ if(!userp) userp = ""; @@ -94,12 +110,12 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn, if(!len) { if(state == GSS_AUTHSUCC) { infof(data, "Negotiate auth restarted"); - Curl_http_auth_cleanup_negotiate(conn); + http_auth_nego_reset(conn, neg_ctx, proxy); } else if(state != GSS_AUTHNONE) { /* The server rejected our authentication and has not supplied any more negotiation mechanisms */ - Curl_http_auth_cleanup_negotiate(conn); + http_auth_nego_reset(conn, neg_ctx, proxy); return CURLE_LOGIN_DENIED; } } @@ -116,7 +132,7 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn, result = Curl_ssl_get_channel_binding( data, FIRSTSOCKET, &neg_ctx->channel_binding_data); if(result) { - Curl_http_auth_cleanup_negotiate(conn); + http_auth_nego_reset(conn, neg_ctx, proxy); return result; } } @@ -134,7 +150,7 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn, #endif if(result) - Curl_http_auth_cleanup_negotiate(conn); + http_auth_nego_reset(conn, neg_ctx, proxy); return result; } @@ -152,7 +168,6 @@ CURLcode Curl_output_negotiate(struct Curl_easy *data, if(proxy) { #ifndef CURL_DISABLE_PROXY - neg_ctx = &conn->proxyneg; authp = &data->state.authproxy; state = &conn->proxy_negotiate_state; #else @@ -160,10 +175,12 @@ CURLcode Curl_output_negotiate(struct Curl_easy *data, #endif } else { - neg_ctx = &conn->negotiate; authp = &data->state.authhost; state = &conn->http_negotiate_state; } + neg_ctx = Curl_auth_nego_get(conn, proxy); + if(!neg_ctx) + return CURLE_OUT_OF_MEMORY; authp->done = FALSE; @@ -184,7 +201,7 @@ CURLcode Curl_output_negotiate(struct Curl_easy *data, if(neg_ctx->noauthpersist && *state == GSS_AUTHSUCC) { infof(data, "Curl_output_negotiate, " "no persistent authentication: cleanup existing context"); - Curl_http_auth_cleanup_negotiate(conn); + http_auth_nego_reset(conn, neg_ctx, proxy); } if(!neg_ctx->context) { result = Curl_input_negotiate(data, conn, proxy, "Negotiate"); @@ -249,13 +266,4 @@ CURLcode Curl_output_negotiate(struct Curl_easy *data, return CURLE_OK; } -void Curl_http_auth_cleanup_negotiate(struct connectdata *conn) -{ - conn->http_negotiate_state = GSS_AUTHNONE; - conn->proxy_negotiate_state = GSS_AUTHNONE; - - Curl_auth_cleanup_spnego(&conn->negotiate); - Curl_auth_cleanup_spnego(&conn->proxyneg); -} - #endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */ diff --git a/vendor/curl/lib/http_negotiate.h b/vendor/curl/lib/http_negotiate.h index 76d8356132d..ad7c43d833e 100644 --- a/vendor/curl/lib/http_negotiate.h +++ b/vendor/curl/lib/http_negotiate.h @@ -34,10 +34,6 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn, CURLcode Curl_output_negotiate(struct Curl_easy *data, struct connectdata *conn, bool proxy); -void Curl_http_auth_cleanup_negotiate(struct connectdata *conn); - -#else /* !CURL_DISABLE_HTTP && USE_SPNEGO */ -#define Curl_http_auth_cleanup_negotiate(x) #endif #endif /* HEADER_CURL_HTTP_NEGOTIATE_H */ diff --git a/vendor/curl/lib/http_ntlm.c b/vendor/curl/lib/http_ntlm.c index e6a3b175a77..a172eb848dd 100644 --- a/vendor/curl/lib/http_ntlm.c +++ b/vendor/curl/lib/http_ntlm.c @@ -45,7 +45,7 @@ /* SSL backend-specific #if branches in this file must be kept in the order documented in curl_ntlm_core. */ -#if defined(USE_WINDOWS_SSPI) +#ifdef USE_WINDOWS_SSPI #include "curl_sspi.h" #endif @@ -60,17 +60,18 @@ CURLcode Curl_input_ntlm(struct Curl_easy *data, header */ { /* point to the correct struct with this */ - struct ntlmdata *ntlm; curlntlm *state; CURLcode result = CURLE_OK; struct connectdata *conn = data->conn; - ntlm = proxy ? &conn->proxyntlm : &conn->ntlm; state = proxy ? &conn->proxy_ntlm_state : &conn->http_ntlm_state; if(checkprefix("NTLM", header)) { - header += strlen("NTLM"); + struct ntlmdata *ntlm = Curl_auth_ntlm_get(conn, proxy); + if(!ntlm) + return CURLE_FAILED_INIT; + header += strlen("NTLM"); curlx_str_passblanks(&header); if(*header) { unsigned char *hdr; @@ -93,11 +94,11 @@ CURLcode Curl_input_ntlm(struct Curl_easy *data, else { if(*state == NTLMSTATE_LAST) { infof(data, "NTLM auth restarted"); - Curl_http_auth_cleanup_ntlm(conn); + Curl_auth_ntlm_remove(conn, proxy); } else if(*state == NTLMSTATE_TYPE3) { infof(data, "NTLM handshake rejected"); - Curl_http_auth_cleanup_ntlm(conn); + Curl_auth_ntlm_remove(conn, proxy); *state = NTLMSTATE_NONE; return CURLE_REMOTE_ACCESS_DENIED; } @@ -150,7 +151,6 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy) service = data->set.str[STRING_PROXY_SERVICE_NAME] ? data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP"; hostname = conn->http_proxy.host.name; - ntlm = &conn->proxyntlm; state = &conn->proxy_ntlm_state; authp = &data->state.authproxy; #else @@ -164,10 +164,12 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy) service = data->set.str[STRING_SERVICE_NAME] ? data->set.str[STRING_SERVICE_NAME] : "HTTP"; hostname = conn->host.name; - ntlm = &conn->ntlm; state = &conn->http_ntlm_state; authp = &data->state.authhost; } + ntlm = Curl_auth_ntlm_get(conn, proxy); + if(!ntlm) + return CURLE_OUT_OF_MEMORY; authp->done = FALSE; /* not set means empty */ @@ -178,10 +180,10 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy) passwdp = ""; #ifdef USE_WINDOWS_SSPI - if(!Curl_hSecDll) { + if(!Curl_pSecFn) { /* not thread safe and leaks - use curl_global_init() to avoid */ CURLcode err = Curl_sspi_global_init(); - if(!Curl_hSecDll) + if(!Curl_pSecFn) return err; } #ifdef SECPKG_ATTR_ENDPOINT_BINDINGS @@ -200,9 +202,8 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy) case NTLMSTATE_TYPE1: default: /* for the weird cases we (re)start here */ /* Create a type-1 message */ - result = Curl_auth_create_ntlm_type1_message(data, userp, passwdp, - service, hostname, - ntlm, &ntlmmsg); + result = Curl_auth_create_ntlm_type1_message(data, userp, passwdp, service, + hostname, ntlm, &ntlmmsg); if(!result) { DEBUGASSERT(Curl_bufref_len(&ntlmmsg) != 0); result = curlx_base64_encode((const char *) Curl_bufref_ptr(&ntlmmsg), @@ -258,10 +259,4 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy) return result; } -void Curl_http_auth_cleanup_ntlm(struct connectdata *conn) -{ - Curl_auth_cleanup_ntlm(&conn->ntlm); - Curl_auth_cleanup_ntlm(&conn->proxyntlm); -} - #endif /* !CURL_DISABLE_HTTP && USE_NTLM */ diff --git a/vendor/curl/lib/http_ntlm.h b/vendor/curl/lib/http_ntlm.h index c1cf05701f4..b38ff82dba3 100644 --- a/vendor/curl/lib/http_ntlm.h +++ b/vendor/curl/lib/http_ntlm.h @@ -35,10 +35,6 @@ CURLcode Curl_input_ntlm(struct Curl_easy *data, bool proxy, /* this is for creating NTLM header output */ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy); -void Curl_http_auth_cleanup_ntlm(struct connectdata *conn); - -#else /* !CURL_DISABLE_HTTP && USE_NTLM */ -#define Curl_http_auth_cleanup_ntlm(x) #endif #endif /* HEADER_CURL_HTTP_NTLM_H */ diff --git a/vendor/curl/lib/http_proxy.c b/vendor/curl/lib/http_proxy.c index 3df6329c06f..df51484eb97 100644 --- a/vendor/curl/lib/http_proxy.c +++ b/vendor/curl/lib/http_proxy.c @@ -38,7 +38,6 @@ #include "cf-h1-proxy.h" #include "cf-h2-proxy.h" #include "connect.h" -#include "strcase.h" #include "vtls/vtls.h" #include "transfer.h" #include "multiif.h" @@ -53,7 +52,7 @@ static bool hd_name_eq(const char *n1, size_t n1len, const char *n2, size_t n2len) { - return (n1len == n2len) ? strncasecompare(n1, n2, n1len) : FALSE; + return (n1len == n2len) ? curl_strnequal(n1, n2, n1len) : FALSE; } static CURLcode dynhds_add_custom(struct Curl_easy *data, @@ -326,36 +325,42 @@ static CURLcode http_proxy_cf_connect(struct Curl_cfilter *cf, if(!ctx->cf_protocol) { struct Curl_cfilter *cf_protocol = NULL; int httpversion = 0; - int alpn = Curl_conn_cf_is_ssl(cf->next) ? - cf->conn->proxy_alpn : CURL_HTTP_VERSION_1_1; - - /* First time call after the subchain connected */ - switch(alpn) { - case CURL_HTTP_VERSION_NONE: - case CURL_HTTP_VERSION_1_0: - case CURL_HTTP_VERSION_1_1: + const char *alpn = Curl_conn_cf_get_alpn_negotiated(cf->next, data); + + if(alpn) + infof(data, "CONNECT: '%s' negotiated", alpn); + else + infof(data, "CONNECT: no ALPN negotiated"); + + if(alpn && !strcmp(alpn, "http/1.0")) { + CURL_TRC_CF(data, cf, "installing subfilter for HTTP/1.0"); + result = Curl_cf_h1_proxy_insert_after(cf, data); + if(result) + goto out; + cf_protocol = cf->next; + httpversion = 10; + } + else if(!alpn || !strcmp(alpn, "http/1.1")) { CURL_TRC_CF(data, cf, "installing subfilter for HTTP/1.1"); - infof(data, "CONNECT tunnel: HTTP/1.%d negotiated", - (alpn == CURL_HTTP_VERSION_1_0) ? 0 : 1); result = Curl_cf_h1_proxy_insert_after(cf, data); if(result) goto out; cf_protocol = cf->next; - httpversion = (alpn == CURL_HTTP_VERSION_1_0) ? 10 : 11; - break; + /* Assume that without an ALPN, we are talking to an ancient one */ + httpversion = 11; + } #ifdef USE_NGHTTP2 - case CURL_HTTP_VERSION_2: + else if(!strcmp(alpn, "h2")) { CURL_TRC_CF(data, cf, "installing subfilter for HTTP/2"); - infof(data, "CONNECT tunnel: HTTP/2 negotiated"); result = Curl_cf_h2_proxy_insert_after(cf, data); if(result) goto out; cf_protocol = cf->next; httpversion = 20; - break; + } #endif - default: - infof(data, "CONNECT tunnel: unsupported ALPN(%d) negotiated", alpn); + else { + failf(data, "CONNECT: negotiated ALPN '%s' not supported", alpn); result = CURLE_COULDNT_CONNECT; goto out; } @@ -383,21 +388,27 @@ static CURLcode http_proxy_cf_connect(struct Curl_cfilter *cf, return result; } -void Curl_cf_http_proxy_get_host(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char **phost, - const char **pdisplay_host, - int *pport) +CURLcode Curl_cf_http_proxy_query(struct Curl_cfilter *cf, + struct Curl_easy *data, + int query, int *pres1, void *pres2) { - (void)data; - if(!cf->connected) { - *phost = cf->conn->http_proxy.host.name; - *pdisplay_host = cf->conn->http_proxy.host.dispname; - *pport = (int)cf->conn->http_proxy.port; + switch(query) { + case CF_QUERY_HOST_PORT: + *pres1 = (int)cf->conn->http_proxy.port; + *((const char **)pres2) = cf->conn->http_proxy.host.name; + return CURLE_OK; + case CF_QUERY_ALPN_NEGOTIATED: { + const char **palpn = pres2; + DEBUGASSERT(palpn); + *palpn = NULL; + return CURLE_OK; } - else { - cf->next->cft->get_host(cf->next, data, phost, pdisplay_host, pport); + default: + break; } + return cf->next ? + cf->next->cft->query(cf->next, data, query, pres1, pres2) : + CURLE_UNKNOWN_OPTION; } static void http_proxy_cf_destroy(struct Curl_cfilter *cf, @@ -443,7 +454,6 @@ struct Curl_cftype Curl_cft_http_proxy = { http_proxy_cf_connect, http_proxy_cf_close, Curl_cf_def_shutdown, - Curl_cf_http_proxy_get_host, Curl_cf_def_adjust_pollset, Curl_cf_def_data_pending, Curl_cf_def_send, @@ -451,7 +461,7 @@ struct Curl_cftype Curl_cft_http_proxy = { Curl_cf_def_cntrl, Curl_cf_def_conn_is_alive, Curl_cf_def_conn_keep_alive, - Curl_cf_def_query, + Curl_cf_http_proxy_query, }; CURLcode Curl_cf_http_proxy_insert_after(struct Curl_cfilter *cf_at, diff --git a/vendor/curl/lib/http_proxy.h b/vendor/curl/lib/http_proxy.h index 2e91ff20371..e6ab2bacf3b 100644 --- a/vendor/curl/lib/http_proxy.h +++ b/vendor/curl/lib/http_proxy.h @@ -48,18 +48,16 @@ CURLcode Curl_http_proxy_create_CONNECT(struct httpreq **preq, /* Default proxy timeout in milliseconds */ #define PROXY_TIMEOUT (3600*1000) -void Curl_cf_http_proxy_get_host(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char **phost, - const char **pdisplay_host, - int *pport); +CURLcode Curl_cf_http_proxy_query(struct Curl_cfilter *cf, + struct Curl_easy *data, + int query, int *pres1, void *pres2); CURLcode Curl_cf_http_proxy_insert_after(struct Curl_cfilter *cf_at, struct Curl_easy *data); extern struct Curl_cftype Curl_cft_http_proxy; -#endif /* !CURL_DISABLE_PROXY && !CURL_DISABLE_HTTP */ +#endif /* !CURL_DISABLE_PROXY && !CURL_DISABLE_HTTP */ #define IS_HTTPS_PROXY(t) (((t) == CURLPROXY_HTTPS) || \ ((t) == CURLPROXY_HTTPS2)) diff --git a/vendor/curl/lib/httpsrr.h b/vendor/curl/lib/httpsrr.h index 83119dc6bde..563d1c8e515 100644 --- a/vendor/curl/lib/httpsrr.h +++ b/vendor/curl/lib/httpsrr.h @@ -76,7 +76,7 @@ void Curl_httpsrr_cleanup(struct Curl_https_rrinfo *rrinfo); #define HTTPS_RR_CODE_ECH 0x05 #define HTTPS_RR_CODE_IPV6 0x06 -#if defined(USE_ARES) +#ifdef USE_ARES CURLcode Curl_httpsrr_from_ares(struct Curl_easy *data, const ares_dns_record_t *dnsrec, struct Curl_https_rrinfo *hinfo); diff --git a/vendor/curl/lib/idn.c b/vendor/curl/lib/idn.c index 798c9aaef1a..63d2b8645a7 100644 --- a/vendor/curl/lib/idn.c +++ b/vendor/curl/lib/idn.c @@ -51,7 +51,7 @@ #include "memdebug.h" /* for macOS and iOS targets */ -#if defined(USE_APPLE_IDN) +#ifdef USE_APPLE_IDN #include #include #include @@ -152,7 +152,7 @@ static CURLcode mac_ascii_to_idn(const char *in, char **out) #ifdef USE_WIN32_IDN /* using Windows kernel32 and normaliz libraries. */ -#if (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x600) && \ +#if (!defined(_WIN32_WINNT) || _WIN32_WINNT < _WIN32_WINNT_VISTA) && \ (!defined(WINVER) || WINVER < 0x600) WINBASEAPI int WINAPI IdnToAscii(DWORD dwFlags, const WCHAR *lpUnicodeCharStr, diff --git a/vendor/curl/lib/if2ip.c b/vendor/curl/lib/if2ip.c index 6da68efd500..91ee59c02a7 100644 --- a/vendor/curl/lib/if2ip.c +++ b/vendor/curl/lib/if2ip.c @@ -52,8 +52,7 @@ # include #endif -#include "inet_ntop.h" -#include "strcase.h" +#include "curlx/inet_ntop.h" #include "if2ip.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -95,7 +94,7 @@ unsigned int Curl_ipv6_scope(const struct sockaddr *sa) #if !defined(CURL_DISABLE_BINDLOCAL) || !defined(CURL_DISABLE_FTP) -#if defined(HAVE_GETIFADDRS) +#ifdef HAVE_GETIFADDRS if2ip_result_t Curl_if2ip(int af, #ifdef USE_IPV6 @@ -110,14 +109,14 @@ if2ip_result_t Curl_if2ip(int af, #if defined(USE_IPV6) && \ !defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) - (void) local_scope_id; + (void)local_scope_id; #endif if(getifaddrs(&head) >= 0) { for(iface = head; iface != NULL; iface = iface->ifa_next) { if(iface->ifa_addr) { if(iface->ifa_addr->sa_family == af) { - if(strcasecompare(iface->ifa_name, interf)) { + if(curl_strequal(iface->ifa_name, interf)) { void *addr; const char *ip; char scope[12] = ""; @@ -162,13 +161,13 @@ if2ip_result_t Curl_if2ip(int af, addr = &((struct sockaddr_in *)(void *)iface->ifa_addr)->sin_addr; res = IF2IP_FOUND; - ip = Curl_inet_ntop(af, addr, ipstr, sizeof(ipstr)); + ip = curlx_inet_ntop(af, addr, ipstr, sizeof(ipstr)); msnprintf(buf, buf_size, "%s%s", ip, scope); break; } } else if((res == IF2IP_NOT_FOUND) && - strcasecompare(iface->ifa_name, interf)) { + curl_strequal(iface->ifa_name, interf)) { res = IF2IP_AF_NOT_SUPPORTED; } } @@ -235,7 +234,7 @@ if2ip_result_t Curl_if2ip(int af, s = (struct sockaddr_in *)(void *)&req.ifr_addr; memcpy(&in, &s->sin_addr, sizeof(in)); - r = Curl_inet_ntop(s->sin_family, &in, buf, buf_size); + r = curlx_inet_ntop(s->sin_family, &in, buf, buf_size); sclose(dummy); if(!r) @@ -253,14 +252,14 @@ if2ip_result_t Curl_if2ip(int af, const char *interf, char *buf, size_t buf_size) { - (void) af; + (void)af; #ifdef USE_IPV6 - (void) remote_scope; - (void) local_scope_id; + (void)remote_scope; + (void)local_scope_id; #endif - (void) interf; - (void) buf; - (void) buf_size; + (void)interf; + (void)buf; + (void)buf_size; return IF2IP_NOT_FOUND; } diff --git a/vendor/curl/lib/imap.c b/vendor/curl/lib/imap.c index fc38a5b61e0..7e6b132ba0d 100644 --- a/vendor/curl/lib/imap.c +++ b/vendor/curl/lib/imap.c @@ -157,8 +157,8 @@ static CURLcode imap_connect(struct Curl_easy *data, bool *done); static CURLcode imap_disconnect(struct Curl_easy *data, struct connectdata *conn, bool dead); static CURLcode imap_multi_statemach(struct Curl_easy *data, bool *done); -static int imap_getsock(struct Curl_easy *data, struct connectdata *conn, - curl_socket_t *socks); +static CURLcode imap_pollset(struct Curl_easy *data, + struct easy_pollset *ps); static CURLcode imap_doing(struct Curl_easy *data, bool *dophase_done); static CURLcode imap_setup_connection(struct Curl_easy *data, struct connectdata *conn); @@ -196,10 +196,10 @@ const struct Curl_handler Curl_handler_imap = { imap_connect, /* connect_it */ imap_multi_statemach, /* connecting */ imap_doing, /* doing */ - imap_getsock, /* proto_getsock */ - imap_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + imap_pollset, /* proto_pollset */ + imap_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ imap_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -227,10 +227,10 @@ const struct Curl_handler Curl_handler_imaps = { imap_connect, /* connect_it */ imap_multi_statemach, /* connecting */ imap_doing, /* doing */ - imap_getsock, /* proto_getsock */ - imap_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + imap_pollset, /* proto_pollset */ + imap_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ imap_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -302,7 +302,7 @@ static bool imap_matchresp(const char *line, size_t len, const char *cmd) /* Does the command name match and is it followed by a space character or at the end of line? */ - if(line + cmd_len <= end && strncasecompare(line, cmd, cmd_len) && + if(line + cmd_len <= end && curl_strnequal(line, cmd, cmd_len) && (line[cmd_len] == ' ' || line + cmd_len + 2 == end)) return TRUE; @@ -358,16 +358,16 @@ static bool imap_endofresp(struct Curl_easy *data, struct connectdata *conn, case IMAP_LIST: if((!imap->custom && !imap_matchresp(line, len, "LIST")) || (imap->custom && !imap_matchresp(line, len, imap->custom) && - (!strcasecompare(imap->custom, "STORE") || + (!curl_strequal(imap->custom, "STORE") || !imap_matchresp(line, len, "FETCH")) && - !strcasecompare(imap->custom, "SELECT") && - !strcasecompare(imap->custom, "EXAMINE") && - !strcasecompare(imap->custom, "SEARCH") && - !strcasecompare(imap->custom, "EXPUNGE") && - !strcasecompare(imap->custom, "LSUB") && - !strcasecompare(imap->custom, "UID") && - !strcasecompare(imap->custom, "GETQUOTAROOT") && - !strcasecompare(imap->custom, "NOOP"))) + !curl_strequal(imap->custom, "SELECT") && + !curl_strequal(imap->custom, "EXAMINE") && + !curl_strequal(imap->custom, "SEARCH") && + !curl_strequal(imap->custom, "EXPUNGE") && + !curl_strequal(imap->custom, "LSUB") && + !curl_strequal(imap->custom, "UID") && + !curl_strequal(imap->custom, "GETQUOTAROOT") && + !curl_strequal(imap->custom, "NOOP"))) return FALSE; break; @@ -1239,7 +1239,7 @@ static CURLcode imap_state_select_resp(struct Curl_easy *data, else if(imapcode == IMAP_RESP_OK) { /* Check if the UIDVALIDITY has been specified and matches */ if(imap->uidvalidity && imapc->mailbox_uidvalidity && - !strcasecompare(imap->uidvalidity, imapc->mailbox_uidvalidity)) { + !curl_strequal(imap->uidvalidity, imapc->mailbox_uidvalidity)) { failf(data, "Mailbox UIDVALIDITY has changed"); result = CURLE_REMOTE_FILE_NOT_FOUND; } @@ -1347,10 +1347,7 @@ static CURLcode imap_state_fetch_resp(struct Curl_easy *data, else { /* IMAP download */ data->req.maxdownload = size; - /* force a recv/send check of this connection, as the data might've been - read off the socket already */ - data->state.select_bits = CURL_CSELECT_IN; - Curl_xfer_setup1(data, CURL_XFER_RECV, size, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, size); } } else { @@ -1401,7 +1398,7 @@ static CURLcode imap_state_append_resp(struct Curl_easy *data, Curl_pgrsSetUploadSize(data, data->state.infilesize); /* IMAP upload */ - Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE); + Curl_xfer_setup_send(data, FIRSTSOCKET); /* End of DO phase */ imap_state(data, imapc, IMAP_STOP); @@ -1563,13 +1560,12 @@ static CURLcode imap_block_statemach(struct Curl_easy *data, } /* For the IMAP "protocol connect" and "doing" phases only */ -static int imap_getsock(struct Curl_easy *data, - struct connectdata *conn, - curl_socket_t *socks) +static CURLcode imap_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { - struct imap_conn *imapc = Curl_conn_meta_get(conn, CURL_META_IMAP_CONN); - return imapc ? - Curl_pp_getsock(data, &imapc->pp, socks) : GETSOCK_BLANK; + struct imap_conn *imapc = + Curl_conn_meta_get(data->conn, CURL_META_IMAP_CONN); + return imapc ? Curl_pp_pollset(data, &imapc->pp, ps) : CURLE_OK; } /*********************************************************************** @@ -1693,9 +1689,9 @@ static CURLcode imap_perform(struct Curl_easy *data, bool *connected, /* Determine if the requested mailbox (with the same UIDVALIDITY if set) has already been selected on this connection */ if(imap->mailbox && imapc->mailbox && - strcasecompare(imap->mailbox, imapc->mailbox) && + curl_strequal(imap->mailbox, imapc->mailbox) && (!imap->uidvalidity || !imapc->mailbox_uidvalidity || - strcasecompare(imap->uidvalidity, imapc->mailbox_uidvalidity))) + curl_strequal(imap->uidvalidity, imapc->mailbox_uidvalidity))) selected = TRUE; /* Start the first command in the DO phase */ @@ -1780,18 +1776,14 @@ static CURLcode imap_disconnect(struct Curl_easy *data, (void)data; if(imapc) { /* We cannot send quit unconditionally. If this connection is stale or - bad in any way, sending quit and waiting around here will make the + bad in any way (pingpong has pending data to send), + sending quit and waiting around here will make the disconnect wait in vain and cause more problems than we need to. */ - - /* The IMAP session may or may not have been allocated/setup at this - point! */ - if(!dead_connection && conn->bits.protoconnstart) { + if(!dead_connection && conn->bits.protoconnstart && + !Curl_pp_needs_flush(data, &imapc->pp)) { if(!imap_perform_logout(data, imapc)) (void)imap_block_statemach(data, imapc, TRUE); /* ignore errors */ } - - /* Cleanup the SASL module */ - Curl_sasl_cleanup(conn, imapc->sasl.authused); } return CURLE_OK; } @@ -2079,12 +2071,12 @@ static CURLcode imap_parse_url_options(struct connectdata *conn, while(*ptr && *ptr != ';') ptr++; - if(strncasecompare(key, "AUTH=+LOGIN", 11)) { + if(curl_strnequal(key, "AUTH=+LOGIN", 11)) { /* User prefers plaintext LOGIN over any SASL, including SASL LOGIN */ prefer_login = TRUE; imapc->sasl.prefmech = SASL_AUTH_NONE; } - else if(strncasecompare(key, "AUTH=", 5)) { + else if(curl_strnequal(key, "AUTH=", 5)) { prefer_login = FALSE; result = Curl_sasl_parse_url_auth_option(&imapc->sasl, value, ptr - value); @@ -2189,35 +2181,35 @@ static CURLcode imap_parse_url_path(struct Curl_easy *data, PARTIAL) stripping of the trailing slash character if it is present. Note: Unknown parameters trigger a URL_MALFORMAT error. */ - if(strcasecompare(name, "UIDVALIDITY") && !imap->uidvalidity) { + if(curl_strequal(name, "UIDVALIDITY") && !imap->uidvalidity) { if(valuelen > 0 && value[valuelen - 1] == '/') value[valuelen - 1] = '\0'; imap->uidvalidity = value; value = NULL; } - else if(strcasecompare(name, "UID") && !imap->uid) { + else if(curl_strequal(name, "UID") && !imap->uid) { if(valuelen > 0 && value[valuelen - 1] == '/') value[valuelen - 1] = '\0'; imap->uid = value; value = NULL; } - else if(strcasecompare(name, "MAILINDEX") && !imap->mindex) { + else if(curl_strequal(name, "MAILINDEX") && !imap->mindex) { if(valuelen > 0 && value[valuelen - 1] == '/') value[valuelen - 1] = '\0'; imap->mindex = value; value = NULL; } - else if(strcasecompare(name, "SECTION") && !imap->section) { + else if(curl_strequal(name, "SECTION") && !imap->section) { if(valuelen > 0 && value[valuelen - 1] == '/') value[valuelen - 1] = '\0'; imap->section = value; value = NULL; } - else if(strcasecompare(name, "PARTIAL") && !imap->partial) { + else if(curl_strequal(name, "PARTIAL") && !imap->partial) { if(valuelen > 0 && value[valuelen - 1] == '/') value[valuelen - 1] = '\0'; diff --git a/vendor/curl/lib/krb5.c b/vendor/curl/lib/krb5.c index 9ebba4e3d1d..40243bddb5a 100644 --- a/vendor/curl/lib/krb5.c +++ b/vendor/curl/lib/krb5.c @@ -56,7 +56,6 @@ #include "transfer.h" #include "curl_krb5.h" #include "curlx/warnless.h" -#include "strcase.h" #include "strdup.h" /* The last 3 #include files should be in this order */ @@ -215,12 +214,14 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn) gss_ctx_id_t *context = app_data; struct gss_channel_bindings_struct chan; size_t base64_sz = 0; - struct sockaddr_in *remote_addr = - (struct sockaddr_in *)CURL_UNCONST(&conn->remote_addr->curl_sa_addr); + const struct Curl_sockaddr_ex *remote_addr = + Curl_conn_get_remote_addr(data, FIRSTSOCKET); + struct sockaddr_in *remote_in_addr = remote_addr ? + (struct sockaddr_in *)CURL_UNCONST(&remote_addr->curl_sa_addr) : NULL; char *stringp; struct ftp_conn *ftpc = Curl_conn_meta_get(conn, CURL_META_FTP_CONN); - if(!ftpc) + if(!ftpc || !remote_in_addr) return -2; if(getsockname(conn->sock[FIRSTSOCKET], @@ -232,7 +233,7 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn) chan.initiator_address.value = &conn->local_addr.sin_addr.s_addr; chan.acceptor_addrtype = GSS_C_AF_INET; chan.acceptor_address.length = l - 4; - chan.acceptor_address.value = &remote_addr->sin_addr.s_addr; + chan.acceptor_address.value = &remote_in_addr->sin_addr.s_addr; chan.application_data.length = 0; chan.application_data.value = NULL; @@ -384,7 +385,8 @@ static void krb5_end(void *app_data) OM_uint32 min; gss_ctx_id_t *context = app_data; if(*context != GSS_C_NO_CONTEXT) { - OM_uint32 maj = gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER); + OM_uint32 maj = Curl_gss_delete_sec_context(&min, context, + GSS_C_NO_BUFFER); (void)maj; DEBUGASSERT(maj == GSS_S_COMPLETE); } @@ -479,19 +481,18 @@ socket_read(struct Curl_easy *data, int sockindex, void *to, size_t len) { char *to_p = to; CURLcode result; - ssize_t nread = 0; + size_t nread = 0; while(len > 0) { result = Curl_conn_recv(data, sockindex, to_p, len, &nread); - if(nread > 0) { - len -= nread; - to_p += nread; - } - else { - if(result == CURLE_AGAIN) - continue; + if(result == CURLE_AGAIN) + continue; + if(result) return result; - } + if(nread > len) + return CURLE_RECV_ERROR; + len -= nread; + to_p += nread; } return CURLE_OK; } @@ -523,8 +524,8 @@ socket_write(struct Curl_easy *data, int sockindex, const void *to, return CURLE_OK; } -static CURLcode read_data(struct Curl_easy *data, int sockindex, - struct krb5buffer *buf) +static CURLcode krb5_read_data(struct Curl_easy *data, int sockindex, + struct krb5buffer *buf) { struct connectdata *conn = data->conn; int len; @@ -579,52 +580,49 @@ buffer_read(struct krb5buffer *buf, void *data, size_t len) } /* Matches Curl_recv signature */ -static ssize_t sec_recv(struct Curl_easy *data, int sockindex, - char *buffer, size_t len, CURLcode *err) +static CURLcode sec_recv(struct Curl_easy *data, int sockindex, + char *buffer, size_t len, size_t *pnread) { - size_t bytes_read; - size_t total_read = 0; struct connectdata *conn = data->conn; - - *err = CURLE_OK; + CURLcode result = CURLE_OK; + size_t bytes_read; /* Handle clear text response. */ - if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR) { - ssize_t nread; - *err = Curl_conn_recv(data, sockindex, buffer, len, &nread); - return nread; - } + if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR) + return Curl_conn_recv(data, sockindex, buffer, len, pnread); if(conn->in_buffer.eof_flag) { conn->in_buffer.eof_flag = 0; - return 0; + *pnread = 0; + return CURLE_OK; } bytes_read = buffer_read(&conn->in_buffer, buffer, len); - len -= bytes_read; - total_read += bytes_read; buffer += bytes_read; + len -= bytes_read; + *pnread += bytes_read; while(len > 0) { - if(read_data(data, sockindex, &conn->in_buffer)) - return -1; + result = krb5_read_data(data, sockindex, &conn->in_buffer); + if(result) + return result; if(curlx_dyn_len(&conn->in_buffer.buf) == 0) { - if(bytes_read > 0) + if(*pnread > 0) conn->in_buffer.eof_flag = 1; - return bytes_read; + return result; } bytes_read = buffer_read(&conn->in_buffer, buffer, len); - len -= bytes_read; - total_read += bytes_read; buffer += bytes_read; + len -= bytes_read; + *pnread += bytes_read; } - return total_read; + return result; } /* Send |length| bytes from |from| to the |sockindex| socket taking care of encoding and negotiating with the server. |from| can be NULL. */ static void do_sec_send(struct Curl_easy *data, struct connectdata *conn, - int sockindex, const char *from, int length) + int sockindex, const char *from, size_t length) { int bytes, htonl_bytes; /* 32-bit integers for htonl */ char *buffer = NULL; @@ -642,8 +640,8 @@ static void do_sec_send(struct Curl_easy *data, struct connectdata *conn, else prot_level = conn->command_prot; } - bytes = conn->mech->encode(conn->app_data, from, length, (int)prot_level, - (void **)&buffer); + bytes = conn->mech->encode(conn->app_data, from, (int)length, + (int)prot_level, (void **)&buffer); if(!buffer || bytes <= 0) return; /* error */ @@ -677,34 +675,36 @@ static void do_sec_send(struct Curl_easy *data, struct connectdata *conn, free(buffer); } -static ssize_t sec_write(struct Curl_easy *data, struct connectdata *conn, - int sockindex, const char *buffer, size_t length) +static CURLcode sec_write(struct Curl_easy *data, int sockindex, + const char *buffer, size_t length, + size_t *pnwritten) { - ssize_t tx = 0, len = conn->buffer_size; + struct connectdata *conn = data->conn; + size_t len = conn->buffer_size; + *pnwritten = 0; if(len <= 0) len = length; while(length) { - if(length < (size_t)len) + if(length < len) len = length; - do_sec_send(data, conn, sockindex, buffer, curlx_sztosi(len)); + /* WTF: this ignores all errors writing to the socket */ + do_sec_send(data, conn, sockindex, buffer, len); length -= len; buffer += len; - tx += len; + *pnwritten += len; } - return tx; + return CURLE_OK; } /* Matches Curl_send signature */ -static ssize_t sec_send(struct Curl_easy *data, int sockindex, - const void *buffer, size_t len, bool eos, - CURLcode *err) +static CURLcode sec_send(struct Curl_easy *data, int sockindex, + const void *buffer, size_t len, bool eos, + size_t *pnwritten) { - struct connectdata *conn = data->conn; (void)eos; /* unused */ - *err = CURLE_OK; - return sec_write(data, conn, sockindex, buffer, len); + return sec_write(data, sockindex, buffer, len, pnwritten); } int Curl_sec_read_msg(struct Curl_easy *data, struct connectdata *conn, @@ -718,7 +718,7 @@ int Curl_sec_read_msg(struct Curl_easy *data, struct connectdata *conn, size_t decoded_sz = 0; CURLcode error; - (void) data; + (void)data; if(!conn->mech) /* not initialized, return error */ diff --git a/vendor/curl/lib/ldap.c b/vendor/curl/lib/ldap.c index c1be2f4bda9..c66a56d7bb2 100644 --- a/vendor/curl/lib/ldap.c +++ b/vendor/curl/lib/ldap.c @@ -43,7 +43,7 @@ */ /* Wincrypt must be included before anything that could include OpenSSL. */ -#if defined(USE_WIN32_CRYPTO) +#ifdef USE_WIN32_CRYPTO #include /* Undefine wincrypt conflicting symbols for BoringSSL. */ #undef X509_NAME @@ -88,7 +88,6 @@ #include "escape.h" #include "progress.h" #include "transfer.h" -#include "strcase.h" #include "curlx/strparse.h" #include "curl_ldap.h" #include "curlx/multibyte.h" @@ -106,7 +105,7 @@ struct ldap_urldesc { char *lud_host; int lud_port; -#if defined(USE_WIN32_LDAP) +#ifdef USE_WIN32_LDAP TCHAR *lud_dn; TCHAR **lud_attrs; #else @@ -114,7 +113,7 @@ struct ldap_urldesc { char **lud_attrs; #endif int lud_scope; -#if defined(USE_WIN32_LDAP) +#ifdef USE_WIN32_LDAP TCHAR *lud_filter; #else char *lud_filter; @@ -178,10 +177,10 @@ const struct Curl_handler Curl_handler_ldap = { ZERO_NULL, /* connect_it */ ZERO_NULL, /* connecting */ ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* proto_pollset */ + ZERO_NULL, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ ZERO_NULL, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -208,10 +207,10 @@ const struct Curl_handler Curl_handler_ldaps = { ZERO_NULL, /* connect_it */ ZERO_NULL, /* connecting */ ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* proto_pollset */ + ZERO_NULL, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ ZERO_NULL, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -225,9 +224,9 @@ const struct Curl_handler Curl_handler_ldaps = { }; #endif -#if defined(USE_WIN32_LDAP) +#ifdef USE_WIN32_LDAP -#if defined(USE_WINDOWS_SSPI) +#ifdef USE_WINDOWS_SSPI static int ldap_win_bind_auth(LDAP *server, const char *user, const char *passwd, unsigned long authflags) { @@ -237,19 +236,19 @@ static int ldap_win_bind_auth(LDAP *server, const char *user, memset(&cred, 0, sizeof(cred)); -#if defined(USE_SPNEGO) +#ifdef USE_SPNEGO if(authflags & CURLAUTH_NEGOTIATE) { method = LDAP_AUTH_NEGOTIATE; } else #endif -#if defined(USE_NTLM) +#ifdef USE_NTLM if(authflags & CURLAUTH_NTLM) { method = LDAP_AUTH_NTLM; } else #endif -#if !defined(CURL_DISABLE_DIGEST_AUTH) +#ifndef CURL_DISABLE_DIGEST_AUTH if(authflags & CURLAUTH_DIGEST) { method = LDAP_AUTH_DIGEST; } @@ -274,7 +273,7 @@ static int ldap_win_bind_auth(LDAP *server, const char *user, } return rc; } -#endif /* #if defined(USE_WINDOWS_SSPI) */ +#endif /* USE_WINDOWS_SSPI */ static int ldap_win_bind(struct Curl_easy *data, LDAP *server, const char *user, const char *passwd) @@ -293,7 +292,7 @@ static int ldap_win_bind(struct Curl_easy *data, LDAP *server, curlx_unicodefree(inuser); curlx_unicodefree(inpass); } -#if defined(USE_WINDOWS_SSPI) +#ifdef USE_WINDOWS_SSPI else { rc = (int)ldap_win_bind_auth(server, user, passwd, data->set.httpauth); } @@ -301,9 +300,9 @@ static int ldap_win_bind(struct Curl_easy *data, LDAP *server, return rc; } -#endif /* #if defined(USE_WIN32_LDAP) */ +#endif /* USE_WIN32_LDAP */ -#if defined(USE_WIN32_LDAP) +#ifdef USE_WIN32_LDAP #define FREE_ON_WINLDAP(x) curlx_unicodefree(x) #define curl_ldap_num_t ULONG #else @@ -329,13 +328,15 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) #ifdef LDAP_OPT_NETWORK_TIMEOUT struct timeval ldap_timeout = {10, 0}; /* 10 sec connection/search timeout */ #endif -#if defined(USE_WIN32_LDAP) +#ifdef USE_WIN32_LDAP TCHAR *host = NULL; #else char *host = NULL; #endif char *user = NULL; char *passwd = NULL; + struct ip_quadruple ipquad; + bool is_ipv6; *done = TRUE; /* unconditionally */ infof(data, "LDAP local: LDAP Vendor = %s ; LDAP Version = %d", @@ -353,13 +354,17 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) goto quit; } + result = Curl_conn_get_ip_info(data, conn, FIRSTSOCKET, &is_ipv6, &ipquad); + if(result) + goto quit; + /* Get the URL scheme (either ldap or ldaps) */ if(Curl_conn_is_ssl(conn, FIRSTSOCKET)) ldap_ssl = 1; infof(data, "LDAP local: trying to establish %s connection", ldap_ssl ? "encrypted" : "cleartext"); -#if defined(USE_WIN32_LDAP) +#ifdef USE_WIN32_LDAP host = curlx_convert_UTF8_to_tchar(conn->host.name); if(!host) { result = CURLE_OUT_OF_MEMORY; @@ -384,7 +389,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) #ifdef HAVE_LDAP_SSL #ifdef USE_WIN32_LDAP /* Win32 LDAP SDK does not support insecure mode without CA! */ - server = ldap_sslinit(host, (curl_ldap_num_t)conn->primary.remote_port, 1); + server = ldap_sslinit(host, (curl_ldap_num_t)ipquad.remote_port, 1); ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON); #else int ldap_option; @@ -393,7 +398,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) if(conn->ssl_config.verifypeer) { /* OpenLDAP SDK supports BASE64 files. */ if((data->set.ssl.cert_type) && - (!strcasecompare(data->set.ssl.cert_type, "PEM"))) { + (!curl_strequal(data->set.ssl.cert_type, "PEM"))) { failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type"); result = CURLE_SSL_CERTPROBLEM; goto quit; @@ -423,10 +428,10 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) result = CURLE_SSL_CERTPROBLEM; goto quit; } - server = ldap_init(host, conn->primary.remote_port); + server = ldap_init(host, ipquad.remote_port); if(!server) { failf(data, "LDAP local: Cannot connect to %s:%u", - conn->host.dispname, conn->primary.remote_port); + conn->host.dispname, ipquad.remote_port); result = CURLE_COULDNT_CONNECT; goto quit; } @@ -466,10 +471,10 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) goto quit; } else { - server = ldap_init(host, (curl_ldap_num_t)conn->primary.remote_port); + server = ldap_init(host, (curl_ldap_num_t)ipquad.remote_port); if(!server) { failf(data, "LDAP local: Cannot connect to %s:%u", - conn->host.dispname, conn->primary.remote_port); + conn->host.dispname, ipquad.remote_port); result = CURLE_COULDNT_CONNECT; goto quit; } @@ -517,7 +522,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) entryIterator; entryIterator = ldap_next_entry(server, entryIterator), num++) { BerElement *ber = NULL; -#if defined(USE_WIN32_LDAP) +#ifdef USE_WIN32_LDAP TCHAR *attribute; #else char *attribute; @@ -528,7 +533,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) { char *name; size_t name_len; -#if defined(USE_WIN32_LDAP) +#ifdef USE_WIN32_LDAP TCHAR *dn = ldap_get_dn(server, entryIterator); name = curlx_convert_tchar_to_UTF8(dn); if(!name) { @@ -575,7 +580,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) attribute = ldap_next_attribute(server, entryIterator, ber)) { BerValue **vals; size_t attr_len; -#if defined(USE_WIN32_LDAP) +#ifdef USE_WIN32_LDAP char *attr = curlx_convert_tchar_to_UTF8(attribute); if(!attr) { if(ber) @@ -748,15 +753,15 @@ static void _ldap_trace(const char *fmt, ...) */ static int str2scope(const char *p) { - if(strcasecompare(p, "one")) + if(curl_strequal(p, "one")) return LDAP_SCOPE_ONELEVEL; - if(strcasecompare(p, "onetree")) + if(curl_strequal(p, "onetree")) return LDAP_SCOPE_ONELEVEL; - if(strcasecompare(p, "base")) + if(curl_strequal(p, "base")) return LDAP_SCOPE_BASE; - if(strcasecompare(p, "sub")) + if(curl_strequal(p, "sub")) return LDAP_SCOPE_SUBTREE; - if(strcasecompare(p, "subtree")) + if(curl_strequal(p, "subtree")) return LDAP_SCOPE_SUBTREE; return -1; } @@ -801,7 +806,7 @@ static int _ldap_url_parse2(struct Curl_easy *data, if(!data || !data->state.up.path || data->state.up.path[0] != '/' || - !strncasecompare("LDAP", data->state.up.scheme, 4)) + !curl_strnequal("LDAP", data->state.up.scheme, 4)) return LDAP_INVALID_SYNTAX; ludp->lud_scope = LDAP_SCOPE_BASE; @@ -838,7 +843,7 @@ static int _ldap_url_parse2(struct Curl_easy *data, goto quit; } -#if defined(USE_WIN32_LDAP) +#ifdef USE_WIN32_LDAP /* Convert the unescaped string to a tchar */ ludp->lud_dn = curlx_convert_UTF8_to_tchar(unescaped); @@ -869,7 +874,7 @@ static int _ldap_url_parse2(struct Curl_easy *data, const char *atp = p; /* Allocate our array (+1 for the NULL entry) */ -#if defined(USE_WIN32_LDAP) +#ifdef USE_WIN32_LDAP ludp->lud_attrs = calloc(count + 1, sizeof(TCHAR *)); #else ludp->lud_attrs = calloc(count + 1, sizeof(char *)); @@ -897,7 +902,7 @@ static int _ldap_url_parse2(struct Curl_easy *data, goto quit; } -#if defined(USE_WIN32_LDAP) +#ifdef USE_WIN32_LDAP /* Convert the unescaped string to a tchar */ ludp->lud_attrs[i] = curlx_convert_UTF8_to_tchar(unescaped); @@ -961,7 +966,7 @@ static int _ldap_url_parse2(struct Curl_easy *data, goto quit; } -#if defined(USE_WIN32_LDAP) +#ifdef USE_WIN32_LDAP /* Convert the unescaped string to a tchar */ ludp->lud_filter = curlx_convert_UTF8_to_tchar(unescaped); @@ -1017,7 +1022,7 @@ static void _ldap_free_urldesc(LDAPURLDesc *ludp) if(!ludp) return; -#if defined(USE_WIN32_LDAP) +#ifdef USE_WIN32_LDAP curlx_unicodefree(ludp->lud_dn); curlx_unicodefree(ludp->lud_filter); #else @@ -1028,7 +1033,7 @@ static void _ldap_free_urldesc(LDAPURLDesc *ludp) if(ludp->lud_attrs) { size_t i; for(i = 0; i < ludp->lud_attrs_dups; i++) { -#if defined(USE_WIN32_LDAP) +#ifdef USE_WIN32_LDAP curlx_unicodefree(ludp->lud_attrs[i]); #else free(ludp->lud_attrs[i]); diff --git a/vendor/curl/lib/llist.c b/vendor/curl/lib/llist.c index 82934425cfc..c9a7d4a8a78 100644 --- a/vendor/curl/lib/llist.c +++ b/vendor/curl/lib/llist.c @@ -181,7 +181,8 @@ void *Curl_node_take_elem(struct Curl_llist_node *e) /* * @unittest: 1300 */ -void +UNITTEST void Curl_node_uremove(struct Curl_llist_node *, void *); +UNITTEST void Curl_node_uremove(struct Curl_llist_node *e, void *user) { struct Curl_llist *list; diff --git a/vendor/curl/lib/llist.h b/vendor/curl/lib/llist.h index 597c0e00a33..0a2bc9a62f4 100644 --- a/vendor/curl/lib/llist.h +++ b/vendor/curl/lib/llist.h @@ -57,7 +57,6 @@ void Curl_llist_insert_next(struct Curl_llist *, struct Curl_llist_node *, const void *, struct Curl_llist_node *node); void Curl_llist_append(struct Curl_llist *, const void *, struct Curl_llist_node *node); -void Curl_node_uremove(struct Curl_llist_node *, void *); void Curl_node_remove(struct Curl_llist_node *); void Curl_llist_destroy(struct Curl_llist *, void *); @@ -76,7 +75,7 @@ size_t Curl_llist_count(struct Curl_llist *list); void *Curl_node_elem(struct Curl_llist_node *n); /* Remove the node from the list and return the custom data - * from a Curl_llist_node. Will NOT incoke a registered `dtor`. */ + * from a Curl_llist_node. Will NOT invoke a registered `dtor`. */ void *Curl_node_take_elem(struct Curl_llist_node *); /* Curl_node_next() returns the next element in a list from a given diff --git a/vendor/curl/lib/md4.c b/vendor/curl/lib/md4.c index a77085a6b28..57545dde93d 100644 --- a/vendor/curl/lib/md4.c +++ b/vendor/curl/lib/md4.c @@ -24,7 +24,7 @@ #include "curl_setup.h" -#if defined(USE_CURL_NTLM_CORE) +#ifdef USE_CURL_NTLM_CORE #include @@ -64,10 +64,8 @@ #endif #endif /* USE_MBEDTLS */ -#if defined(USE_GNUTLS) -#include /* When OpenSSL or wolfSSL is available, we use their MD4 functions. */ -#elif defined(USE_WOLFSSL) && !defined(WOLFSSL_NO_MD4) +#if defined(USE_WOLFSSL) && !defined(WOLFSSL_NO_MD4) #include #elif defined(USE_OPENSSL) && !defined(OPENSSL_NO_MD4) #include @@ -83,6 +81,8 @@ #include #elif defined(USE_WIN32_CRYPTO) #include +#elif defined(USE_GNUTLS) +#include #elif(defined(USE_MBEDTLS) && defined(MBEDTLS_MD4_C)) #include #endif @@ -93,27 +93,7 @@ #include "memdebug.h" -#if defined(USE_GNUTLS) - -typedef struct md4_ctx MD4_CTX; - -static int MD4_Init(MD4_CTX *ctx) -{ - md4_init(ctx); - return 1; -} - -static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) -{ - md4_update(ctx, size, data); -} - -static void MD4_Final(unsigned char *result, MD4_CTX *ctx) -{ - md4_digest(ctx, MD4_DIGEST_SIZE, result); -} - -#elif defined(USE_WOLFSSL) && !defined(WOLFSSL_NO_MD4) +#if defined(USE_WOLFSSL) && !defined(WOLFSSL_NO_MD4) #ifdef OPENSSL_COEXIST #define MD4_CTX WOLFSSL_MD4_CTX @@ -193,6 +173,26 @@ static void MD4_Final(unsigned char *result, MD4_CTX *ctx) CryptReleaseContext(ctx->hCryptProv, 0); } +#elif defined(USE_GNUTLS) + +typedef struct md4_ctx MD4_CTX; + +static int MD4_Init(MD4_CTX *ctx) +{ + md4_init(ctx); + return 1; +} + +static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) +{ + md4_update(ctx, size, data); +} + +static void MD4_Final(unsigned char *result, MD4_CTX *ctx) +{ + md4_digest(ctx, MD4_DIGEST_SIZE, result); +} + #elif(defined(USE_MBEDTLS) && defined(MBEDTLS_MD4_C)) struct md4_ctx { @@ -220,10 +220,10 @@ static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) static void MD4_Final(unsigned char *result, MD4_CTX *ctx) { if(ctx->data) { -#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS) +#ifndef HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS mbedtls_md4(ctx->data, ctx->size, result); #else - (void) mbedtls_md4_ret(ctx->data, ctx->size, result); + (void)mbedtls_md4_ret(ctx->data, ctx->size, result); #endif Curl_safefree(ctx->data); diff --git a/vendor/curl/lib/md5.c b/vendor/curl/lib/md5.c index 6a273c56c0e..fea20377fe9 100644 --- a/vendor/curl/lib/md5.c +++ b/vendor/curl/lib/md5.c @@ -24,8 +24,8 @@ #include "curl_setup.h" -#if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) \ - || !defined(CURL_DISABLE_DIGEST_AUTH) +#if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) || \ + !defined(CURL_DISABLE_DIGEST_AUTH) #include #include @@ -57,7 +57,7 @@ #endif #endif -#if defined(USE_GNUTLS) +#ifdef USE_GNUTLS #include #elif defined(USE_OPENSSL_MD5) #include @@ -84,7 +84,7 @@ #include "curl_memory.h" #include "memdebug.h" -#if defined(USE_GNUTLS) +#ifdef USE_GNUTLS typedef struct md5_ctx my_md5_ctx; @@ -177,19 +177,19 @@ static void my_md5_update(void *ctx, const unsigned char *data, unsigned int length) { -#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS) - (void) mbedtls_md5_update(ctx, data, length); +#ifndef HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS + (void)mbedtls_md5_update(ctx, data, length); #else - (void) mbedtls_md5_update_ret(ctx, data, length); + (void)mbedtls_md5_update_ret(ctx, data, length); #endif } static void my_md5_final(unsigned char *digest, void *ctx) { -#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS) - (void) mbedtls_md5_finish(ctx, digest); +#ifndef HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS + (void)mbedtls_md5_finish(ctx, digest); #else - (void) mbedtls_md5_finish_ret(ctx, digest); + (void)mbedtls_md5_finish_ret(ctx, digest); #endif } diff --git a/vendor/curl/lib/memdebug.c b/vendor/curl/lib/memdebug.c index b351726b320..d063f94c321 100644 --- a/vendor/curl/lib/memdebug.c +++ b/vendor/curl/lib/memdebug.c @@ -30,8 +30,6 @@ #include "urldata.h" -#define MEMDEBUG_NODEFINES /* do not redefine the standard functions */ - /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" @@ -70,7 +68,7 @@ static void curl_dbg_cleanup(void) if(curl_dbg_logfile && curl_dbg_logfile != stderr && curl_dbg_logfile != stdout) { - fclose(curl_dbg_logfile); + (fclose)(curl_dbg_logfile); } curl_dbg_logfile = NULL; } @@ -80,7 +78,11 @@ void curl_dbg_memdebug(const char *logname) { if(!curl_dbg_logfile) { if(logname && *logname) - curl_dbg_logfile = fopen(logname, FOPEN_WRITETEXT); +#ifdef CURL_FOPEN + curl_dbg_logfile = CURL_FOPEN(logname, FOPEN_WRITETEXT); +#else + curl_dbg_logfile = (fopen)(logname, FOPEN_WRITETEXT); +#endif else curl_dbg_logfile = stderr; #ifdef MEMDEBUG_LOG_SYNC @@ -302,14 +304,14 @@ void curl_dbg_free(void *ptr, int line, const char *source) } curl_socket_t curl_dbg_socket(int domain, int type, int protocol, - int line, const char *source) + int line, const char *source) { curl_socket_t sockfd; if(countcheck("socket", line, source)) return CURL_SOCKET_BAD; - sockfd = socket(domain, type, protocol); + sockfd = (socket)(domain, type, protocol); if(source && (sockfd != CURL_SOCKET_BAD)) curl_dbg_log("FD %s:%d socket() = %" FMT_SOCKET_T "\n", @@ -326,7 +328,7 @@ SEND_TYPE_RETV curl_dbg_send(SEND_TYPE_ARG1 sockfd, SEND_TYPE_RETV rc; if(countcheck("send", line, source)) return -1; - rc = send(sockfd, buf, len, flags); + rc = (send)(sockfd, buf, len, flags); if(source) curl_dbg_log("SEND %s:%d send(%lu) = %ld\n", source, line, (unsigned long)len, (long)rc); @@ -340,7 +342,7 @@ RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd, RECV_TYPE_ARG2 buf, RECV_TYPE_RETV rc; if(countcheck("recv", line, source)) return -1; - rc = recv(sockfd, buf, len, flags); + rc = (recv)(sockfd, buf, len, flags); if(source) curl_dbg_log("RECV %s:%d recv(%lu) = %ld\n", source, line, (unsigned long)len, (long)rc); @@ -349,12 +351,12 @@ RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd, RECV_TYPE_ARG2 buf, #ifdef HAVE_SOCKETPAIR int curl_dbg_socketpair(int domain, int type, int protocol, - curl_socket_t socket_vector[2], - int line, const char *source) + curl_socket_t socket_vector[2], + int line, const char *source) { - int res = socketpair(domain, type, protocol, socket_vector); + int res = (socketpair)(domain, type, protocol, socket_vector); - if(source && (0 == res)) + if(source && (res == 0)) curl_dbg_log("FD %s:%d socketpair() = " "%" FMT_SOCKET_T " %" FMT_SOCKET_T "\n", source, line, socket_vector[0], socket_vector[1]); @@ -364,12 +366,12 @@ int curl_dbg_socketpair(int domain, int type, int protocol, #endif curl_socket_t curl_dbg_accept(curl_socket_t s, void *saddr, void *saddrlen, - int line, const char *source) + int line, const char *source) { struct sockaddr *addr = (struct sockaddr *)saddr; curl_socklen_t *addrlen = (curl_socklen_t *)saddrlen; - curl_socket_t sockfd = accept(s, addr, addrlen); + curl_socket_t sockfd = (accept)(s, addr, addrlen); if(source && (sockfd != CURL_SOCKET_BAD)) curl_dbg_log("FD %s:%d accept() = %" FMT_SOCKET_T "\n", @@ -386,7 +388,7 @@ curl_socket_t curl_dbg_accept4(curl_socket_t s, void *saddr, void *saddrlen, struct sockaddr *addr = (struct sockaddr *)saddr; curl_socklen_t *addrlen = (curl_socklen_t *)saddrlen; - curl_socket_t sockfd = accept4(s, addr, addrlen, flags); + curl_socket_t sockfd = (accept4)(s, addr, addrlen, flags); if(source && (sockfd != CURL_SOCKET_BAD)) curl_dbg_log("FD %s:%d accept() = %" FMT_SOCKET_T "\n", @@ -407,7 +409,7 @@ void curl_dbg_mark_sclose(curl_socket_t sockfd, int line, const char *source) /* this is our own defined way to close sockets on *ALL* platforms */ int curl_dbg_sclose(curl_socket_t sockfd, int line, const char *source) { - int res = sclose(sockfd); + int res = CURL_SCLOSE(sockfd); curl_dbg_mark_sclose(sockfd, line, source); return res; } @@ -416,7 +418,12 @@ ALLOC_FUNC FILE *curl_dbg_fopen(const char *file, const char *mode, int line, const char *source) { - FILE *res = fopen(file, mode); + FILE *res; +#ifdef CURL_FOPEN + res = CURL_FOPEN(file, mode); +#else + res = (fopen)(file, mode); +#endif if(source) curl_dbg_log("FILE %s:%d fopen(\"%s\",\"%s\") = %p\n", @@ -429,7 +436,7 @@ ALLOC_FUNC FILE *curl_dbg_fdopen(int filedes, const char *mode, int line, const char *source) { - FILE *res = fdopen(filedes, mode); + FILE *res = (fdopen)(filedes, mode); if(source) curl_dbg_log("FILE %s:%d fdopen(\"%d\",\"%s\") = %p\n", source, line, filedes, mode, (void *)res); @@ -446,7 +453,7 @@ int curl_dbg_fclose(FILE *file, int line, const char *source) curl_dbg_log("FILE %s:%d fclose(%p)\n", source, line, (void *)file); - res = fclose(file); + res = (fclose)(file); return res; } @@ -469,7 +476,7 @@ void curl_dbg_log(const char *format, ...) nchars = (int)sizeof(buf) - 1; if(nchars > 0) - fwrite(buf, 1, (size_t)nchars, curl_dbg_logfile); + (fwrite)(buf, 1, (size_t)nchars, curl_dbg_logfile); } #endif /* CURLDEBUG */ diff --git a/vendor/curl/lib/memdebug.h b/vendor/curl/lib/memdebug.h index 11b250dea23..d8d5f807d7f 100644 --- a/vendor/curl/lib/memdebug.h +++ b/vendor/curl/lib/memdebug.h @@ -1,6 +1,5 @@ #ifndef HEADER_CURL_MEMDEBUG_H #define HEADER_CURL_MEMDEBUG_H -#ifdef CURLDEBUG /*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | @@ -30,103 +29,7 @@ * as well as the library. Do not mix with library internals! */ -#include -#include "functypes.h" - -#ifdef __clang__ -# define ALLOC_FUNC __attribute__((__malloc__)) -# if __clang_major__ >= 4 -# define ALLOC_SIZE(s) __attribute__((__alloc_size__(s))) -# define ALLOC_SIZE2(n, s) __attribute__((__alloc_size__(n, s))) -# else -# define ALLOC_SIZE(s) -# define ALLOC_SIZE2(n, s) -# endif -#elif defined(__GNUC__) && __GNUC__ >= 3 -# define ALLOC_FUNC __attribute__((__malloc__)) -# define ALLOC_SIZE(s) __attribute__((__alloc_size__(s))) -# define ALLOC_SIZE2(n, s) __attribute__((__alloc_size__(n, s))) -#elif defined(_MSC_VER) -# define ALLOC_FUNC __declspec(restrict) -# define ALLOC_SIZE(s) -# define ALLOC_SIZE2(n, s) -#else -# define ALLOC_FUNC -# define ALLOC_SIZE(s) -# define ALLOC_SIZE2(n, s) -#endif - -#define CURL_MT_LOGFNAME_BUFSIZE 512 - -/* Avoid redundant redeclaration warnings with modern compilers, when including - this header multiple times. */ -#ifndef HEADER_CURL_MEMDEBUG_H_EXTERNS -#define HEADER_CURL_MEMDEBUG_H_EXTERNS -extern FILE *curl_dbg_logfile; - -/* memory functions */ -CURL_EXTERN void curl_dbg_free(void *ptr, int line, const char *source); -CURL_EXTERN ALLOC_FUNC ALLOC_SIZE(1) - void *curl_dbg_malloc(size_t size, int line, const char *source); -CURL_EXTERN ALLOC_FUNC ALLOC_SIZE2(1, 2) - void *curl_dbg_calloc(size_t n, size_t size, int line, const char *source); -CURL_EXTERN ALLOC_SIZE(2) - void *curl_dbg_realloc(void *ptr, size_t size, int line, const char *source); -CURL_EXTERN ALLOC_FUNC - char *curl_dbg_strdup(const char *str, int line, const char *src); -#if defined(_WIN32) && defined(UNICODE) -CURL_EXTERN ALLOC_FUNC - wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, const char *source); -#endif - -CURL_EXTERN void curl_dbg_memdebug(const char *logname); -CURL_EXTERN void curl_dbg_memlimit(long limit); -CURL_EXTERN void curl_dbg_log(const char *format, ...) CURL_PRINTF(1, 2); - -/* file descriptor manipulators */ -CURL_EXTERN curl_socket_t curl_dbg_socket(int domain, int type, int protocol, - int line, const char *source); -CURL_EXTERN void curl_dbg_mark_sclose(curl_socket_t sockfd, - int line, const char *source); -CURL_EXTERN int curl_dbg_sclose(curl_socket_t sockfd, - int line, const char *source); -CURL_EXTERN curl_socket_t curl_dbg_accept(curl_socket_t s, void *a, void *alen, - int line, const char *source); -#ifdef HAVE_ACCEPT4 -CURL_EXTERN curl_socket_t curl_dbg_accept4(curl_socket_t s, void *saddr, - void *saddrlen, int flags, - int line, const char *source); -#endif -#ifdef HAVE_SOCKETPAIR -CURL_EXTERN int curl_dbg_socketpair(int domain, int type, int protocol, - curl_socket_t socket_vector[2], - int line, const char *source); -#endif - -/* send/receive sockets */ -CURL_EXTERN SEND_TYPE_RETV curl_dbg_send(SEND_TYPE_ARG1 sockfd, - SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf, - SEND_TYPE_ARG3 len, - SEND_TYPE_ARG4 flags, int line, - const char *source); -CURL_EXTERN RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd, - RECV_TYPE_ARG2 buf, - RECV_TYPE_ARG3 len, - RECV_TYPE_ARG4 flags, int line, - const char *source); - -/* FILE functions */ -CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source); -CURL_EXTERN ALLOC_FUNC - FILE *curl_dbg_fopen(const char *file, const char *mode, - int line, const char *source); -CURL_EXTERN ALLOC_FUNC - FILE *curl_dbg_fdopen(int filedes, const char *mode, - int line, const char *source); - -#endif /* HEADER_CURL_MEMDEBUG_H_EXTERNS */ - -#ifndef MEMDEBUG_NODEFINES +#ifdef CURLDEBUG /* Set this symbol on the command-line, recompile all lib-sources */ #undef strdup @@ -145,67 +48,37 @@ CURL_EXTERN ALLOC_FUNC #define recv(a,b,c,d) curl_dbg_recv(a,b,c,d, __LINE__, __FILE__) #ifdef _WIN32 -# ifdef UNICODE -# undef wcsdup -# define wcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__) -# undef _wcsdup -# define _wcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__) -# undef _tcsdup -# define _tcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__) -# else -# undef _tcsdup -# define _tcsdup(ptr) curl_dbg_strdup(ptr, __LINE__, __FILE__) -# endif +#undef _tcsdup +#ifdef UNICODE +#define _tcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__) +#else +#define _tcsdup(ptr) curl_dbg_strdup(ptr, __LINE__, __FILE__) #endif +#endif /* _WIN32 */ #undef socket -#define socket(domain,type,protocol)\ - curl_dbg_socket((int)domain, type, protocol, __LINE__, __FILE__) +#define socket(domain,type,protocol) \ + curl_dbg_socket((int)domain, type, protocol, __LINE__, __FILE__) #undef accept /* for those with accept as a macro */ -#define accept(sock,addr,len)\ - curl_dbg_accept(sock, addr, len, __LINE__, __FILE__) +#define accept(sock,addr,len) \ + curl_dbg_accept(sock, addr, len, __LINE__, __FILE__) #ifdef HAVE_ACCEPT4 #undef accept4 /* for those with accept4 as a macro */ -#define accept4(sock,addr,len,flags)\ - curl_dbg_accept4(sock, addr, len, flags, __LINE__, __FILE__) +#define accept4(sock,addr,len,flags) \ + curl_dbg_accept4(sock, addr, len, flags, __LINE__, __FILE__) #endif #ifdef HAVE_SOCKETPAIR -#define socketpair(domain,type,protocol,socket_vector)\ - curl_dbg_socketpair((int)domain, type, protocol, socket_vector, \ - __LINE__, __FILE__) +#define socketpair(domain,type,protocol,socket_vector) \ + curl_dbg_socketpair((int)domain, type, protocol, socket_vector, \ + __LINE__, __FILE__) #endif -/* sclose is probably already defined, redefine it! */ -#undef sclose -#define sclose(sockfd) curl_dbg_sclose(sockfd,__LINE__,__FILE__) - -#define fake_sclose(sockfd) curl_dbg_mark_sclose(sockfd,__LINE__,__FILE__) - #undef fopen #define fopen(file,mode) curl_dbg_fopen(file,mode,__LINE__,__FILE__) #undef fdopen #define fdopen(file,mode) curl_dbg_fdopen(file,mode,__LINE__,__FILE__) +#undef fclose #define fclose(file) curl_dbg_fclose(file,__LINE__,__FILE__) -#endif /* MEMDEBUG_NODEFINES */ - #endif /* CURLDEBUG */ - -/* -** Following section applies even when CURLDEBUG is not defined. -*/ - -#ifndef fake_sclose -#define fake_sclose(x) Curl_nop_stmt -#endif - -/* - * Curl_safefree defined as a macro to allow MemoryTracking feature - * to log free() calls at same location where Curl_safefree is used. - * This macro also assigns NULL to given pointer when free'd. - */ - -#define Curl_safefree(ptr) \ - do { free((ptr)); (ptr) = NULL;} while(0) - #endif /* HEADER_CURL_MEMDEBUG_H */ diff --git a/vendor/curl/lib/mime.c b/vendor/curl/lib/mime.c index c90c34898d5..3d4eef767fc 100644 --- a/vendor/curl/lib/mime.c +++ b/vendor/curl/lib/mime.c @@ -32,12 +32,14 @@ struct Curl_easy; #include "curlx/warnless.h" #include "urldata.h" #include "sendf.h" +#include "transfer.h" #include "strdup.h" #include "curlx/base64.h" -#if !defined(CURL_DISABLE_MIME) && (!defined(CURL_DISABLE_HTTP) || \ - !defined(CURL_DISABLE_SMTP) || \ - !defined(CURL_DISABLE_IMAP)) +#if !defined(CURL_DISABLE_MIME) && \ + (!defined(CURL_DISABLE_HTTP) || \ + !defined(CURL_DISABLE_SMTP) || \ + !defined(CURL_DISABLE_IMAP)) #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME) #include @@ -45,7 +47,6 @@ struct Curl_easy; #include "rand.h" #include "slist.h" -#include "strcase.h" #include "curlx/dynbuf.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -53,26 +54,25 @@ struct Curl_easy; #include "memdebug.h" #ifdef _WIN32 -# ifndef R_OK +# ifndef R_OK # define R_OK 4 -# endif +# endif #endif - -#define READ_ERROR ((size_t) -1) -#define STOP_FILLING ((size_t) -2) +#define READ_ERROR ((size_t) -1) +#define STOP_FILLING ((size_t) -2) static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems, void *instream, bool *hasread); /* Encoders. */ static size_t encoder_nop_read(char *buffer, size_t size, bool ateof, - curl_mimepart *part); + curl_mimepart *part); static curl_off_t encoder_nop_size(curl_mimepart *part); static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof, curl_mimepart *part); static size_t encoder_base64_read(char *buffer, size_t size, bool ateof, - curl_mimepart *part); + curl_mimepart *part); static curl_off_t encoder_base64_size(curl_mimepart *part); static size_t encoder_qp_read(char *buffer, size_t size, bool ateof, curl_mimepart *part); @@ -97,30 +97,30 @@ static const struct mime_encoder encoders[] = { #define QP_CR 3 /* Carriage return. */ #define QP_LF 4 /* Line-feed. */ static const unsigned char qp_class[] = { - 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 07 */ - 0, QP_SP, QP_LF, 0, 0, QP_CR, 0, 0, /* 08 - 0F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 17 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* 18 - 1F */ - QP_SP, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 20 - 27 */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 28 - 2F */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 30 - 37 */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, 0 , QP_OK, QP_OK, /* 38 - 3F */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 40 - 47 */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 48 - 4F */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 50 - 57 */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 58 - 5F */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 60 - 67 */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 68 - 6F */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 70 - 77 */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, 0, /* 78 - 7F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0 - FF */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 07 */ + 0, QP_SP, QP_LF, 0, 0, QP_CR, 0, 0, /* 08 - 0F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 17 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 18 - 1F */ + QP_SP, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 20 - 27 */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 28 - 2F */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 30 - 37 */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, 0 , QP_OK, QP_OK, /* 38 - 3F */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 40 - 47 */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 48 - 4F */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 50 - 57 */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 58 - 5F */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 60 - 67 */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 68 - 6F */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 70 - 77 */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, 0, /* 78 - 7F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0 - FF */ }; @@ -335,7 +335,7 @@ static char *match_header(struct curl_slist *hdr, const char *lbl, size_t len) { char *value = NULL; - if(strncasecompare(hdr->data, lbl, len) && hdr->data[len] == ':') + if(curl_strnequal(hdr->data, lbl, len) && hdr->data[len] == ':') for(value = hdr->data + len + 1; *value == ' '; value++) ; return value; @@ -384,7 +384,7 @@ static size_t encoder_nop_read(char *buffer, size_t size, bool ateof, struct mime_encoder_state *st = &part->encstate; size_t insize = st->bufend - st->bufbeg; - (void) ateof; + (void)ateof; if(!size) return STOP_FILLING; @@ -412,7 +412,7 @@ static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof, struct mime_encoder_state *st = &part->encstate; size_t cursize = st->bufend - st->bufbeg; - (void) ateof; + (void)ateof; if(!size) return STOP_FILLING; @@ -433,7 +433,7 @@ static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof, /* Base64 content encoder. */ static size_t encoder_base64_read(char *buffer, size_t size, bool ateof, - curl_mimepart *part) + curl_mimepart *part) { struct mime_encoder_state *st = &part->encstate; size_t cursize = 0; @@ -661,7 +661,7 @@ static size_t mime_mem_read(char *buffer, size_t size, size_t nitems, { curl_mimepart *part = (curl_mimepart *) instream; size_t sz = curlx_sotouz(part->datasize - part->state.offset); - (void) size; /* Always 1.*/ + (void)size; /* Always 1.*/ if(!nitems) return STOP_FILLING; @@ -1000,7 +1000,7 @@ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems, { curl_mime *mime = (curl_mime *) instream; size_t cursize = 0; - (void) size; /* Always 1. */ + (void)size; /* Always 1. */ while(nitems) { size_t sz = 0; @@ -1478,7 +1478,7 @@ CURLcode curl_mime_encoder(curl_mimepart *part, const char *encoding) return CURLE_OK; /* Removing current encoder. */ for(mep = encoders; mep->name; mep++) - if(strcasecompare(encoding, mep->name)) { + if(curl_strequal(encoding, mep->name)) { part->encoder = mep; result = CURLE_OK; } @@ -1593,7 +1593,7 @@ size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream) size_t ret; bool hasread; - (void) size; /* Always 1. */ + (void)size; /* Always 1. */ /* If `nitems` is <= 4, some encoders will return STOP_FILLING without * adding any data and this loops infinitely. */ @@ -1742,7 +1742,7 @@ const char *Curl_mime_contenttype(const char *filename) for(i = 0; i < CURL_ARRAYSIZE(ctts); i++) { size_t len2 = strlen(ctts[i].extension); - if(len1 >= len2 && strcasecompare(nameend - len2, ctts[i].extension)) + if(len1 >= len2 && curl_strequal(nameend - len2, ctts[i].extension)) return ctts[i].type; } } @@ -1752,7 +1752,7 @@ const char *Curl_mime_contenttype(const char *filename) static bool content_type_match(const char *contenttype, const char *target, size_t len) { - if(contenttype && strncasecompare(contenttype, target, len)) + if(contenttype && curl_strnequal(contenttype, target, len)) switch(contenttype[len]) { case '\0': case '\t': @@ -1825,7 +1825,7 @@ CURLcode Curl_mime_prepare_headers(struct Curl_easy *data, if(!search_header(part->userheaders, STRCONST("Content-Disposition"))) { if(!disposition) if(part->filename || part->name || - (contenttype && !strncasecompare(contenttype, "multipart/", 10))) + (contenttype && !curl_strnequal(contenttype, "multipart/", 10))) disposition = DISPOSITION_DEFAULT; if(disposition && curl_strequal(disposition, "attachment") && !part->name && !part->filename) @@ -1962,6 +1962,7 @@ static CURLcode cr_mime_read(struct Curl_easy *data, size_t *pnread, bool *peos) { struct cr_mime_ctx *ctx = reader->ctx; + CURLcode result = CURLE_OK; size_t nread; char tmp[256]; @@ -1990,15 +1991,12 @@ static CURLcode cr_mime_read(struct Curl_easy *data, } if(!Curl_bufq_is_empty(&ctx->tmpbuf)) { - CURLcode result = CURLE_OK; - ssize_t n = Curl_bufq_read(&ctx->tmpbuf, (unsigned char *)buf, blen, - &result); - if(n < 0) { + result = Curl_bufq_read(&ctx->tmpbuf, (unsigned char *)buf, blen, &nread); + if(result) { ctx->errored = TRUE; ctx->error_result = result; return result; } - nread = (size_t)n; } else if(blen <= 4) { /* Curl_mime_read() may go into an infinite loop when reading @@ -2008,22 +2006,20 @@ static CURLcode cr_mime_read(struct Curl_easy *data, CURL_TRC_READ(data, "cr_mime_read(len=%zu), small read, using tmp", blen); nread = Curl_mime_read(tmp, 1, sizeof(tmp), ctx->part); if(nread <= sizeof(tmp)) { - CURLcode result = CURLE_OK; - ssize_t n = Curl_bufq_write(&ctx->tmpbuf, (unsigned char *)tmp, nread, - &result); - if(n < 0) { + size_t n; + result = Curl_bufq_write(&ctx->tmpbuf, (unsigned char *)tmp, nread, &n); + if(result) { ctx->errored = TRUE; ctx->error_result = result; return result; } /* stored it, read again */ - n = Curl_bufq_read(&ctx->tmpbuf, (unsigned char *)buf, blen, &result); - if(n < 0) { + result = Curl_bufq_cread(&ctx->tmpbuf, buf, blen, &nread); + if(result) { ctx->errored = TRUE; ctx->error_result = result; return result; } - nread = (size_t)n; } } else @@ -2051,14 +2047,15 @@ static CURLcode cr_mime_read(struct Curl_easy *data, *peos = FALSE; ctx->errored = TRUE; ctx->error_result = CURLE_ABORTED_BY_CALLBACK; - return CURLE_ABORTED_BY_CALLBACK; + result = CURLE_ABORTED_BY_CALLBACK; + break; case CURL_READFUNC_PAUSE: /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */ CURL_TRC_READ(data, "cr_mime_read(len=%zu), paused by callback", blen); - data->req.keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */ *pnread = 0; *peos = FALSE; + result = Curl_xfer_pause_send(data, TRUE); break; /* nothing was read */ case STOP_FILLING: @@ -2068,7 +2065,8 @@ static CURLcode cr_mime_read(struct Curl_easy *data, *peos = FALSE; ctx->errored = TRUE; ctx->error_result = CURLE_READ_ERROR; - return CURLE_READ_ERROR; + result = CURLE_READ_ERROR; + break; default: if(nread > blen) { @@ -2090,8 +2088,8 @@ static CURLcode cr_mime_read(struct Curl_easy *data, CURL_TRC_READ(data, "cr_mime_read(len=%zu, total=%" FMT_OFF_T ", read=%"FMT_OFF_T") -> %d, %zu, %d", - blen, ctx->total_len, ctx->read_len, CURLE_OK, *pnread, *peos); - return CURLE_OK; + blen, ctx->total_len, ctx->read_len, result, *pnread, *peos); + return result; } static bool cr_mime_needs_rewind(struct Curl_easy *data, @@ -2222,62 +2220,62 @@ CURLcode Curl_creader_set_mime(struct Curl_easy *data, curl_mimepart *part) /* Mime not compiled in: define stubs for externally-referenced functions. */ curl_mime *curl_mime_init(CURL *easy) { - (void) easy; + (void)easy; return NULL; } void curl_mime_free(curl_mime *mime) { - (void) mime; + (void)mime; } curl_mimepart *curl_mime_addpart(curl_mime *mime) { - (void) mime; + (void)mime; return NULL; } CURLcode curl_mime_name(curl_mimepart *part, const char *name) { - (void) part; - (void) name; + (void)part; + (void)name; return CURLE_NOT_BUILT_IN; } CURLcode curl_mime_filename(curl_mimepart *part, const char *filename) { - (void) part; - (void) filename; + (void)part; + (void)filename; return CURLE_NOT_BUILT_IN; } CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype) { - (void) part; - (void) mimetype; + (void)part; + (void)mimetype; return CURLE_NOT_BUILT_IN; } CURLcode curl_mime_encoder(curl_mimepart *part, const char *encoding) { - (void) part; - (void) encoding; + (void)part; + (void)encoding; return CURLE_NOT_BUILT_IN; } CURLcode curl_mime_data(curl_mimepart *part, const char *data, size_t datasize) { - (void) part; - (void) data; - (void) datasize; + (void)part; + (void)data; + (void)datasize; return CURLE_NOT_BUILT_IN; } CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename) { - (void) part; - (void) filename; + (void)part; + (void)filename; return CURLE_NOT_BUILT_IN; } @@ -2288,28 +2286,28 @@ CURLcode curl_mime_data_cb(curl_mimepart *part, curl_free_callback freefunc, void *arg) { - (void) part; - (void) datasize; - (void) readfunc; - (void) seekfunc; - (void) freefunc; - (void) arg; + (void)part; + (void)datasize; + (void)readfunc; + (void)seekfunc; + (void)freefunc; + (void)arg; return CURLE_NOT_BUILT_IN; } CURLcode curl_mime_subparts(curl_mimepart *part, curl_mime *subparts) { - (void) part; - (void) subparts; + (void)part; + (void)subparts; return CURLE_NOT_BUILT_IN; } CURLcode curl_mime_headers(curl_mimepart *part, struct curl_slist *headers, int take_ownership) { - (void) part; - (void) headers; - (void) take_ownership; + (void)part; + (void)headers; + (void)take_ownership; return CURLE_NOT_BUILT_IN; } diff --git a/vendor/curl/lib/mqtt.c b/vendor/curl/lib/mqtt.c index 77e73346131..35afe012075 100644 --- a/vendor/curl/lib/mqtt.c +++ b/vendor/curl/lib/mqtt.c @@ -107,8 +107,8 @@ static CURLcode mqtt_do(struct Curl_easy *data, bool *done); static CURLcode mqtt_done(struct Curl_easy *data, CURLcode status, bool premature); static CURLcode mqtt_doing(struct Curl_easy *data, bool *done); -static int mqtt_getsock(struct Curl_easy *data, struct connectdata *conn, - curl_socket_t *sock); +static CURLcode mqtt_pollset(struct Curl_easy *data, + struct easy_pollset *ps); static CURLcode mqtt_setup_conn(struct Curl_easy *data, struct connectdata *conn); @@ -125,10 +125,10 @@ const struct Curl_handler Curl_handler_mqtt = { ZERO_NULL, /* connect_it */ ZERO_NULL, /* connecting */ mqtt_doing, /* doing */ - ZERO_NULL, /* proto_getsock */ - mqtt_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* proto_pollset */ + mqtt_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ ZERO_NULL, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -213,13 +213,10 @@ static CURLcode mqtt_send(struct Curl_easy *data, /* Generic function called by the multi interface to figure out what socket(s) to wait for and for what actions during the DOING and PROTOCONNECT states */ -static int mqtt_getsock(struct Curl_easy *data, - struct connectdata *conn, - curl_socket_t *sock) +static CURLcode mqtt_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { - (void)data; - sock[0] = conn->sock[FIRSTSOCKET]; - return GETSOCK_READSOCK(FIRSTSOCKET); + return Curl_pollset_add_in(data, ps, data->conn->sock[FIRSTSOCKET]); } static int mqtt_encode_len(char *buf, size_t len) @@ -240,7 +237,7 @@ static int mqtt_encode_len(char *buf, size_t len) /* add the passwd to the CONNECT packet */ static int add_passwd(const char *passwd, const size_t plen, - char *pkt, const size_t start, int remain_pos) + char *pkt, const size_t start, int remain_pos) { /* magic number that need to be set properly */ const size_t conn_flags_pos = remain_pos + 8; @@ -428,14 +425,13 @@ static CURLcode mqtt_recv_atleast(struct Curl_easy *data, size_t nbytes) if(rlen < nbytes) { unsigned char readbuf[1024]; - ssize_t nread; + size_t nread; DEBUGASSERT(nbytes - rlen < sizeof(readbuf)); result = Curl_xfer_recv(data, (char *)readbuf, nbytes - rlen, &nread); if(result) return result; - DEBUGASSERT(nread >= 0); - if(curlx_dyn_addn(&mq->recvbuf, readbuf, (size_t)nread)) + if(curlx_dyn_addn(&mq->recvbuf, readbuf, nread)) return CURLE_OUT_OF_MEMORY; rlen = curlx_dyn_len(&mq->recvbuf); } @@ -703,7 +699,7 @@ static CURLcode mqtt_read_publish(struct Curl_easy *data, bool *done) { CURLcode result = CURLE_OK; struct connectdata *conn = data->conn; - ssize_t nread; + size_t nread; size_t remlen; struct mqtt_conn *mqtt = Curl_conn_meta_get(conn, CURL_META_MQTT_CONN); struct MQTT *mq = Curl_meta_get(data, CURL_META_MQTT_EASY); @@ -868,7 +864,7 @@ static CURLcode mqtt_doing(struct Curl_easy *data, bool *done) { struct MQTT *mq = Curl_meta_get(data, CURL_META_MQTT_EASY); CURLcode result = CURLE_OK; - ssize_t nread; + size_t nread; unsigned char recvbyte; struct mqtt_conn *mqtt = Curl_conn_meta_get(data->conn, CURL_META_MQTT_CONN); diff --git a/vendor/curl/lib/multi.c b/vendor/curl/lib/multi.c index 64eb1ae8540..d38155cd9b3 100644 --- a/vendor/curl/lib/multi.c +++ b/vendor/curl/lib/multi.c @@ -42,6 +42,7 @@ #include "http.h" #include "select.h" #include "curlx/warnless.h" +#include "curlx/wait.h" #include "speedcheck.h" #include "conncache.h" #include "multihandle.h" @@ -234,6 +235,7 @@ struct Curl_multi *Curl_multi_handle(unsigned int xfer_table_size, Curl_multi_ev_init(multi, ev_hashsize); Curl_uint_tbl_init(&multi->xfers, NULL); Curl_uint_bset_init(&multi->process); + Curl_uint_bset_init(&multi->dirty); Curl_uint_bset_init(&multi->pending); Curl_uint_bset_init(&multi->msgsent); Curl_hash_init(&multi->proto_hash, 23, @@ -246,6 +248,7 @@ struct Curl_multi *Curl_multi_handle(unsigned int xfer_table_size, if(Curl_uint_bset_resize(&multi->process, xfer_table_size) || Curl_uint_bset_resize(&multi->pending, xfer_table_size) || + Curl_uint_bset_resize(&multi->dirty, xfer_table_size) || Curl_uint_bset_resize(&multi->msgsent, xfer_table_size) || Curl_uint_tbl_resize(&multi->xfers, xfer_table_size)) goto error; @@ -268,20 +271,22 @@ struct Curl_multi *Curl_multi_handle(unsigned int xfer_table_size, Curl_cpool_init(&multi->cpool, multi->admin, NULL, chashsize); +#ifdef USE_SSL if(Curl_ssl_scache_create(sesssize, 2, &multi->ssl_scache)) goto error; +#else + (void)sesssize; +#endif #ifdef USE_WINSOCK multi->wsa_event = WSACreateEvent(); if(multi->wsa_event == WSA_INVALID_EVENT) goto error; -#else -#ifdef ENABLE_WAKEUP +#elif defined(ENABLE_WAKEUP) if(wakeup_create(multi->wakeup_pair, TRUE) < 0) { multi->wakeup_pair[0] = CURL_SOCKET_BAD; multi->wakeup_pair[1] = CURL_SOCKET_BAD; } -#endif #endif return multi; @@ -293,13 +298,16 @@ struct Curl_multi *Curl_multi_handle(unsigned int xfer_table_size, Curl_dnscache_destroy(&multi->dnscache); Curl_cpool_destroy(&multi->cpool); Curl_cshutdn_destroy(&multi->cshutdn, multi->admin); +#ifdef USE_SSL Curl_ssl_scache_destroy(multi->ssl_scache); +#endif if(multi->admin) { multi->admin->multi = NULL; Curl_close(&multi->admin); } Curl_uint_bset_destroy(&multi->process); + Curl_uint_bset_destroy(&multi->dirty); Curl_uint_bset_destroy(&multi->pending); Curl_uint_bset_destroy(&multi->msgsent); Curl_uint_tbl_destroy(&multi->xfers); @@ -335,34 +343,57 @@ static void multi_warn_debug(struct Curl_multi *multi, struct Curl_easy *data) static CURLMcode multi_xfers_add(struct Curl_multi *multi, struct Curl_easy *data) { - /* We want `multi->xfers` to have "sufficient" free rows, so that we do - * have to reuse the `mid` from a just removed easy right away. - * Since uint_tbl and uint_bset is quite memory efficient, - * regard less than 25% free as insufficient. - * (for low capacities, e.g. multi_easy, 4 or less). */ unsigned int capacity = Curl_uint_tbl_capacity(&multi->xfers); - unsigned int unused = capacity - Curl_uint_tbl_count(&multi->xfers); - unsigned int min_unused = CURLMAX(capacity >> 2, 4); - - if(unused <= min_unused) { - /* make it a 64 multiple, since our bitsets frow by that and - * small (easy_multi) grows to at least 64 on first resize. */ - unsigned int newsize = (((capacity + min_unused) + 63) / 64) * 64; - DEBUGASSERT(newsize > capacity); + unsigned int new_size = 0; + /* Prepare to make this into a CURLMOPT_MAX_TRANSFERS, because some + * applications may want to prevent a run-away of their memory use. */ + /* UINT_MAX is our "invalid" id, do not let the table grow up to that. */ + const unsigned int max_capacity = UINT_MAX - 1; + + if(capacity < max_capacity) { + /* We want `multi->xfers` to have "sufficient" free rows, so that we do + * have to reuse the `mid` from a just removed easy right away. + * Since uint_tbl and uint_bset are quite memory efficient, + * regard less than 25% free as insufficient. + * (for low capacities, e.g. multi_easy, 4 or less). */ + unsigned int used = Curl_uint_tbl_count(&multi->xfers); + unsigned int unused = capacity - used; + unsigned int min_unused = CURLMAX(capacity >> 2, 4); + if(unused <= min_unused) { + /* Make sure the uint arithmetic here works on the corner + * cases where we are close to max_capacity or UINT_MAX */ + if((min_unused >= max_capacity) || + ((max_capacity - min_unused) <= capacity) || + ((UINT_MAX - min_unused - 63) <= capacity)) { + new_size = max_capacity; /* can not be larger than this */ + } + else { + /* make it a 64 multiple, since our bitsets frow by that and + * small (easy_multi) grows to at least 64 on first resize. */ + new_size = (((used + min_unused) + 63) / 64) * 64; + } + } + } + + if(new_size > capacity) { /* Grow the bitsets first. Should one fail, we do not need * to downsize the already resized ones. The sets continue * to work properly when larger than the table, but not * the other way around. */ - if(Curl_uint_bset_resize(&multi->process, newsize) || - Curl_uint_bset_resize(&multi->pending, newsize) || - Curl_uint_bset_resize(&multi->msgsent, newsize) || - Curl_uint_tbl_resize(&multi->xfers, newsize)) + CURL_TRC_M(data, "increasing xfer table size to %u", new_size); + if(Curl_uint_bset_resize(&multi->process, new_size) || + Curl_uint_bset_resize(&multi->dirty, new_size) || + Curl_uint_bset_resize(&multi->pending, new_size) || + Curl_uint_bset_resize(&multi->msgsent, new_size) || + Curl_uint_tbl_resize(&multi->xfers, new_size)) return CURLM_OUT_OF_MEMORY; - CURL_TRC_M(data, "increased xfer table size to %u", newsize); } - /* Insert the easy into the table now that MUST have room for it */ + + /* Insert the easy into the table now */ if(!Curl_uint_tbl_add(&multi->xfers, data, &data->mid)) { - DEBUGASSERT(0); + /* MUST only happen when table is full */ + DEBUGASSERT(Curl_uint_tbl_capacity(&multi->xfers) <= + Curl_uint_tbl_count(&multi->xfers)); return CURLM_OUT_OF_MEMORY; } return CURLM_OK; @@ -400,6 +431,7 @@ CURLMcode curl_multi_add_handle(CURLM *m, CURL *d) return CURLM_ABORTED_BY_CALLBACK; multi->dead = FALSE; Curl_uint_bset_clear(&multi->process); + Curl_uint_bset_clear(&multi->dirty); Curl_uint_bset_clear(&multi->pending); Curl_uint_bset_clear(&multi->msgsent); } @@ -433,22 +465,6 @@ CURLMcode curl_multi_add_handle(CURLM *m, CURL *d) is called. */ data->multi = multi; - /* Set the timeout for this handle to expire really soon so that it will - be taken care of even when this handle is added in the midst of operation - when only the curl_multi_socket() API is used. During that flow, only - sockets that time-out or have actions will be dealt with. Since this - handle has no action yet, we make sure it times out to get things to - happen. */ - Curl_expire(data, 0, EXPIRE_RUN_NOW); - - rc = Curl_update_timer(multi); - if(rc) { - data->multi = NULL; /* not anymore */ - Curl_uint_tbl_remove(&multi->xfers, data->mid); - data->mid = UINT_MAX; - return rc; - } - /* set the easy handle */ multistate(data, MSTATE_INIT); @@ -463,10 +479,23 @@ CURLMcode curl_multi_add_handle(CURLM *m, CURL *d) /* add the easy handle to the process set */ Curl_uint_bset_add(&multi->process, data->mid); ++multi->xfers_alive; + ++multi->xfers_total_ever; Curl_cpool_xfer_init(data); multi_warn_debug(multi, data); + /* Make sure the new handle will run */ + Curl_multi_mark_dirty(data); + /* Necessary in event based processing, where dirty handles trigger + * a timeout callback invocation. */ + rc = Curl_update_timer(multi); + if(rc) { + data->multi = NULL; /* not anymore */ + Curl_uint_tbl_remove(&multi->xfers, data->mid); + data->mid = UINT_MAX; + return rc; + } + /* The admin handle only ever has default timeouts set. To improve the state somewhat we clone the timeouts from each added handle so that the admin handle always has the same timeouts as the most recently added @@ -507,6 +536,22 @@ static void multi_done_locked(struct connectdata *conn, void *userdata) { struct multi_done_ctx *mdctx = userdata; +#ifndef CURL_DISABLE_VERBOSE_STRINGS + const char *host = +#ifndef CURL_DISABLE_PROXY + conn->bits.socksproxy ? + conn->socks_proxy.host.dispname : + conn->bits.httpproxy ? conn->http_proxy.host.dispname : +#endif + conn->bits.conn_to_host ? conn->conn_to_host.dispname : + conn->host.dispname; + int port = +#ifndef CURL_DISABLE_PROXY + conn->bits.httpproxy ? conn->http_proxy.port : +#endif + conn->bits.conn_to_port ? conn->conn_to_port : + conn->remote_port; +#endif Curl_detach_connection(data); @@ -542,40 +587,43 @@ static void multi_done_locked(struct connectdata *conn, */ if((data->set.reuse_forbid -#if defined(USE_NTLM) +#ifdef USE_NTLM && !(conn->http_ntlm_state == NTLMSTATE_TYPE2 || conn->proxy_ntlm_state == NTLMSTATE_TYPE2) #endif -#if defined(USE_SPNEGO) +#ifdef USE_SPNEGO && !(conn->http_negotiate_state == GSS_AUTHRECV || conn->proxy_negotiate_state == GSS_AUTHRECV) #endif ) || conn->bits.close || (mdctx->premature && !Curl_conn_is_multiplex(conn, FIRSTSOCKET))) { - CURL_TRC_M(data, "multi_done, not reusing connection=%" - FMT_OFF_T ", forbid=%d" - ", close=%d, premature=%d, conn_multiplex=%d", - conn->connection_id, data->set.reuse_forbid, - conn->bits.close, mdctx->premature, - Curl_conn_is_multiplex(conn, FIRSTSOCKET)); +#ifndef CURL_DISABLE_VERBOSE_STRINGS + CURL_TRC_M(data, "multi_done, terminating conn #%" FMT_OFF_T " to %s:%d, " + "forbid=%d, close=%d, premature=%d, conn_multiplex=%d", + conn->connection_id, host, port, data->set.reuse_forbid, + conn->bits.close, mdctx->premature, + Curl_conn_is_multiplex(conn, FIRSTSOCKET)); +#endif connclose(conn, "disconnecting"); Curl_conn_terminate(data, conn, mdctx->premature); } + else if(!Curl_conn_get_max_concurrent(data, conn, FIRSTSOCKET)) { +#ifndef CURL_DISABLE_VERBOSE_STRINGS + CURL_TRC_M(data, "multi_done, conn #%" FMT_OFF_T " to %s:%d was shutdown" + " by server, not reusing", conn->connection_id, host, port); +#endif + connclose(conn, "server shutdown"); + Curl_conn_terminate(data, conn, mdctx->premature); + } else { /* the connection is no longer in use by any transfer */ if(Curl_cpool_conn_now_idle(data, conn)) { /* connection kept in the cpool */ - const char *host = -#ifndef CURL_DISABLE_PROXY - conn->bits.socksproxy ? - conn->socks_proxy.host.dispname : - conn->bits.httpproxy ? conn->http_proxy.host.dispname : -#endif - conn->bits.conn_to_host ? conn->conn_to_host.dispname : - conn->host.dispname; data->state.lastconnect_id = conn->connection_id; - infof(data, "Connection #%" FMT_OFF_T " to host %s left intact", - conn->connection_id, host); +#ifndef CURL_DISABLE_VERBOSE_STRINGS + infof(data, "Connection #%" FMT_OFF_T " to host %s:%d left intact", + conn->connection_id, host, port); +#endif } else { /* connection was removed from the cpool and destroyed. */ @@ -589,7 +637,7 @@ static CURLcode multi_done(struct Curl_easy *data, after an error was detected */ bool premature) { - CURLcode result, r2; + CURLcode result; struct connectdata *conn = data->conn; struct multi_done_ctx mdctx; @@ -638,9 +686,7 @@ static CURLcode multi_done(struct Curl_easy *data, } /* Make sure that transfer client writes are really done now. */ - r2 = Curl_xfer_write_done(data, premature); - if(r2 && !result) - result = r2; + result = Curl_1st_err(result, Curl_xfer_write_done(data, premature)); /* Inform connection filters that this transfer is done */ Curl_conn_ev_data_done(data, premature); @@ -794,6 +840,7 @@ CURLMcode curl_multi_remove_handle(CURLM *m, CURL *d) DEBUGASSERT(Curl_uint_tbl_contains(&multi->xfers, mid)); Curl_uint_tbl_remove(&multi->xfers, mid); Curl_uint_bset_remove(&multi->process, mid); + Curl_uint_bset_remove(&multi->dirty, mid); Curl_uint_bset_remove(&multi->pending, mid); Curl_uint_bset_remove(&multi->msgsent, mid); data->multi = NULL; @@ -861,118 +908,105 @@ void Curl_attach_connection(struct Curl_easy *data, conn->handler->attach(data, conn); } -static int connecting_getsock(struct Curl_easy *data, curl_socket_t *socks) +static CURLcode mstate_connecting_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { - struct connectdata *conn = data->conn; - curl_socket_t sockfd; - - if(!conn) - return GETSOCK_BLANK; - sockfd = Curl_conn_get_socket(data, FIRSTSOCKET); - if(sockfd != CURL_SOCKET_BAD) { - /* Default is to wait to something from the server */ - socks[0] = sockfd; - return GETSOCK_READSOCK(0); + if(data->conn) { + curl_socket_t sockfd = Curl_conn_get_first_socket(data); + if(sockfd != CURL_SOCKET_BAD) { + /* Default is to wait to something from the server */ + return Curl_pollset_change(data, ps, sockfd, CURL_POLL_IN, 0); + } } - return GETSOCK_BLANK; + return CURLE_OK; } -static int protocol_getsock(struct Curl_easy *data, curl_socket_t *socks) +static CURLcode mstate_protocol_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { - struct connectdata *conn = data->conn; - curl_socket_t sockfd; - - if(!conn) - return GETSOCK_BLANK; - if(conn->handler->proto_getsock) - return conn->handler->proto_getsock(data, conn, socks); - sockfd = Curl_conn_get_socket(data, FIRSTSOCKET); - if(sockfd != CURL_SOCKET_BAD) { - /* Default is to wait to something from the server */ - socks[0] = sockfd; - return GETSOCK_READSOCK(0); + if(data->conn) { + curl_socket_t sockfd; + if(data->conn->handler->proto_pollset) + return data->conn->handler->proto_pollset(data, ps); + sockfd = data->conn->sock[FIRSTSOCKET]; + if(sockfd != CURL_SOCKET_BAD) { + /* Default is to wait to something from the server */ + return Curl_pollset_change(data, ps, sockfd, CURL_POLL_IN, 0); + } } - return GETSOCK_BLANK; + return CURLE_OK; } -static int domore_getsock(struct Curl_easy *data, curl_socket_t *socks) +static CURLcode mstate_do_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { - struct connectdata *conn = data->conn; - if(!conn) - return GETSOCK_BLANK; - if(conn->handler->domore_getsock) - return conn->handler->domore_getsock(data, conn, socks); - else if(conn->sockfd != CURL_SOCKET_BAD) { - /* Default is that we want to send something to the server */ - socks[0] = conn->sockfd; - return GETSOCK_WRITESOCK(0); + if(data->conn) { + if(data->conn->handler->doing_pollset) + return data->conn->handler->doing_pollset(data, ps); + else if(CONN_SOCK_IDX_VALID(data->conn->send_idx)) { + /* Default is that we want to send something to the server */ + return Curl_pollset_add_out( + data, ps, data->conn->sock[data->conn->send_idx]); + } } - return GETSOCK_BLANK; + return CURLE_OK; } -static int doing_getsock(struct Curl_easy *data, curl_socket_t *socks) +static CURLcode mstate_domore_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { - struct connectdata *conn = data->conn; - if(!conn) - return GETSOCK_BLANK; - if(conn->handler->doing_getsock) - return conn->handler->doing_getsock(data, conn, socks); - else if(conn->sockfd != CURL_SOCKET_BAD) { - /* Default is that we want to send something to the server */ - socks[0] = conn->sockfd; - return GETSOCK_WRITESOCK(0); + if(data->conn) { + if(data->conn->handler->domore_pollset) + return data->conn->handler->domore_pollset(data, ps); + else if(CONN_SOCK_IDX_VALID(data->conn->send_idx)) { + /* Default is that we want to send something to the server */ + return Curl_pollset_add_out( + data, ps, data->conn->sock[data->conn->send_idx]); + } } - return GETSOCK_BLANK; + return CURLE_OK; } -static int perform_getsock(struct Curl_easy *data, curl_socket_t *sock) +static CURLcode mstate_perform_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { - struct connectdata *conn = data->conn; - if(!conn) - return GETSOCK_BLANK; - else if(conn->handler->perform_getsock) - return conn->handler->perform_getsock(data, conn, sock); + if(!data->conn) + return CURLE_OK; + else if(data->conn->handler->perform_pollset) + return data->conn->handler->perform_pollset(data, ps); else { /* Default is to obey the data->req.keepon flags for send/recv */ - int bitmap = GETSOCK_BLANK; - unsigned sockindex = 0; - if(CURL_WANT_RECV(data)) { - DEBUGASSERT(conn->sockfd != CURL_SOCKET_BAD); - bitmap |= GETSOCK_READSOCK(sockindex); - sock[sockindex] = conn->sockfd; - } - - if(Curl_req_want_send(data)) { - if((conn->sockfd != conn->writesockfd) || - bitmap == GETSOCK_BLANK) { - /* only if they are not the same socket and we have a readable - one, we increase index */ - if(bitmap != GETSOCK_BLANK) - sockindex++; /* increase index if we need two entries */ - - DEBUGASSERT(conn->writesockfd != CURL_SOCKET_BAD); - sock[sockindex] = conn->writesockfd; - } - bitmap |= GETSOCK_WRITESOCK(sockindex); + CURLcode result = CURLE_OK; + if(CURL_WANT_RECV(data) && CONN_SOCK_IDX_VALID(data->conn->recv_idx)) { + result = Curl_pollset_add_in( + data, ps, data->conn->sock[data->conn->recv_idx]); } - return bitmap; + + if(!result && Curl_req_want_send(data) && + CONN_SOCK_IDX_VALID(data->conn->send_idx)) { + result = Curl_pollset_add_out( + data, ps, data->conn->sock[data->conn->send_idx]); + } + return result; } } /* Initializes `poll_set` with the current socket poll actions needed * for transfer `data`. */ -void Curl_multi_getsock(struct Curl_easy *data, - struct easy_pollset *ps, - const char *caller) +CURLMcode Curl_multi_pollset(struct Curl_easy *data, + struct easy_pollset *ps, + const char *caller) { + CURLMcode mresult = CURLM_OK; + CURLcode result = CURLE_OK; bool expect_sockets = TRUE; /* If the transfer has no connection, this is fine. Happens when called via curl_multi_remove_handle() => Curl_multi_ev_assess() => - Curl_multi_getsock(). */ - Curl_pollset_reset(data, ps); + Curl_multi_pollset(). */ + Curl_pollset_reset(ps); if(!data->conn) - return; + return CURLM_OK; switch(data->mstate) { case MSTATE_INIT: @@ -984,7 +1018,7 @@ void Curl_multi_getsock(struct Curl_easy *data, break; case MSTATE_RESOLVING: - Curl_pollset_add_socks(data, ps, Curl_resolv_getsock); + result = Curl_resolv_pollset(data, ps); /* connection filters are not involved in this phase. It's ok if we get no * sockets to wait for. Resolving can wake up from other sources. */ expect_sockets = FALSE; @@ -992,31 +1026,36 @@ void Curl_multi_getsock(struct Curl_easy *data, case MSTATE_CONNECTING: case MSTATE_TUNNELING: - Curl_pollset_add_socks(data, ps, connecting_getsock); - Curl_conn_adjust_pollset(data, data->conn, ps); + result = mstate_connecting_pollset(data, ps); + if(!result) + result = Curl_conn_adjust_pollset(data, data->conn, ps); break; case MSTATE_PROTOCONNECT: case MSTATE_PROTOCONNECTING: - Curl_pollset_add_socks(data, ps, protocol_getsock); - Curl_conn_adjust_pollset(data, data->conn, ps); + result = mstate_protocol_pollset(data, ps); + if(!result) + result = Curl_conn_adjust_pollset(data, data->conn, ps); break; case MSTATE_DO: case MSTATE_DOING: - Curl_pollset_add_socks(data, ps, doing_getsock); - Curl_conn_adjust_pollset(data, data->conn, ps); + result = mstate_do_pollset(data, ps); + if(!result) + result = Curl_conn_adjust_pollset(data, data->conn, ps); break; case MSTATE_DOING_MORE: - Curl_pollset_add_socks(data, ps, domore_getsock); - Curl_conn_adjust_pollset(data, data->conn, ps); + result = mstate_domore_pollset(data, ps); + if(!result) + result = Curl_conn_adjust_pollset(data, data->conn, ps); break; case MSTATE_DID: /* same as PERFORMING in regard to polling */ case MSTATE_PERFORMING: - Curl_pollset_add_socks(data, ps, perform_getsock); - Curl_conn_adjust_pollset(data, data->conn, ps); + result = mstate_perform_pollset(data, ps); + if(!result) + result = Curl_conn_adjust_pollset(data, data->conn, ps); break; case MSTATE_RATELIMITING: @@ -1038,11 +1077,34 @@ void Curl_multi_getsock(struct Curl_easy *data, break; } - switch(ps->num) { + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + mresult = CURLM_OUT_OF_MEMORY; + else { + failf(data, "error determining pollset: %d", result); + mresult = CURLM_INTERNAL_ERROR; + } + goto out; + } + + /* Unblocked and waiting to receive with buffered input. + * Make transfer run again at next opportunity. */ + if(!Curl_xfer_is_blocked(data) && + ((Curl_pollset_want_read(data, ps, data->conn->sock[FIRSTSOCKET]) && + Curl_conn_data_pending(data, FIRSTSOCKET)) || + (Curl_pollset_want_read(data, ps, data->conn->sock[SECONDARYSOCKET]) && + Curl_conn_data_pending(data, SECONDARYSOCKET)))) { + CURL_TRC_M(data, "%s pollset[] has POLLIN, but there is still " + "buffered input to consume -> mark as dirty", caller); + Curl_multi_mark_dirty(data); + } + + switch(ps->n) { case 0: CURL_TRC_M(data, "%s pollset[], timeouts=%zu, paused %d/%d (r/w)", caller, Curl_llist_count(&data->state.timeoutlist), - Curl_creader_is_paused(data), Curl_cwriter_is_paused(data)); + Curl_xfer_send_is_paused(data), + Curl_xfer_recv_is_paused(data)); break; case 1: CURL_TRC_M(data, "%s pollset[fd=%" FMT_SOCKET_T " %s%s], timeouts=%zu", @@ -1064,20 +1126,24 @@ void Curl_multi_getsock(struct Curl_easy *data, break; default: CURL_TRC_M(data, "%s pollset[fds=%u], timeouts=%zu", - caller, ps->num, Curl_llist_count(&data->state.timeoutlist)); + caller, ps->n, Curl_llist_count(&data->state.timeoutlist)); break; } - if(expect_sockets && !ps->num && + if(expect_sockets && !ps->n && data->multi && + !Curl_uint_bset_contains(&data->multi->dirty, data->mid) && !Curl_llist_count(&data->state.timeoutlist) && !Curl_cwriter_is_paused(data) && !Curl_creader_is_paused(data) && Curl_conn_is_ip_connected(data, FIRSTSOCKET)) { /* We expected sockets for POLL monitoring, but none are set. + * We are not dirty (and run anyway). * We are not waiting on any timer. * None of the READ/WRITE directions are paused. * We are connected to the server on IP level, at least. */ infof(data, "WARNING: no socket in pollset or timer, transfer may stall!"); DEBUGASSERT(0); } +out: + return mresult; } CURLMcode curl_multi_fdset(CURLM *m, @@ -1089,6 +1155,7 @@ CURLMcode curl_multi_fdset(CURLM *m, and then we must make sure that is done. */ int this_max_fd = -1; struct Curl_multi *multi = m; + struct easy_pollset ps; unsigned int i, mid; (void)exc_fd_set; /* not used */ @@ -1098,22 +1165,22 @@ CURLMcode curl_multi_fdset(CURLM *m, if(multi->in_callback) return CURLM_RECURSIVE_API_CALL; + Curl_pollset_init(&ps); if(Curl_uint_bset_first(&multi->process, &mid)) { do { struct Curl_easy *data = Curl_multi_get_easy(multi, mid); - struct easy_pollset ps; if(!data) { DEBUGASSERT(0); continue; } - Curl_multi_getsock(data, &ps, "curl_multi_fdset"); - for(i = 0; i < ps.num; i++) { + Curl_multi_pollset(data, &ps, "curl_multi_fdset"); + for(i = 0; i < ps.n; i++) { if(!FDSET_SOCK(ps.sockets[i])) /* pretend it does not exist */ continue; -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif @@ -1121,7 +1188,7 @@ CURLMcode curl_multi_fdset(CURLM *m, FD_SET(ps.sockets[i], read_fd_set); if(ps.actions[i] & CURL_POLL_OUT) FD_SET(ps.sockets[i], write_fd_set); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif if((int)ps.sockets[i] > this_max_fd) @@ -1135,6 +1202,7 @@ CURLMcode curl_multi_fdset(CURLM *m, read_fd_set, write_fd_set, &this_max_fd); *max_fd = this_max_fd; + Curl_pollset_cleanup(&ps); return CURLM_OK; } @@ -1147,6 +1215,7 @@ CURLMcode curl_multi_waitfds(CURLM *m, struct Curl_waitfds cwfds; CURLMcode result = CURLM_OK; struct Curl_multi *multi = m; + struct easy_pollset ps; unsigned int need = 0, mid; if(!ufds && (size || !fd_count)) @@ -1158,17 +1227,18 @@ CURLMcode curl_multi_waitfds(CURLM *m, if(multi->in_callback) return CURLM_RECURSIVE_API_CALL; + Curl_pollset_init(&ps); Curl_waitfds_init(&cwfds, ufds, size); if(Curl_uint_bset_first(&multi->process, &mid)) { do { struct Curl_easy *data = Curl_multi_get_easy(multi, mid); - struct easy_pollset ps; if(!data) { DEBUGASSERT(0); Curl_uint_bset_remove(&multi->process, mid); + Curl_uint_bset_remove(&multi->dirty, mid); continue; } - Curl_multi_getsock(data, &ps, "curl_multi_waitfds"); + Curl_multi_pollset(data, &ps, "curl_multi_waitfds"); need += Curl_waitfds_add_ps(&cwfds, &ps); } while(Curl_uint_bset_next(&multi->process, mid, &mid)); @@ -1182,6 +1252,7 @@ CURLMcode curl_multi_waitfds(CURLM *m, if(fd_count) *fd_count = need; + Curl_pollset_cleanup(&ps); return result; } @@ -1215,9 +1286,11 @@ static CURLMcode multi_wait(struct Curl_multi *multi, struct curltime expire_time; long timeout_internal; int retcode = 0; + struct easy_pollset ps; struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK]; struct curl_pollfds cpfds; unsigned int curl_nfds = 0; /* how many pfds are for curl transfers */ + struct Curl_easy *data = NULL; CURLMcode result = CURLM_OK; unsigned int mid; @@ -1238,19 +1311,20 @@ static CURLMcode multi_wait(struct Curl_multi *multi, if(timeout_ms < 0) return CURLM_BAD_FUNCTION_ARGUMENT; + Curl_pollset_init(&ps); Curl_pollfds_init(&cpfds, a_few_on_stack, NUM_POLLS_ON_STACK); /* Add the curl handles to our pollfds first */ if(Curl_uint_bset_first(&multi->process, &mid)) { do { - struct Curl_easy *data = Curl_multi_get_easy(multi, mid); - struct easy_pollset ps; + data = Curl_multi_get_easy(multi, mid); if(!data) { DEBUGASSERT(0); Curl_uint_bset_remove(&multi->process, mid); + Curl_uint_bset_remove(&multi->dirty, mid); continue; } - Curl_multi_getsock(data, &ps, "multi_wait"); + Curl_multi_pollset(data, &ps, "multi_wait"); if(Curl_pollfds_add_ps(&cpfds, &ps)) { result = CURLM_OUT_OF_MEMORY; goto out; @@ -1320,6 +1394,9 @@ static CURLMcode multi_wait(struct Curl_multi *multi, if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms)) timeout_ms = (int)timeout_internal; + if(data) + CURL_TRC_M(data, "multi_wait(fds=%d, timeout=%d) tinternal=%ld", + cpfds.n, timeout_ms, timeout_internal); #if defined(ENABLE_WAKEUP) && defined(USE_WINSOCK) if(cpfds.n || use_wakeup) { #else @@ -1441,11 +1518,12 @@ static CURLMcode multi_wait(struct Curl_multi *multi, timeout */ else if(sleep_ms < 0) sleep_ms = timeout_ms; - Curl_wait_ms(sleep_ms); + curlx_wait_ms(sleep_ms); } } out: + Curl_pollset_cleanup(&ps); Curl_pollfds_cleanup(&cpfds); return result; } @@ -1946,12 +2024,6 @@ static CURLMcode state_performing(struct Curl_easy *data, } } } - else if(data->state.select_bits && !Curl_xfer_is_blocked(data)) { - /* This avoids CURLM_CALL_MULTI_PERFORM so that a very fast transfer does - not get stuck on this transfer at the expense of other concurrent - transfers */ - Curl_expire(data, 0, EXPIRE_RUN_NOW); - } free(newurl); *resultp = result; return rc; @@ -2215,6 +2287,7 @@ static CURLMcode state_connect(struct Curl_multi *multi, multistate(data, MSTATE_PENDING); /* move from process to pending set */ Curl_uint_bset_remove(&multi->process, data->mid); + Curl_uint_bset_remove(&multi->dirty, data->mid); Curl_uint_bset_add(&multi->pending, data->mid); *resultp = CURLE_OK; return rc; @@ -2276,6 +2349,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, multi_warn_debug(multi, data); + /* transfer runs now, clear the dirty bit. This may be set + * again during processing, triggering a re-run later. */ + Curl_uint_bset_remove(&multi->dirty, data->mid); + do { /* A "stream" here is a logical stream if the protocol can handle that (HTTP/2), or the full connection for older protocols */ @@ -2480,8 +2557,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* Only perform the transfer if there is a good socket to work with. Having both BAD is a signal to skip immediately to DONE */ - if((data->conn->sockfd != CURL_SOCKET_BAD) || - (data->conn->writesockfd != CURL_SOCKET_BAD)) + if(CONN_SOCK_IDX_VALID(data->conn->recv_idx) || + CONN_SOCK_IDX_VALID(data->conn->send_idx)) multistate(data, MSTATE_PERFORMING); else { #ifndef CURL_DISABLE_FTP @@ -2642,6 +2719,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* remove from the other sets, add to msgsent */ Curl_uint_bset_remove(&multi->process, data->mid); + Curl_uint_bset_remove(&multi->dirty, data->mid); Curl_uint_bset_remove(&multi->pending, data->mid); Curl_uint_bset_add(&multi->msgsent, data->mid); --multi->xfers_alive; @@ -2679,6 +2757,7 @@ CURLMcode curl_multi_perform(CURLM *m, int *running_handles) if(!data) { DEBUGASSERT(0); Curl_uint_bset_remove(&multi->process, mid); + Curl_uint_bset_remove(&multi->dirty, mid); continue; } if(data != multi->admin) { @@ -2714,6 +2793,7 @@ CURLMcode curl_multi_perform(CURLM *m, int *running_handles) if(t) { /* the removed may have another timeout in queue */ struct Curl_easy *data = Curl_splayget(t); + (void)add_next_timeout(now, multi, data); if(data->mstate == MSTATE_PENDING) { bool stream_unused; CURLcode result_unused; @@ -2722,7 +2802,6 @@ CURLMcode curl_multi_perform(CURLM *m, int *running_handles) move_pending_to_connect(multi, data); } } - (void)add_next_timeout(now, multi, Curl_splayget(t)); } } while(t); @@ -2757,7 +2836,7 @@ CURLMcode curl_multi_cleanup(CURLM *m) #ifdef DEBUGBUILD if(mid != data->mid) { CURL_TRC_M(data, "multi_cleanup: still present with mid=%u, " - "but unexpected data->mid=%u\n", mid, data->mid); + "but unexpected data->mid=%u\n", mid, data->mid); DEBUGASSERT(0); } #endif @@ -2798,7 +2877,9 @@ CURLMcode curl_multi_cleanup(CURLM *m) Curl_hash_destroy(&multi->proto_hash); Curl_dnscache_destroy(&multi->dnscache); Curl_psl_destroy(&multi->psl); +#ifdef USE_SSL Curl_ssl_scache_destroy(multi->ssl_scache); +#endif #ifdef USE_WINSOCK WSACloseEvent(multi->wsa_event); @@ -2819,6 +2900,7 @@ CURLMcode curl_multi_cleanup(CURLM *m) } #endif Curl_uint_bset_destroy(&multi->process); + Curl_uint_bset_destroy(&multi->dirty); Curl_uint_bset_destroy(&multi->pending); Curl_uint_bset_destroy(&multi->msgsent); Curl_uint_tbl_destroy(&multi->xfers); @@ -2942,12 +3024,11 @@ struct multi_run_ctx { bool run_cpool; }; -static CURLMcode multi_run_expired(struct multi_run_ctx *mrc) +static void multi_mark_expired_as_dirty(struct multi_run_ctx *mrc) { struct Curl_multi *multi = mrc->multi; struct Curl_easy *data = NULL; struct Curl_tree *t = NULL; - CURLMcode result = CURLM_OK; /* * The loop following here will go on as long as there are expire-times left @@ -2959,33 +3040,64 @@ static CURLMcode multi_run_expired(struct multi_run_ctx *mrc) extracts a matching node if there is one */ multi->timetree = Curl_splaygetbest(mrc->now, multi->timetree, &t); if(!t) - goto out; + return; data = Curl_splayget(t); /* assign this for next loop */ if(!data) continue; (void)add_next_timeout(mrc->now, multi, data); - if(data == multi->admin) { - mrc->run_cpool = TRUE; - continue; - } + Curl_multi_mark_dirty(data); + } +} - mrc->run_xfers++; - sigpipe_apply(data, &mrc->pipe_st); - result = multi_runsingle(multi, &mrc->now, data); +static CURLMcode multi_run_dirty(struct multi_run_ctx *mrc) +{ + struct Curl_multi *multi = mrc->multi; + CURLMcode result = CURLM_OK; + unsigned int mid; - if(CURLM_OK >= result) { - /* reassess event handling of data */ - result = Curl_multi_ev_assess_xfer(multi, data); - if(result) - goto out; + if(Curl_uint_bset_first(&multi->dirty, &mid)) { + do { + struct Curl_easy *data = Curl_multi_get_easy(multi, mid); + if(data) { + CURL_TRC_M(data, "multi_run_dirty"); + + if(data == multi->admin) { + Curl_uint_bset_remove(&multi->dirty, mid); + mrc->run_cpool = TRUE; + continue; + } + else if(!Curl_uint_bset_contains(&multi->process, mid)) { + /* We are no longer processing this transfer */ + Curl_uint_bset_remove(&multi->dirty, mid); + continue; + } + + mrc->run_xfers++; + sigpipe_apply(data, &mrc->pipe_st); + /* runsingle() clears the dirty mid */ + result = multi_runsingle(multi, &mrc->now, data); + + if(CURLM_OK >= result) { + /* reassess event handling of data */ + result = Curl_multi_ev_assess_xfer(multi, data); + if(result) + goto out; + } + } + else { + CURL_TRC_M(multi->admin, "multi_run_dirty, %u no longer found", mid); + Curl_uint_bset_remove(&multi->dirty, mid); + } } + while(Curl_uint_bset_next(&multi->dirty, mid, &mid)); } out: return result; } + static CURLMcode multi_socket(struct Curl_multi *multi, bool checkall, curl_socket_t s, @@ -3014,7 +3126,8 @@ static CURLMcode multi_socket(struct Curl_multi *multi, } if(s != CURL_SOCKET_TIMEOUT) { - Curl_multi_ev_expire_xfers(multi, s, &mrc.now, &mrc.run_cpool); + /* Mark all transfers of that socket as dirty */ + Curl_multi_ev_dirty_xfers(multi, s, &mrc.run_cpool); } else { /* Asked to run due to time-out. Clear the 'last_expire_ts' variable to @@ -3026,7 +3139,8 @@ static CURLMcode multi_socket(struct Curl_multi *multi, mrc.run_cpool = TRUE; } - result = multi_run_expired(&mrc); + multi_mark_expired_as_dirty(&mrc); + result = multi_run_dirty(&mrc); if(result) goto out; @@ -3037,7 +3151,8 @@ static CURLMcode multi_socket(struct Curl_multi *multi, * Do that only once or it might be unfair to transfers on other * sockets. */ mrc.now = curlx_now(); - result = multi_run_expired(&mrc); + multi_mark_expired_as_dirty(&mrc); + result = multi_run_dirty(&mrc); } out: @@ -3129,6 +3244,16 @@ CURLMcode curl_multi_setopt(CURLM *m, multi->max_concurrent_streams = (unsigned int)streams; } break; + case CURLMOPT_NETWORK_CHANGED: { + long val = va_arg(param, long); + if(val & CURLMNWC_CLEAR_DNS) { + Curl_dnscache_clear(multi->admin); + } + if(val & CURLMNWC_CLEAR_CONNS) { + Curl_cpool_nw_changed(multi->admin); + } + break; + } default: res = CURLM_UNKNOWN_OPTION; break; @@ -3165,6 +3290,29 @@ CURLMcode curl_multi_socket_all(CURLM *m, int *running_handles) return multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles); } + +static bool multi_has_dirties(struct Curl_multi *multi) +{ + unsigned int mid; + if(Curl_uint_bset_first(&multi->dirty, &mid)) { + do { + struct Curl_easy *data = Curl_multi_get_easy(multi, mid); + if(data) { + if(Curl_uint_bset_contains(&multi->process, mid)) + return TRUE; + /* We are no longer processing this transfer */ + Curl_uint_bset_remove(&multi->dirty, mid); + } + else { + CURL_TRC_M(multi->admin, "dirty transfer %u no longer found", mid); + Curl_uint_bset_remove(&multi->dirty, mid); + } + } + while(Curl_uint_bset_next(&multi->dirty, mid, &mid)); + } + return FALSE; +} + static CURLMcode multi_timeout(struct Curl_multi *multi, struct curltime *expire_time, long *timeout_ms) @@ -3176,7 +3324,12 @@ static CURLMcode multi_timeout(struct Curl_multi *multi, return CURLM_OK; } - if(multi->timetree) { + if(multi_has_dirties(multi)) { + *expire_time = curlx_now(); + *timeout_ms = 0; + return CURLM_OK; + } + else if(multi->timetree) { /* we have a tree of expire times */ struct curltime now = curlx_now(); @@ -3197,6 +3350,10 @@ static CURLMcode multi_timeout(struct Curl_multi *multi, *timeout_ms = (long)diff; } else { + if(multi->timetree) { + struct Curl_easy *data = Curl_splayget(multi->timetree); + CURL_TRC_M(data, "multi_timeout() says this has expired"); + } /* 0 means immediately */ *timeout_ms = 0; } @@ -3420,6 +3577,9 @@ void Curl_expire_ex(struct Curl_easy *data, Curl_splayset(&data->state.timenode, data); multi->timetree = Curl_splayinsert(*curr_expire, multi->timetree, &data->state.timenode); + if(data->id >= 0) + CURL_TRC_M(data, "set expire[%d] in %" FMT_TIMEDIFF_T "ns", + id, curlx_timediff_us(set, *nowp)); } /* @@ -3508,9 +3668,7 @@ static void move_pending_to_connect(struct Curl_multi *multi, Curl_uint_bset_add(&multi->process, data->mid); multistate(data, MSTATE_CONNECT); - - /* Make sure that the handle will be processed soonish. */ - Curl_expire(data, 0, EXPIRE_RUN_NOW); + Curl_multi_mark_dirty(data); /* make it run */ } /* process_pending_handles() moves a handle from PENDING back into the process @@ -3533,9 +3691,13 @@ static void process_pending_handles(struct Curl_multi *multi) if(Curl_uint_bset_first(&multi->pending, &mid)) { do { struct Curl_easy *data = Curl_multi_get_easy(multi, mid); - DEBUGASSERT(data); - if(data) + if(data) { move_pending_to_connect(multi, data); + break; + } + /* transfer no longer known, should not happen */ + Curl_uint_bset_remove(&multi->pending, mid); + DEBUGASSERT(0); } while(Curl_uint_bset_next(&multi->pending, mid, &mid)); } @@ -3581,6 +3743,43 @@ CURL **curl_multi_get_handles(CURLM *m) return a; } +CURLMcode curl_multi_get_offt(CURLM *m, + CURLMinfo_offt info, + curl_off_t *pvalue) +{ + struct Curl_multi *multi = m; + + if(!GOOD_MULTI_HANDLE(multi)) + return CURLM_BAD_HANDLE; + if(!pvalue) + return CURLM_BAD_FUNCTION_ARGUMENT; + + switch(info) { + case CURLMINFO_XFERS_CURRENT: { + unsigned int n = Curl_uint_tbl_count(&multi->xfers); + if(n && multi->admin) + --n; + *pvalue = (curl_off_t)n; + return CURLM_OK; + } + case CURLMINFO_XFERS_RUNNING: + *pvalue = (curl_off_t)Curl_uint_bset_count(&multi->process); + return CURLM_OK; + case CURLMINFO_XFERS_PENDING: + *pvalue = (curl_off_t)Curl_uint_bset_count(&multi->pending); + return CURLM_OK; + case CURLMINFO_XFERS_DONE: + *pvalue = (curl_off_t)Curl_uint_bset_count(&multi->msgsent); + return CURLM_OK; + case CURLMINFO_XFERS_ADDED: + *pvalue = multi->xfers_total_ever; + return CURLM_OK; + default: + *pvalue = -1; + return CURLM_UNKNOWN_OPTION; + } +} + CURLcode Curl_multi_xfer_buf_borrow(struct Curl_easy *data, char **pbuf, size_t *pbuflen) { @@ -3763,9 +3962,15 @@ unsigned int Curl_multi_xfers_running(struct Curl_multi *multi) return multi->xfers_alive; } +void Curl_multi_mark_dirty(struct Curl_easy *data) +{ + if(data->multi && data->mid != UINT_MAX) + Curl_uint_bset_add(&data->multi->dirty, data->mid); +} + #ifdef DEBUGBUILD static void multi_xfer_dump(struct Curl_multi *multi, unsigned int mid, - void *entry) + void *entry) { struct Curl_easy *data = entry; diff --git a/vendor/curl/lib/multi_ev.c b/vendor/curl/lib/multi_ev.c index 21d28676195..61c639d9e48 100644 --- a/vendor/curl/lib/multi_ev.c +++ b/vendor/curl/lib/multi_ev.c @@ -64,19 +64,21 @@ struct mev_sh_entry { * libcurl application to watch out for */ unsigned int readers; /* this many transfers want to read */ unsigned int writers; /* this many transfers want to write */ + BIT(announced); /* this socket has been passed to the socket + callback at least once */ }; static size_t mev_sh_entry_hash(void *key, size_t key_length, size_t slots_num) { curl_socket_t fd = *((curl_socket_t *) key); - (void) key_length; + (void)key_length; return (fd % (curl_socket_t)slots_num); } static size_t mev_sh_entry_compare(void *k1, size_t k1_len, void *k2, size_t k2_len) { - (void) k1_len; (void) k2_len; + (void)k1_len; (void)k2_len; return (*((curl_socket_t *) k1)) == (*((curl_socket_t *) k2)); } @@ -205,13 +207,14 @@ static CURLMcode mev_forget_socket(struct Curl_multi *multi, return CURLM_OK; /* We managed this socket before, tell the socket callback to forget it. */ - if(multi->socket_cb) { + if(entry->announced && multi->socket_cb) { CURL_TRC_M(data, "ev %s, call(fd=%" FMT_SOCKET_T ", ev=REMOVE)", cause, s); mev_in_callback(multi, TRUE); rc = multi->socket_cb(data, s, CURL_POLL_REMOVE, multi->socket_userp, entry->user_data); mev_in_callback(multi, FALSE); + entry->announced = FALSE; } mev_sh_entry_kill(multi, s); @@ -281,8 +284,8 @@ static CURLMcode mev_sh_entry_update(struct Curl_multi *multi, mev_in_callback(multi, TRUE); rc = multi->socket_cb(data, s, comboaction, multi->socket_userp, entry->user_data); - mev_in_callback(multi, FALSE); + entry->announced = TRUE; if(rc == -1) { multi->dead = TRUE; return CURLM_ABORTED_BY_CALLBACK; @@ -314,7 +317,7 @@ static CURLMcode mev_pollset_diff(struct Curl_multi *multi, DEBUGASSERT(prev_ps); /* Handle changes to sockets the transfer is interested in. */ - for(i = 0; i < ps->num; i++) { + for(i = 0; i < ps->n; i++) { unsigned char last_action; bool first_time = FALSE; /* data/conn appears first time on socket */ @@ -359,7 +362,7 @@ static CURLMcode mev_pollset_diff(struct Curl_multi *multi, entry->conn ? 1 : 0); } else { - for(j = 0; j < prev_ps->num; j++) { + for(j = 0; j < prev_ps->n; j++) { if(s == prev_ps->sockets[j]) { last_action = prev_ps->actions[j]; break; @@ -374,11 +377,11 @@ static CURLMcode mev_pollset_diff(struct Curl_multi *multi, } /* Handle changes to sockets the transfer is NO LONGER interested in. */ - for(i = 0; i < prev_ps->num; i++) { + for(i = 0; i < prev_ps->n; i++) { bool stillused = FALSE; s = prev_ps->sockets[i]; - for(j = 0; j < ps->num; j++) { + for(j = 0; j < ps->n; j++) { if(s == ps->sockets[j]) { /* socket is still supervised */ stillused = TRUE; @@ -434,15 +437,19 @@ static CURLMcode mev_pollset_diff(struct Curl_multi *multi, } /* for loop over num */ /* Remember for next time */ - memcpy(prev_ps, ps, sizeof(*prev_ps)); + Curl_pollset_move(prev_ps, ps); return CURLM_OK; } static void mev_pollset_dtor(void *key, size_t klen, void *entry) { + struct easy_pollset *ps = entry; (void)key; (void)klen; - free(entry); + if(ps) { + Curl_pollset_cleanup(ps); + free(ps); + } } static struct easy_pollset* @@ -450,7 +457,7 @@ mev_add_new_conn_pollset(struct connectdata *conn) { struct easy_pollset *ps; - ps = calloc(1, sizeof(*ps)); + ps = Curl_pollset_create(); if(!ps) return NULL; if(Curl_conn_meta_set(conn, CURL_META_MEV_POLLSET, ps, mev_pollset_dtor)) @@ -463,7 +470,7 @@ mev_add_new_xfer_pollset(struct Curl_easy *data) { struct easy_pollset *ps; - ps = calloc(1, sizeof(*ps)); + ps = Curl_pollset_create(); if(!ps) return NULL; if(Curl_meta_set(data, CURL_META_MEV_POLLSET, ps, mev_pollset_dtor)) @@ -483,42 +490,47 @@ mev_get_last_pollset(struct Curl_easy *data, return NULL; } -static void mev_init_cur_pollset(struct easy_pollset *ps, - struct Curl_easy *data, - struct connectdata *conn) -{ - memset(ps, 0, sizeof(*ps)); - if(conn) - Curl_conn_adjust_pollset(data, conn, ps); - else if(data) - Curl_multi_getsock(data, ps, "ev assess"); -} - static CURLMcode mev_assess(struct Curl_multi *multi, struct Curl_easy *data, struct connectdata *conn) { - if(multi && multi->socket_cb) { - struct easy_pollset ps, *last_ps; + struct easy_pollset ps, *last_ps; + CURLMcode res = CURLM_OK; - mev_init_cur_pollset(&ps, data, conn); - last_ps = mev_get_last_pollset(data, conn); + if(!multi || !multi->socket_cb) + return CURLM_OK; - if(!last_ps && ps.num) { - if(conn) - last_ps = mev_add_new_conn_pollset(conn); - else - last_ps = mev_add_new_xfer_pollset(data); - if(!last_ps) - return CURLM_OUT_OF_MEMORY; + Curl_pollset_init(&ps); + if(conn) { + CURLcode r = Curl_conn_adjust_pollset(data, conn, &ps); + if(r) { + res = (r == CURLE_OUT_OF_MEMORY) ? + CURLM_OUT_OF_MEMORY : CURLM_INTERNAL_ERROR; + goto out; } + } + else if(data) + Curl_multi_pollset(data, &ps, "ev assess"); + last_ps = mev_get_last_pollset(data, conn); - if(last_ps) - return mev_pollset_diff(multi, data, conn, &ps, last_ps); + if(!last_ps && ps.n) { + if(conn) + last_ps = mev_add_new_conn_pollset(conn); else - DEBUGASSERT(!ps.num); + last_ps = mev_add_new_xfer_pollset(data); + if(!last_ps) { + res = CURLM_OUT_OF_MEMORY; + goto out; + } } - return CURLM_OK; + + if(last_ps) + res = mev_pollset_diff(multi, data, conn, &ps, last_ps); + else + DEBUGASSERT(!ps.n); +out: + Curl_pollset_cleanup(&ps); + return res; } CURLMcode Curl_multi_ev_assess_xfer(struct Curl_multi *multi, @@ -563,10 +575,9 @@ CURLMcode Curl_multi_ev_assign(struct Curl_multi *multi, return CURLM_OK; } -void Curl_multi_ev_expire_xfers(struct Curl_multi *multi, - curl_socket_t s, - const struct curltime *nowp, - bool *run_cpool) +void Curl_multi_ev_dirty_xfers(struct Curl_multi *multi, + curl_socket_t s, + bool *run_cpool) { struct mev_sh_entry *entry; @@ -586,9 +597,11 @@ void Curl_multi_ev_expire_xfers(struct Curl_multi *multi, do { data = Curl_multi_get_easy(multi, mid); if(data) { - /* Expire with out current now, so we will get it below when - * asking the splaytree for expired transfers. */ - Curl_expire_ex(data, nowp, 0, EXPIRE_RUN_NOW); + Curl_multi_mark_dirty(data); + } + else { + CURL_TRC_M(multi->admin, "socket transfer %u no longer found", mid); + Curl_uint_spbset_remove(&entry->xfers, mid); } } while(Curl_uint_spbset_next(&entry->xfers, mid, &mid)); diff --git a/vendor/curl/lib/multi_ev.h b/vendor/curl/lib/multi_ev.h index 06be842fb96..20c1aeac81a 100644 --- a/vendor/curl/lib/multi_ev.h +++ b/vendor/curl/lib/multi_ev.h @@ -61,11 +61,10 @@ CURLMcode Curl_multi_ev_assess_conn(struct Curl_multi *multi, struct Curl_easy *data, struct connectdata *conn); -/* Expire all transfers tied to the given socket */ -void Curl_multi_ev_expire_xfers(struct Curl_multi *multi, - curl_socket_t s, - const struct curltime *nowp, - bool *run_cpool); +/* Mark all transfers tied to the given socket as dirty */ +void Curl_multi_ev_dirty_xfers(struct Curl_multi *multi, + curl_socket_t s, + bool *run_cpool); /* Socket will be closed, forget anything we know about it. */ void Curl_multi_ev_socket_done(struct Curl_multi *multi, diff --git a/vendor/curl/lib/multihandle.h b/vendor/curl/lib/multihandle.h index 04db02f0b16..ae41044adc2 100644 --- a/vendor/curl/lib/multihandle.h +++ b/vendor/curl/lib/multihandle.h @@ -72,15 +72,9 @@ typedef enum { MSTATE_LAST /* 18 - not a true state, never use this */ } CURLMstate; -/* we support N sockets per easy handle. Set the corresponding bit to what - action we should wait for */ -#define MAX_SOCKSPEREASYHANDLE 5 -#define GETSOCK_READABLE (0x00ff) -#define GETSOCK_WRITABLE (0xff00) - #define CURLPIPE_ANY (CURLPIPE_MULTIPLEX) -#if !defined(CURL_DISABLE_SOCKETPAIR) +#ifndef CURL_DISABLE_SOCKETPAIR #define ENABLE_WAKEUP #endif @@ -95,9 +89,11 @@ struct Curl_multi { unsigned int xfers_alive; /* amount of added transfers that have not yet reached COMPLETE state */ + curl_off_t xfers_total_ever; /* total of added transfers, ever. */ struct uint_tbl xfers; /* transfers added to this multi */ /* Each transfer's mid may be present in at most one of these */ struct uint_bset process; /* transfer being processed */ + struct uint_bset dirty; /* transfer to be run NOW, e.g. ASAP. */ struct uint_bset pending; /* transfers in waiting (conn limit etc.) */ struct uint_bset msgsent; /* transfers done with message for application */ diff --git a/vendor/curl/lib/multiif.h b/vendor/curl/lib/multiif.h index eae634ab405..5cf22bc0467 100644 --- a/vendor/curl/lib/multiif.h +++ b/vendor/curl/lib/multiif.h @@ -36,7 +36,7 @@ bool Curl_expire_clear(struct Curl_easy *data); void Curl_expire_done(struct Curl_easy *data, expire_id id); CURLMcode Curl_update_timer(struct Curl_multi *multi) WARN_UNUSED_RESULT; void Curl_attach_connection(struct Curl_easy *data, - struct connectdata *conn); + struct connectdata *conn); void Curl_detach_connection(struct Curl_easy *data); bool Curl_multiplex_wanted(const struct Curl_multi *multi); void Curl_set_in_callback(struct Curl_easy *data, bool value); @@ -53,20 +53,6 @@ struct Curl_multi *Curl_multi_handle(unsigned int xfer_table_size, size_t dnssize, size_t sesssize); -/* the write bits start at bit 16 for the *getsock() bitmap */ -#define GETSOCK_WRITEBITSTART 16 - -#define GETSOCK_BLANK 0 /* no bits set */ - -/* set the bit for the given sock number to make the bitmap for writable */ -#define GETSOCK_WRITESOCK(x) (1 << (GETSOCK_WRITEBITSTART + (x))) - -/* set the bit for the given sock number to make the bitmap for readable */ -#define GETSOCK_READSOCK(x) (1 << (x)) - -/* mask for checking if read and/or write is set for index x */ -#define GETSOCK_MASK_RW(x) (GETSOCK_READSOCK(x)|GETSOCK_WRITESOCK(x)) - /** * Let the multi handle know that the socket is about to be closed. * The multi will then remove anything it knows about the socket, so @@ -86,9 +72,9 @@ CURLMcode Curl_multi_add_perform(struct Curl_multi *multi, /* Return the value of the CURLMOPT_MAX_CONCURRENT_STREAMS option */ unsigned int Curl_multi_max_concurrent_streams(struct Curl_multi *multi); -void Curl_multi_getsock(struct Curl_easy *data, - struct easy_pollset *ps, - const char *caller); +CURLMcode Curl_multi_pollset(struct Curl_easy *data, + struct easy_pollset *ps, + const char *caller); /** * Borrow the transfer buffer from the multi, suitable @@ -106,7 +92,7 @@ void Curl_multi_getsock(struct Curl_easy *data, * CURLE_AGAIN if the buffer is borrowed already. */ CURLcode Curl_multi_xfer_buf_borrow(struct Curl_easy *data, - char **pbuf, size_t *pbuflen); + char **pbuf, size_t *pbuflen); /** * Release the borrowed buffer. All references into the buffer become * invalid after this. @@ -173,4 +159,8 @@ struct Curl_easy *Curl_multi_get_easy(struct Curl_multi *multi, /* Get the # of transfers current in process/pending. */ unsigned int Curl_multi_xfers_running(struct Curl_multi *multi); +/* Mark a transfer as dirty, e.g. to be rerun at earliest convenience. + * A cheap operation, can be done many times repeatedly. */ +void Curl_multi_mark_dirty(struct Curl_easy *data); + #endif /* HEADER_CURL_MULTIIF_H */ diff --git a/vendor/curl/lib/netrc.c b/vendor/curl/lib/netrc.c index 7df3f17fc3a..447ee095852 100644 --- a/vendor/curl/lib/netrc.c +++ b/vendor/curl/lib/netrc.c @@ -229,12 +229,12 @@ static NETRCcode parsenetrc(struct store_netrc *store, switch(state) { case NOTHING: - if(strcasecompare("macdef", tok)) + if(curl_strequal("macdef", tok)) /* Define a macro. A macro is defined with the specified name; its contents begin with the next .netrc line and continue until a null line (consecutive new-line characters) is encountered. */ state = MACDEF; - else if(strcasecompare("machine", tok)) { + else if(curl_strequal("machine", tok)) { /* the next tok is the machine name, this is in itself the delimiter that starts the stuff entered for this machine, after this we need to search for 'login' and 'password'. */ @@ -246,7 +246,7 @@ static NETRCcode parsenetrc(struct store_netrc *store, if(!specific_login) Curl_safefree(login); } - else if(strcasecompare("default", tok)) { + else if(curl_strequal("default", tok)) { state = HOSTVALID; retcode = NETRC_OK; /* we did find our host */ } @@ -256,7 +256,7 @@ static NETRCcode parsenetrc(struct store_netrc *store, state = NOTHING; break; case HOSTFOUND: - if(strcasecompare(host, tok)) { + if(curl_strequal(host, tok)) { /* and yes, this is our host! */ state = HOSTVALID; retcode = NETRC_OK; /* we did find our host */ @@ -293,11 +293,11 @@ static NETRCcode parsenetrc(struct store_netrc *store, found |= FOUND_PASSWORD; keyword = NONE; } - else if(strcasecompare("login", tok)) + else if(curl_strequal("login", tok)) keyword = LOGIN; - else if(strcasecompare("password", tok)) + else if(curl_strequal("password", tok)) keyword = PASSWORD; - else if(strcasecompare("machine", tok)) { + else if(curl_strequal("machine", tok)) { /* a new machine here */ if(found & FOUND_PASSWORD) { done = TRUE; @@ -310,7 +310,7 @@ static NETRCcode parsenetrc(struct store_netrc *store, if(!specific_login) Curl_safefree(login); } - else if(strcasecompare("default", tok)) { + else if(curl_strequal("default", tok)) { state = HOSTVALID; retcode = NETRC_OK; /* we did find our host */ Curl_safefree(password); @@ -390,53 +390,57 @@ const char *Curl_netrc_strerror(NETRCcode ret) */ NETRCcode Curl_parsenetrc(struct store_netrc *store, const char *host, char **loginp, char **passwordp, - char *netrcfile) + const char *netrcfile) { NETRCcode retcode = NETRC_OK; char *filealloc = NULL; if(!netrcfile) { + char *home = NULL; + char *homea = NULL; #if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) char pwbuf[1024]; #endif - char *home = NULL; - char *homea = curl_getenv("HOME"); /* portable environment reader */ - if(homea) { - home = homea; + filealloc = curl_getenv("NETRC"); + if(!filealloc) { + homea = curl_getenv("HOME"); /* portable environment reader */ + if(homea) { + home = homea; #if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) - } - else { - struct passwd pw, *pw_res; - if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) - && pw_res) { - home = pw.pw_dir; } + else { + struct passwd pw, *pw_res; + if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) + && pw_res) { + home = pw.pw_dir; + } #elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID) - } - else { - struct passwd *pw; - pw = getpwuid(geteuid()); - if(pw) { - home = pw->pw_dir; } + else { + struct passwd *pw; + pw = getpwuid(geteuid()); + if(pw) { + home = pw->pw_dir; + } #elif defined(_WIN32) - } - else { - homea = curl_getenv("USERPROFILE"); - if(homea) { - home = homea; } + else { + homea = curl_getenv("USERPROFILE"); + if(homea) { + home = homea; + } #endif - } + } - if(!home) - return NETRC_FILE_MISSING; /* no home directory found (or possibly out - of memory) */ + if(!home) + return NETRC_FILE_MISSING; /* no home directory found (or possibly out + of memory) */ - filealloc = aprintf("%s%s.netrc", home, DIR_CHAR); - if(!filealloc) { - free(homea); - return NETRC_OUT_OF_MEMORY; + filealloc = aprintf("%s%s.netrc", home, DIR_CHAR); + if(!filealloc) { + free(homea); + return NETRC_OUT_OF_MEMORY; + } } retcode = parsenetrc(store, host, loginp, passwordp, filealloc); free(filealloc); diff --git a/vendor/curl/lib/netrc.h b/vendor/curl/lib/netrc.h index ef3bde5212a..0d6d081bfbb 100644 --- a/vendor/curl/lib/netrc.h +++ b/vendor/curl/lib/netrc.h @@ -48,7 +48,8 @@ void Curl_netrc_init(struct store_netrc *s); void Curl_netrc_cleanup(struct store_netrc *s); NETRCcode Curl_parsenetrc(struct store_netrc *s, const char *host, - char **loginp, char **passwordp, char *filename); + char **loginp, char **passwordp, + const char *filename); /* Assume: (*passwordp)[0]=0, host[0] != 0. * If (*loginp)[0] = 0, search for login and password within a machine * section in the netrc. diff --git a/vendor/curl/lib/noproxy.c b/vendor/curl/lib/noproxy.c index f70f57eb5af..22b067ad1b0 100644 --- a/vendor/curl/lib/noproxy.c +++ b/vendor/curl/lib/noproxy.c @@ -26,8 +26,8 @@ #ifndef CURL_DISABLE_PROXY +#include /* for curl_strnequal() */ #include "curlx/inet_pton.h" -#include "strcase.h" #include "noproxy.h" #include "curlx/strparse.h" @@ -54,9 +54,9 @@ UNITTEST bool Curl_cidr4_match(const char *ipv4, /* 1.2.3.4 address */ /* strange input */ return FALSE; - if(1 != curlx_inet_pton(AF_INET, ipv4, &address)) + if(curlx_inet_pton(AF_INET, ipv4, &address) != 1) return FALSE; - if(1 != curlx_inet_pton(AF_INET, network, &check)) + if(curlx_inet_pton(AF_INET, network, &check) != 1) return FALSE; if(bits && (bits != 32)) { @@ -92,9 +92,9 @@ UNITTEST bool Curl_cidr6_match(const char *ipv6, rest = bits & 0x07; if((bytes > 16) || ((bytes == 16) && rest)) return FALSE; - if(1 != curlx_inet_pton(AF_INET6, ipv6, address)) + if(curlx_inet_pton(AF_INET6, ipv6, address) != 1) return FALSE; - if(1 != curlx_inet_pton(AF_INET6, network, check)) + if(curlx_inet_pton(AF_INET6, network, check) != 1) return FALSE; if(bytes && memcmp(address, check, bytes)) return FALSE; @@ -163,7 +163,7 @@ bool Curl_check_noproxy(const char *name, const char *no_proxy) else { unsigned int address; namelen = strlen(name); - if(1 == curlx_inet_pton(AF_INET, name, &address)) + if(curlx_inet_pton(AF_INET, name, &address) == 1) type = TYPE_IPV4; else { /* ignore trailing dots in the hostname */ @@ -205,12 +205,12 @@ bool Curl_check_noproxy(const char *name, const char *no_proxy) */ if(tokenlen == namelen) /* case A, exact match */ - match = strncasecompare(token, name, namelen); + match = curl_strnequal(token, name, namelen); else if(tokenlen < namelen) { /* case B, tailmatch domain */ match = (name[namelen - tokenlen - 1] == '.') && - strncasecompare(token, name + (namelen - tokenlen), - tokenlen); + curl_strnequal(token, name + (namelen - tokenlen), + tokenlen); } /* case C passes through, not a match */ break; diff --git a/vendor/curl/lib/openldap.c b/vendor/curl/lib/openldap.c index 6343c40c094..1b32e12b686 100644 --- a/vendor/curl/lib/openldap.c +++ b/vendor/curl/lib/openldap.c @@ -126,10 +126,10 @@ const struct Curl_handler Curl_handler_ldap = { oldap_connect, /* connect_it */ oldap_connecting, /* connecting */ ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* proto_pollset */ + ZERO_NULL, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ oldap_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -156,10 +156,10 @@ const struct Curl_handler Curl_handler_ldaps = { oldap_connect, /* connect_it */ oldap_connecting, /* connecting */ ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* proto_pollset */ + ZERO_NULL, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ oldap_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -924,7 +924,7 @@ static CURLcode oldap_disconnect(struct Curl_easy *data, bool dead_connection) { struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); - (void) dead_connection; + (void)dead_connection; #ifndef USE_SSL (void)data; #endif @@ -941,7 +941,6 @@ static CURLcode oldap_disconnect(struct Curl_easy *data, ldap_unbind_ext(li->ld, NULL, NULL); li->ld = NULL; } - Curl_sasl_cleanup(conn, li->sasl.authused); } return CURLE_OK; } @@ -994,7 +993,7 @@ static CURLcode oldap_do(struct Curl_easy *data, bool *done) } lr->msgid = msgid; - Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); *done = TRUE; out: @@ -1048,8 +1047,8 @@ static CURLcode client_write(struct Curl_easy *data, return result; } -static ssize_t oldap_recv(struct Curl_easy *data, int sockindex, char *buf, - size_t len, CURLcode *err) +static CURLcode oldap_recv(struct Curl_easy *data, int sockindex, char *buf, + size_t len, size_t *pnread) { struct connectdata *conn = data->conn; struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); @@ -1067,10 +1066,9 @@ static ssize_t oldap_recv(struct Curl_easy *data, int sockindex, char *buf, (void)len; (void)buf; (void)sockindex; - if(!li || !lr) { - *err = CURLE_FAILED_INIT; - return -1; - } + *pnread = 0; + if(!li || !lr) + return CURLE_FAILED_INIT; rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_ONE, &tv, &msg); if(rc < 0) { @@ -1078,11 +1076,9 @@ static ssize_t oldap_recv(struct Curl_easy *data, int sockindex, char *buf, result = CURLE_RECV_ERROR; } - *err = result; - /* error or timed out */ if(!msg) - return -1; + return result; result = CURLE_OK; @@ -1210,8 +1206,7 @@ static ssize_t oldap_recv(struct Curl_easy *data, int sockindex, char *buf, } ldap_msgfree(msg); - *err = result; - return result ? -1 : 0; + return result; } #ifdef USE_SSL @@ -1258,15 +1253,17 @@ ldapsb_tls_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) if(conn) { struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); CURLcode err = CURLE_RECV_ERROR; + size_t nread; if(!li) { SET_SOCKERRNO(SOCKEINVAL); return -1; } - ret = (li->recv)(data, FIRSTSOCKET, buf, len, &err); - if(ret < 0 && err == CURLE_AGAIN) { + err = (li->recv)(data, FIRSTSOCKET, buf, len, &nread); + if(err == CURLE_AGAIN) { SET_SOCKERRNO(SOCKEWOULDBLOCK); } + ret = err ? -1 : (ber_slen_t)nread; } } return ret; @@ -1281,15 +1278,17 @@ ldapsb_tls_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) if(conn) { struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); CURLcode err = CURLE_SEND_ERROR; + size_t nwritten; if(!li) { SET_SOCKERRNO(SOCKEINVAL); return -1; } - ret = (li->send)(data, FIRSTSOCKET, buf, len, FALSE, &err); - if(ret < 0 && err == CURLE_AGAIN) { + err = (li->send)(data, FIRSTSOCKET, buf, len, FALSE, &nwritten); + if(err == CURLE_AGAIN) { SET_SOCKERRNO(SOCKEWOULDBLOCK); } + ret = err ? -1 : (ber_slen_t)nwritten; } } return ret; diff --git a/vendor/curl/lib/parsedate.c b/vendor/curl/lib/parsedate.c index 7e0c69106c0..eedab7c411b 100644 --- a/vendor/curl/lib/parsedate.c +++ b/vendor/curl/lib/parsedate.c @@ -80,7 +80,6 @@ #include #include -#include "strcase.h" #include "curlx/warnless.h" #include "parsedate.h" #include "curlx/strparse.h" @@ -151,7 +150,7 @@ static const struct tzinfo tz[]= { {"HDT", 600 tDAYZONE}, /* Hawaii Daylight */ {"CAT", 600}, /* Central Alaska */ {"AHST", 600}, /* Alaska-Hawaii Standard */ - {"NT", 660}, /* Nome */ + {"NT", 660}, /* Nome */ /* spellchecker:disable-line */ {"IDLW", 720}, /* International Date Line West */ {"CET", -60}, /* Central European */ {"MET", -60}, /* Middle European */ @@ -162,7 +161,8 @@ static const struct tzinfo tz[]= { {"FWT", -60}, /* French Winter */ {"FST", -60 tDAYZONE}, /* French Summer */ {"EET", -120}, /* Eastern Europe, USSR Zone 1 */ - {"WAST", -420}, /* West Australian Standard */ + {"WAST", -420}, /* spellchecker:disable-line */ + /* West Australian Standard */ {"WADT", -420 tDAYZONE}, /* West Australian Daylight */ {"CCT", -480}, /* China Coast, USSR Zone 7 */ {"JST", -540}, /* Japan Standard, USSR Zone 8 */ @@ -224,7 +224,7 @@ static int checkday(const char *check, size_t len) for(i = 0; i < 7; i++) { size_t ilen = strlen(what[0]); if((ilen == len) && - strncasecompare(check, what[0], len)) + curl_strnequal(check, what[0], len)) return i; what++; } @@ -239,7 +239,7 @@ static int checkmonth(const char *check, size_t len) return -1; /* not a month */ for(i = 0; i < 12; i++) { - if(strncasecompare(check, what[0], 3)) + if(curl_strnequal(check, what[0], 3)) return i; what++; } @@ -259,7 +259,7 @@ static int checktz(const char *check, size_t len) for(i = 0; i < CURL_ARRAYSIZE(tz); i++) { size_t ilen = strlen(what->name); if((ilen == len) && - strncasecompare(check, what->name, len)) + curl_strnequal(check, what->name, len)) return what->offset*60; what++; } diff --git a/vendor/curl/lib/pingpong.c b/vendor/curl/lib/pingpong.c index c5513f60502..003ad58441c 100644 --- a/vendor/curl/lib/pingpong.c +++ b/vendor/curl/lib/pingpong.c @@ -52,7 +52,7 @@ timediff_t Curl_pp_state_timeout(struct Curl_easy *data, struct pingpong *pp, bool disconnecting) { timediff_t timeout_ms; /* in milliseconds */ - timediff_t response_time = (data->set.server_response_timeout) ? + timediff_t response_time = (data->set.server_response_timeout > 0) ? data->set.server_response_timeout : pp->response_time; struct curltime now = curlx_now(); @@ -65,7 +65,7 @@ timediff_t Curl_pp_state_timeout(struct Curl_easy *data, full response to arrive before we bail out */ timeout_ms = response_time - curlx_timediff(now, pp->response); - if(data->set.timeout && !disconnecting) { + if((data->set.timeout > 0) && !disconnecting) { /* if timeout is requested, find out how much overall remains */ timediff_t timeout2_ms = Curl_timeleft(data, &now, FALSE); /* pick the lowest number */ @@ -116,11 +116,15 @@ CURLcode Curl_pp_statemach(struct Curl_easy *data, else if(!pp->sendleft && Curl_conn_data_pending(data, FIRSTSOCKET)) /* We are receiving and there is data ready in the SSL library */ rc = 1; - else + else { + DEBUGF(infof(data, "pp_statematch, select, timeout=%" FMT_TIMEDIFF_T + ", sendleft=%zu", + timeout_ms, pp->sendleft)); rc = Curl_socket_check(pp->sendleft ? CURL_SOCKET_BAD : sock, /* reading */ CURL_SOCKET_BAD, pp->sendleft ? sock : CURL_SOCKET_BAD, /* writing */ interval_ms); + } if(block) { /* if we did not wait, we do not have to spend time on this now */ @@ -266,7 +270,7 @@ static CURLcode pingpong_read(struct Curl_easy *data, int sockindex, char *buffer, size_t buflen, - ssize_t *nread) + size_t *nread) { CURLcode result; #ifdef HAVE_GSSAPI @@ -294,7 +298,7 @@ CURLcode Curl_pp_readresp(struct Curl_easy *data, { struct connectdata *conn = data->conn; CURLcode result = CURLE_OK; - ssize_t gotbytes; + size_t gotbytes; char buffer[900]; *code = 0; /* 0 for errors or not done */ @@ -321,7 +325,7 @@ CURLcode Curl_pp_readresp(struct Curl_easy *data, if(result) return result; - if(gotbytes <= 0) { + if(!gotbytes) { failf(data, "response reading failed (errno: %d)", SOCKERRNO); return CURLE_RECV_ERROR; } @@ -393,19 +397,13 @@ CURLcode Curl_pp_readresp(struct Curl_easy *data, return result; } -int Curl_pp_getsock(struct Curl_easy *data, - struct pingpong *pp, curl_socket_t *socks) +CURLcode Curl_pp_pollset(struct Curl_easy *data, + struct pingpong *pp, + struct easy_pollset *ps) { - struct connectdata *conn = data->conn; - socks[0] = conn->sock[FIRSTSOCKET]; - - if(pp->sendleft) { - /* write mode */ - return GETSOCK_WRITESOCK(0); - } - - /* read mode */ - return GETSOCK_READSOCK(0); + int flags = pp->sendleft ? CURL_POLL_OUT : CURL_POLL_IN; + return Curl_pollset_change(data, ps, data->conn->sock[FIRSTSOCKET], + flags, 0); } bool Curl_pp_needs_flush(struct Curl_easy *data, diff --git a/vendor/curl/lib/pingpong.h b/vendor/curl/lib/pingpong.h index 0665b83659e..5db96c4345f 100644 --- a/vendor/curl/lib/pingpong.h +++ b/vendor/curl/lib/pingpong.h @@ -59,7 +59,7 @@ struct pingpong { struct dynbuf recvbuf; size_t overflow; /* number of bytes left after a final response line */ size_t nfinal; /* number of bytes in the final response line, which - after a match is first in the receice buffer */ + after a match is first in the receive buffer */ /* Function pointers the protocols MUST implement and provide for the pingpong layer to function */ @@ -147,8 +147,9 @@ CURLcode Curl_pp_flushsend(struct Curl_easy *data, /* call this when a pingpong connection is disconnected */ CURLcode Curl_pp_disconnect(struct pingpong *pp); -int Curl_pp_getsock(struct Curl_easy *data, struct pingpong *pp, - curl_socket_t *socks); +CURLcode Curl_pp_pollset(struct Curl_easy *data, + struct pingpong *pp, + struct easy_pollset *ps); /*********************************************************************** diff --git a/vendor/curl/lib/pop3.c b/vendor/curl/lib/pop3.c index aa8c2d834a9..508f8faed3d 100644 --- a/vendor/curl/lib/pop3.c +++ b/vendor/curl/lib/pop3.c @@ -66,7 +66,6 @@ #include "socks.h" #include "pingpong.h" #include "pop3.h" -#include "strcase.h" #include "vtls/vtls.h" #include "cfilters.h" #include "connect.h" @@ -154,8 +153,8 @@ static CURLcode pop3_connect(struct Curl_easy *data, bool *done); static CURLcode pop3_disconnect(struct Curl_easy *data, struct connectdata *conn, bool dead); static CURLcode pop3_multi_statemach(struct Curl_easy *data, bool *done); -static int pop3_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks); +static CURLcode pop3_pollset(struct Curl_easy *data, + struct easy_pollset *ps); static CURLcode pop3_doing(struct Curl_easy *data, bool *dophase_done); static CURLcode pop3_setup_connection(struct Curl_easy *data, struct connectdata *conn); @@ -187,10 +186,10 @@ const struct Curl_handler Curl_handler_pop3 = { pop3_connect, /* connect_it */ pop3_multi_statemach, /* connecting */ pop3_doing, /* doing */ - pop3_getsock, /* proto_getsock */ - pop3_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + pop3_pollset, /* proto_pollset */ + pop3_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ pop3_disconnect, /* disconnect */ pop3_write, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -218,10 +217,10 @@ const struct Curl_handler Curl_handler_pop3s = { pop3_connect, /* connect_it */ pop3_multi_statemach, /* connecting */ pop3_doing, /* doing */ - pop3_getsock, /* proto_getsock */ - pop3_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + pop3_pollset, /* proto_pollset */ + pop3_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ pop3_disconnect, /* disconnect */ pop3_write, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -285,7 +284,7 @@ static bool pop3_is_multiline(const char *cmdline) { size_t i; for(i = 0; i < CURL_ARRAYSIZE(pop3cmds); ++i) { - if(strncasecompare(pop3cmds[i].name, cmdline, pop3cmds[i].nlen)) { + if(curl_strnequal(pop3cmds[i].name, cmdline, pop3cmds[i].nlen)) { if(!cmdline[pop3cmds[i].nlen]) return pop3cmds[i].multiline; else if(cmdline[pop3cmds[i].nlen] == ' ') @@ -1117,7 +1116,7 @@ static CURLcode pop3_state_command_resp(struct Curl_easy *data, if(pop3->transfer == PPTRANSFER_BODY) { /* POP3 download */ - Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); if(pp->overflow) { /* The recv buffer contains data that is actually body content so send @@ -1270,13 +1269,12 @@ static CURLcode pop3_block_statemach(struct Curl_easy *data, } /* For the POP3 "protocol connect" and "doing" phases only */ -static int pop3_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks) +static CURLcode pop3_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - if(pop3c) - return Curl_pp_getsock(data, &pop3c->pp, socks); - return GETSOCK_BLANK; + struct pop3_conn *pop3c = + Curl_conn_meta_get(data->conn, CURL_META_POP3_CONN); + return pop3c ? Curl_pp_pollset(data, &pop3c->pp, ps) : CURLE_OK; } /*********************************************************************** @@ -1450,7 +1448,8 @@ static CURLcode pop3_disconnect(struct Curl_easy *data, bad in any way, sending quit and waiting around here will make the disconnect wait in vain and cause more problems than we need to. */ - if(!dead_connection && conn->bits.protoconnstart) { + if(!dead_connection && conn->bits.protoconnstart && + !Curl_pp_needs_flush(data, &pop3c->pp)) { if(!pop3_perform_quit(data, conn)) (void)pop3_block_statemach(data, conn, TRUE); /* ignore errors on QUIT */ } @@ -1458,9 +1457,6 @@ static CURLcode pop3_disconnect(struct Curl_easy *data, /* Disconnect from the server */ Curl_pp_disconnect(&pop3c->pp); - /* Cleanup the SASL module */ - Curl_sasl_cleanup(conn, pop3c->sasl.authused); - /* Cleanup our connection based variables */ Curl_safefree(pop3c->apoptimestamp); @@ -1593,11 +1589,11 @@ static CURLcode pop3_parse_url_options(struct connectdata *conn) while(*ptr && *ptr != ';') ptr++; - if(strncasecompare(key, "AUTH=", 5)) { + if(curl_strnequal(key, "AUTH=", 5)) { result = Curl_sasl_parse_url_auth_option(&pop3c->sasl, value, ptr - value); - if(result && strncasecompare(value, "+APOP", ptr - value)) { + if(result && curl_strnequal(value, "+APOP", ptr - value)) { pop3c->preftype = POP3_TYPE_APOP; pop3c->sasl.prefmech = SASL_AUTH_NONE; result = CURLE_OK; diff --git a/vendor/curl/lib/progress.c b/vendor/curl/lib/progress.c index 8e6d98f0d98..1a3f4334ca9 100644 --- a/vendor/curl/lib/progress.c +++ b/vendor/curl/lib/progress.c @@ -44,18 +44,18 @@ static void time2str(char *r, curl_off_t seconds) strcpy(r, "--:--:--"); return; } - h = seconds / CURL_OFF_T_C(3600); - if(h <= CURL_OFF_T_C(99)) { - curl_off_t m = (seconds - (h*CURL_OFF_T_C(3600))) / CURL_OFF_T_C(60); - curl_off_t s = (seconds - (h*CURL_OFF_T_C(3600))) - (m*CURL_OFF_T_C(60)); + h = seconds / 3600; + if(h <= 99) { + curl_off_t m = (seconds - (h * 3600)) / 60; + curl_off_t s = (seconds - (h * 3600)) - (m * 60); msnprintf(r, 9, "%2" FMT_OFF_T ":%02" FMT_OFF_T ":%02" FMT_OFF_T, h, m, s); } else { /* this equals to more than 99 hours, switch to a more suitable output format to fit within the limits. */ - curl_off_t d = seconds / CURL_OFF_T_C(86400); - h = (seconds - (d*CURL_OFF_T_C(86400))) / CURL_OFF_T_C(3600); - if(d <= CURL_OFF_T_C(999)) + curl_off_t d = seconds / 86400; + h = (seconds - (d * 86400)) / 3600; + if(d <= 999) msnprintf(r, 9, "%3" FMT_OFF_T "d %02" FMT_OFF_T "h", d, h); else msnprintf(r, 9, "%7" FMT_OFF_T "d", d); @@ -67,39 +67,39 @@ static void time2str(char *r, curl_off_t seconds) Add suffix k, M, G when suitable... */ static char *max5data(curl_off_t bytes, char *max5) { -#define ONE_KILOBYTE CURL_OFF_T_C(1024) -#define ONE_MEGABYTE (CURL_OFF_T_C(1024) * ONE_KILOBYTE) -#define ONE_GIGABYTE (CURL_OFF_T_C(1024) * ONE_MEGABYTE) -#define ONE_TERABYTE (CURL_OFF_T_C(1024) * ONE_GIGABYTE) -#define ONE_PETABYTE (CURL_OFF_T_C(1024) * ONE_TERABYTE) +#define ONE_KILOBYTE (curl_off_t)1024 +#define ONE_MEGABYTE (1024 * ONE_KILOBYTE) +#define ONE_GIGABYTE (1024 * ONE_MEGABYTE) +#define ONE_TERABYTE (1024 * ONE_GIGABYTE) +#define ONE_PETABYTE (1024 * ONE_TERABYTE) - if(bytes < CURL_OFF_T_C(100000)) + if(bytes < 100000) msnprintf(max5, 6, "%5" FMT_OFF_T, bytes); - else if(bytes < CURL_OFF_T_C(10000) * ONE_KILOBYTE) + else if(bytes < 10000 * ONE_KILOBYTE) msnprintf(max5, 6, "%4" FMT_OFF_T "k", bytes/ONE_KILOBYTE); - else if(bytes < CURL_OFF_T_C(100) * ONE_MEGABYTE) + else if(bytes < 100 * ONE_MEGABYTE) /* 'XX.XM' is good as long as we are less than 100 megs */ msnprintf(max5, 6, "%2" FMT_OFF_T ".%0" FMT_OFF_T "M", bytes/ONE_MEGABYTE, - (bytes%ONE_MEGABYTE) / (ONE_MEGABYTE/CURL_OFF_T_C(10)) ); + (bytes%ONE_MEGABYTE) / (ONE_MEGABYTE/10) ); - else if(bytes < CURL_OFF_T_C(10000) * ONE_MEGABYTE) + else if(bytes < 10000 * ONE_MEGABYTE) /* 'XXXXM' is good until we are at 10000MB or above */ msnprintf(max5, 6, "%4" FMT_OFF_T "M", bytes/ONE_MEGABYTE); - else if(bytes < CURL_OFF_T_C(100) * ONE_GIGABYTE) + else if(bytes < 100 * ONE_GIGABYTE) /* 10000 MB - 100 GB, we show it as XX.XG */ msnprintf(max5, 6, "%2" FMT_OFF_T ".%0" FMT_OFF_T "G", bytes/ONE_GIGABYTE, - (bytes%ONE_GIGABYTE) / (ONE_GIGABYTE/CURL_OFF_T_C(10)) ); + (bytes%ONE_GIGABYTE) / (ONE_GIGABYTE/10) ); - else if(bytes < CURL_OFF_T_C(10000) * ONE_GIGABYTE) + else if(bytes < 10000 * ONE_GIGABYTE) /* up to 10000GB, display without decimal: XXXXG */ msnprintf(max5, 6, "%4" FMT_OFF_T "G", bytes/ONE_GIGABYTE); - else if(bytes < CURL_OFF_T_C(10000) * ONE_TERABYTE) + else if(bytes < 10000 * ONE_TERABYTE) /* up to 10000TB, display without decimal: XXXXT */ msnprintf(max5, 6, "%4" FMT_OFF_T "T", bytes/ONE_TERABYTE); @@ -296,7 +296,7 @@ timediff_t Curl_pgrsLimitWaitTime(struct pgrs_dir *d, * stay below 'limit'. */ if(size < CURL_OFF_T_MAX/1000) - minimum = (timediff_t) (CURL_OFF_T_C(1000) * size / speed_limit); + minimum = (timediff_t) (1000 * size / speed_limit); else { minimum = (timediff_t) (size / speed_limit); if(minimum < TIMEDIFF_T_MAX/1000) @@ -449,13 +449,13 @@ static bool progress_calc(struct Curl_easy *data, struct curltime now) /* Figure out the exact time for the time span */ span_ms = curlx_timediff(now, p->speeder_time[checkindex]); - if(0 == span_ms) + if(span_ms == 0) span_ms = 1; /* at least one millisecond MUST have passed */ /* Calculate the average speed the last 'span_ms' milliseconds */ amount = p->speeder[nowindex]- p->speeder[checkindex]; - if(amount > CURL_OFF_T_C(4294967) /* 0xffffffff/1000 */) + if(amount > (0xffffffff/1000)) /* the 'amount' value is bigger than would fit in 32 bits if multiplied with 1000, so we use the double math for this */ p->current_speed = (curl_off_t) @@ -463,7 +463,7 @@ static bool progress_calc(struct Curl_easy *data, struct curltime now) else /* the 'amount' value is small enough to fit within 32 bits even when multiplied with 1000 */ - p->current_speed = amount*CURL_OFF_T_C(1000)/span_ms; + p->current_speed = amount * 1000/span_ms; } else /* the first second we use the average */ @@ -482,9 +482,9 @@ struct pgrs_estimate { static curl_off_t pgrs_est_percent(curl_off_t total, curl_off_t cur) { - if(total > CURL_OFF_T_C(10000)) - return cur / (total/CURL_OFF_T_C(100)); - else if(total > CURL_OFF_T_C(0)) + if(total > 10000) + return cur / (total / 100); + else if(total > 0) return (cur*100) / total; return 0; } @@ -495,7 +495,7 @@ static void pgrs_estimates(struct pgrs_dir *d, { est->secs = 0; est->percent = 0; - if(total_known && (d->speed > CURL_OFF_T_C(0))) { + if(total_known && (d->speed > 0)) { est->secs = d->total_size / d->speed; est->percent = pgrs_est_percent(d->total_size, d->cur_size); } diff --git a/vendor/curl/lib/rand.c b/vendor/curl/lib/rand.c index c0368dd7635..a1a5e42c2bb 100644 --- a/vendor/curl/lib/rand.c +++ b/vendor/curl/lib/rand.c @@ -48,13 +48,14 @@ #ifdef _WIN32 -#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x600 && \ +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= _WIN32_WINNT_VISTA && \ !defined(CURL_WINDOWS_UWP) # define HAVE_WIN_BCRYPTGENRANDOM # include # ifdef _MSC_VER # pragma comment(lib, "bcrypt.lib") # endif + /* Offered by mingw-w64 v3+. MS SDK v7.0A+. */ # ifndef BCRYPT_USE_SYSTEM_PREFERRED_RNG # define BCRYPT_USE_SYSTEM_PREFERRED_RNG 0x00000002 # endif @@ -72,7 +73,7 @@ CURLcode Curl_win32_random(unsigned char *entropy, size_t length) { memset(entropy, 0, length); -#if defined(HAVE_WIN_BCRYPTGENRANDOM) +#ifdef HAVE_WIN_BCRYPTGENRANDOM if(BCryptGenRandom(NULL, entropy, (ULONG)length, BCRYPT_USE_SYSTEM_PREFERRED_RNG) != STATUS_SUCCESS) return CURLE_FAILED_INIT; @@ -100,11 +101,11 @@ CURLcode Curl_win32_random(unsigned char *entropy, size_t length) } #endif -#if !defined(USE_SSL) +#ifndef USE_SSL /* ---- possibly non-cryptographic version following ---- */ static CURLcode weak_random(struct Curl_easy *data, - unsigned char *entropy, - size_t length) /* always 4, size of int */ + unsigned char *entropy, + size_t length) /* always 4, size of int */ { unsigned int r; DEBUGASSERT(length == sizeof(int)); @@ -119,7 +120,7 @@ static CURLcode weak_random(struct Curl_easy *data, } #endif -#if defined(HAVE_ARC4RANDOM) +#ifdef HAVE_ARC4RANDOM (void)data; r = (unsigned int)arc4random(); memcpy(entropy, &r, length); diff --git a/vendor/curl/lib/request.c b/vendor/curl/lib/request.c index f937a7f4bfe..733e3e92947 100644 --- a/vendor/curl/lib/request.c +++ b/vendor/curl/lib/request.c @@ -62,7 +62,7 @@ CURLcode Curl_req_soft_reset(struct SingleRequest *req, req->shutdown = FALSE; req->bytecount = 0; req->writebytecount = 0; - req->header = TRUE; /* assume header */ + req->header = FALSE; req->headerline = 0; req->headerbytecount = 0; req->allheadercount = 0; @@ -153,6 +153,7 @@ void Curl_req_hard_reset(struct SingleRequest *req, struct Curl_easy *data) req->eos_written = FALSE; req->eos_read = FALSE; req->eos_sent = FALSE; + req->rewind_read = FALSE; req->upload_done = FALSE; req->upload_aborted = FALSE; req->ignorebody = FALSE; @@ -160,7 +161,6 @@ void Curl_req_hard_reset(struct SingleRequest *req, struct Curl_easy *data) req->chunk = FALSE; req->ignore_cl = FALSE; req->upload_chunky = FALSE; - req->getheader = FALSE; req->no_body = data->set.opt_no_body; req->authneg = FALSE; req->shutdown = FALSE; @@ -338,20 +338,18 @@ static CURLcode req_flush(struct Curl_easy *data) return CURLE_OK; } -static ssize_t add_from_client(void *reader_ctx, - unsigned char *buf, size_t buflen, - CURLcode *err) +static CURLcode add_from_client(void *reader_ctx, + unsigned char *buf, size_t buflen, + size_t *pnread) { struct Curl_easy *data = reader_ctx; - size_t nread; + CURLcode result; bool eos; - *err = Curl_client_read(data, (char *)buf, buflen, &nread, &eos); - if(*err) - return -1; - if(eos) + result = Curl_client_read(data, (char *)buf, buflen, pnread, &eos); + if(!result && eos) data->req.eos_read = TRUE; - return (ssize_t)nread; + return result; } static CURLcode req_send_buffer_add(struct Curl_easy *data, @@ -359,13 +357,12 @@ static CURLcode req_send_buffer_add(struct Curl_easy *data, size_t hds_len) { CURLcode result = CURLE_OK; - ssize_t n; - n = Curl_bufq_write(&data->req.sendbuf, - (const unsigned char *)buf, blen, &result); - if(n < 0) + size_t n; + result = Curl_bufq_cwrite(&data->req.sendbuf, buf, blen, &n); + if(result) return result; /* We rely on a SOFTLIMIT on sendbuf, so it can take all data in */ - DEBUGASSERT((size_t)n == blen); + DEBUGASSERT(n == blen); data->req.sendbuf_hds_len += hds_len; return CURLE_OK; } @@ -383,8 +380,14 @@ CURLcode Curl_req_send(struct Curl_easy *data, struct dynbuf *req, data->req.httpversion_sent = httpversion; buf = curlx_dyn_ptr(req); blen = curlx_dyn_len(req); - if(!Curl_creader_total_length(data)) { - /* Request without body. Try to send directly from the buf given. */ + /* if the sendbuf is empty and the request without body and + * the length to send fits info a sendbuf chunk, we send it directly. + * If `blen` is larger then `chunk_size`, we can not. Because we + * might have to retry a blocked send later from sendbuf and that + * would result in retry sends with a shrunken length. That is trouble. */ + if(Curl_bufq_is_empty(&data->req.sendbuf) && + !Curl_creader_total_length(data) && + (blen <= data->req.sendbuf.chunk_size)) { data->req.eos_read = TRUE; result = xfer_send(data, buf, blen, blen, &nwritten); if(result) @@ -435,11 +438,12 @@ CURLcode Curl_req_send_more(struct Curl_easy *data) /* Fill our send buffer if more from client can be read. */ if(!data->req.upload_aborted && !data->req.eos_read && - !(data->req.keepon & KEEP_SEND_PAUSE) && + !Curl_xfer_send_is_paused(data) && !Curl_bufq_is_full(&data->req.sendbuf)) { - ssize_t nread = Curl_bufq_sipn(&data->req.sendbuf, 0, - add_from_client, data, &result); - if(nread < 0 && result != CURLE_AGAIN) + size_t nread; + result = Curl_bufq_sipn(&data->req.sendbuf, 0, + add_from_client, data, &nread); + if(result && result != CURLE_AGAIN) return result; } diff --git a/vendor/curl/lib/request.h b/vendor/curl/lib/request.h index 74d9f534396..bce34de8ba9 100644 --- a/vendor/curl/lib/request.h +++ b/vendor/curl/lib/request.h @@ -123,7 +123,6 @@ struct SingleRequest { BIT(ignore_cl); /* ignore content-length */ BIT(upload_chunky); /* set TRUE if we are doing chunked transfer-encoding on upload */ - BIT(getheader); /* TRUE if header parsing is wanted */ BIT(no_body); /* the response has no body */ BIT(authneg); /* TRUE when the auth phase has started, which means that we are creating a request with an auth header, diff --git a/vendor/curl/lib/rtsp.c b/vendor/curl/lib/rtsp.c index ac44bec4222..dbe3e63cf31 100644 --- a/vendor/curl/lib/rtsp.c +++ b/vendor/curl/lib/rtsp.c @@ -24,7 +24,7 @@ #include "curl_setup.h" -#if !defined(CURL_DISABLE_RTSP) +#ifndef CURL_DISABLE_RTSP #include "urldata.h" #include @@ -83,8 +83,8 @@ struct RTSP { static CURLcode rtsp_do(struct Curl_easy *data, bool *done); static CURLcode rtsp_done(struct Curl_easy *data, CURLcode, bool premature); static CURLcode rtsp_connect(struct Curl_easy *data, bool *done); -static int rtsp_getsock_do(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks); +static CURLcode rtsp_do_pollset(struct Curl_easy *data, + struct easy_pollset *ps); /* * Parse and write out an RTSP response. @@ -100,6 +100,10 @@ static CURLcode rtsp_rtp_write_resp(struct Curl_easy *data, const char *buf, size_t blen, bool is_eos); +static CURLcode rtsp_rtp_write_resp_hd(struct Curl_easy *data, + const char *buf, + size_t blen, + bool is_eos); static CURLcode rtsp_setup_connection(struct Curl_easy *data, struct connectdata *conn); @@ -110,13 +114,11 @@ static unsigned int rtsp_conncheck(struct Curl_easy *data, /* this returns the socket to wait for in the DO and DOING state for the multi interface and then we are always _sending_ a request and thus we wait for the single socket to become writable only */ -static int rtsp_getsock_do(struct Curl_easy *data, struct connectdata *conn, - curl_socket_t *socks) +static CURLcode rtsp_do_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { /* write mode */ - (void)data; - socks[0] = conn->sock[FIRSTSOCKET]; - return GETSOCK_WRITESOCK(0); + return Curl_pollset_add_out(data, ps, data->conn->sock[FIRSTSOCKET]); } static @@ -137,13 +139,13 @@ const struct Curl_handler Curl_handler_rtsp = { rtsp_connect, /* connect_it */ ZERO_NULL, /* connecting */ ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - rtsp_getsock_do, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* proto_pollset */ + rtsp_do_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ ZERO_NULL, /* disconnect */ rtsp_rtp_write_resp, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ + rtsp_rtp_write_resp_hd, /* write_resp_hd */ rtsp_conncheck, /* connection_check */ ZERO_NULL, /* attach connection */ Curl_http_follow, /* follow */ @@ -372,7 +374,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done) } if(rtspreq == RTSPREQ_RECEIVE) { - Curl_xfer_setup1(data, CURL_XFER_RECV, -1, TRUE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); goto out; } @@ -638,7 +640,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done) if(result) goto out; - Curl_xfer_setup1(data, CURL_XFER_SENDRECV, -1, TRUE); + Curl_xfer_setup_sendrecv(data, FIRSTSOCKET, -1); /* issue the request */ result = Curl_req_send(data, &req_buffer, httpversion); @@ -937,6 +939,14 @@ static CURLcode rtsp_rtp_write_resp(struct Curl_easy *data, return result; } +static CURLcode rtsp_rtp_write_resp_hd(struct Curl_easy *data, + const char *buf, + size_t blen, + bool is_eos) +{ + return rtsp_rtp_write_resp(data, buf, blen, is_eos); +} + static CURLcode rtp_client_write(struct Curl_easy *data, const char *ptr, size_t len) { diff --git a/vendor/curl/lib/select.c b/vendor/curl/lib/select.c index ee239b73217..af78cb836b0 100644 --- a/vendor/curl/lib/select.c +++ b/vendor/curl/lib/select.c @@ -36,75 +36,20 @@ #include #endif -#ifdef MSDOS -#include /* delay() */ -#endif - #include #include "urldata.h" #include "connect.h" #include "select.h" +#include "curl_trc.h" #include "curlx/timediff.h" +#include "curlx/wait.h" #include "curlx/warnless.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" #include "memdebug.h" -/* - * Internal function used for waiting a specific amount of ms in - * Curl_socket_check() and Curl_poll() when no file descriptor is provided to - * wait on, just being used to delay execution. Winsock select() and poll() - * timeout mechanisms need a valid socket descriptor in a not null file - * descriptor set to work. Waiting indefinitely with this function is not - * allowed, a zero or negative timeout value will return immediately. Timeout - * resolution, accuracy, as well as maximum supported value is system - * dependent, neither factor is a critical issue for the intended use of this - * function in the library. - * - * Return values: - * -1 = system call error, or invalid timeout value - * 0 = specified timeout has elapsed, or interrupted - */ -int Curl_wait_ms(timediff_t timeout_ms) -{ - int r = 0; - - if(!timeout_ms) - return 0; - if(timeout_ms < 0) { - SET_SOCKERRNO(SOCKEINVAL); - return -1; - } -#if defined(MSDOS) - delay((unsigned int)timeout_ms); -#elif defined(_WIN32) - /* prevent overflow, timeout_ms is typecast to ULONG/DWORD. */ -#if TIMEDIFF_T_MAX >= ULONG_MAX - if(timeout_ms >= ULONG_MAX) - timeout_ms = ULONG_MAX-1; - /* do not use ULONG_MAX, because that is equal to INFINITE */ -#endif - Sleep((DWORD)timeout_ms); -#else - /* avoid using poll() for this since it behaves incorrectly with no sockets - on Apple operating systems */ - { - struct timeval pending_tv; - r = select(0, NULL, NULL, NULL, curlx_mstotv(&pending_tv, timeout_ms)); - } -#endif /* _WIN32 */ - if(r) { - if((r == -1) && (SOCKERRNO == SOCKEINTR)) - /* make EINTR from select or poll not a "lethal" error */ - r = 0; - else - r = -1; - } - return r; -} - #ifndef HAVE_POLL /* * This is a wrapper around select() to aid in Windows compatibility. A @@ -132,7 +77,7 @@ static int our_select(curl_socket_t maxfd, /* highest socket number */ (!fds_write || fds_write->fd_count == 0) && (!fds_err || fds_err->fd_count == 0)) { /* no sockets, just wait */ - return Curl_wait_ms(timeout_ms); + return curlx_wait_ms(timeout_ms); } #endif @@ -194,7 +139,7 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */ if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) && (writefd == CURL_SOCKET_BAD)) { /* no sockets, just wait */ - return Curl_wait_ms(timeout_ms); + return curlx_wait_ms(timeout_ms); } /* Avoid initial timestamp, avoid curlx_now() call, when elapsed @@ -289,7 +234,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms) } if(fds_none) { /* no sockets, just wait */ - return Curl_wait_ms(timeout_ms); + return curlx_wait_ms(timeout_ms); } /* Avoid initial timestamp, avoid curlx_now() call, when elapsed @@ -479,7 +424,7 @@ CURLcode Curl_pollfds_add_ps(struct curl_pollfds *cpfds, DEBUGASSERT(cpfds); DEBUGASSERT(ps); - for(i = 0; i < ps->num; i++) { + for(i = 0; i < ps->n; i++) { short events = 0; if(ps->actions[i] & CURL_POLL_IN) events |= POLLIN; @@ -537,7 +482,7 @@ unsigned int Curl_waitfds_add_ps(struct Curl_waitfds *cwfds, DEBUGASSERT(cwfds); DEBUGASSERT(ps); - for(i = 0; i < ps->num; i++) { + for(i = 0; i < ps->n; i++) { short events = 0; if(ps->actions[i] & CURL_POLL_IN) events |= CURL_WAIT_POLLIN; @@ -548,3 +493,233 @@ unsigned int Curl_waitfds_add_ps(struct Curl_waitfds *cwfds, } return need; } + +void Curl_pollset_reset(struct easy_pollset *ps) +{ + unsigned int i; + ps->n = 0; +#ifdef DEBUGBUILD + DEBUGASSERT(ps->init == CURL_EASY_POLLSET_MAGIC); +#endif + DEBUGASSERT(ps->count); + for(i = 0; i < ps->count; i++) + ps->sockets[i] = CURL_SOCKET_BAD; + memset(ps->actions, 0, ps->count * sizeof(ps->actions[0])); +} + +void Curl_pollset_init(struct easy_pollset *ps) +{ +#ifdef DEBUGBUILD + ps->init = CURL_EASY_POLLSET_MAGIC; +#endif + ps->sockets = ps->def_sockets; + ps->actions = ps->def_actions; + ps->count = CURL_ARRAYSIZE(ps->def_sockets); + ps->n = 0; + Curl_pollset_reset(ps); +} + +struct easy_pollset *Curl_pollset_create(void) +{ + struct easy_pollset *ps = calloc(1, sizeof(*ps)); + if(ps) + Curl_pollset_init(ps); + return ps; +} + +void Curl_pollset_cleanup(struct easy_pollset *ps) +{ +#ifdef DEBUGBUILD + DEBUGASSERT(ps->init == CURL_EASY_POLLSET_MAGIC); +#endif + if(ps->sockets != ps->def_sockets) { + free(ps->sockets); + ps->sockets = ps->def_sockets; + } + if(ps->actions != ps->def_actions) { + free(ps->actions); + ps->actions = ps->def_actions; + } + ps->count = CURL_ARRAYSIZE(ps->def_sockets); + Curl_pollset_reset(ps); +} + +void Curl_pollset_move(struct easy_pollset *to, struct easy_pollset *from) +{ + Curl_pollset_cleanup(to); /* deallocate anything in to */ + if(from->sockets != from->def_sockets) { + DEBUGASSERT(from->actions != from->def_actions); + to->sockets = from->sockets; + to->actions = from->actions; + to->count = from->count; + to->n = from->n; + Curl_pollset_init(from); + } + else { + DEBUGASSERT(to->sockets == to->def_sockets); + DEBUGASSERT(to->actions == to->def_actions); + memcpy(to->sockets, from->sockets, to->count * sizeof(to->sockets[0])); + memcpy(to->actions, from->actions, to->count * sizeof(to->actions[0])); + to->n = from->n; + Curl_pollset_init(from); + } +} + +/** + * + */ +CURLcode Curl_pollset_change(struct Curl_easy *data, + struct easy_pollset *ps, curl_socket_t sock, + int add_flags, int remove_flags) +{ + unsigned int i; + +#ifdef DEBUGBUILD + DEBUGASSERT(ps->init == CURL_EASY_POLLSET_MAGIC); +#endif + + (void)data; + DEBUGASSERT(VALID_SOCK(sock)); + if(!VALID_SOCK(sock)) + return CURLE_BAD_FUNCTION_ARGUMENT; + + DEBUGASSERT(add_flags <= (CURL_POLL_IN|CURL_POLL_OUT)); + DEBUGASSERT(remove_flags <= (CURL_POLL_IN|CURL_POLL_OUT)); + DEBUGASSERT((add_flags&remove_flags) == 0); /* no overlap */ + for(i = 0; i < ps->n; ++i) { + if(ps->sockets[i] == sock) { + ps->actions[i] &= (unsigned char)(~remove_flags); + ps->actions[i] |= (unsigned char)add_flags; + /* all gone? remove socket */ + if(!ps->actions[i]) { + if((i + 1) < ps->n) { + memmove(&ps->sockets[i], &ps->sockets[i + 1], + (ps->n - (i + 1)) * sizeof(ps->sockets[0])); + memmove(&ps->actions[i], &ps->actions[i + 1], + (ps->n - (i + 1)) * sizeof(ps->actions[0])); + } + --ps->n; + } + return CURLE_OK; + } + } + /* not present */ + if(add_flags) { + if(i >= ps->count) { /* need to grow */ + unsigned int new_count = CURLMAX(ps->count * 2, 8); + curl_socket_t *nsockets; + unsigned char *nactions; + + CURL_TRC_M(data, "growing pollset capacity from %u to %u", + ps->count, new_count); + if(new_count <= ps->count) + return CURLE_OUT_OF_MEMORY; + nsockets = calloc(new_count, sizeof(nsockets[0])); + if(!nsockets) + return CURLE_OUT_OF_MEMORY; + nactions = calloc(new_count, sizeof(nactions[0])); + if(!nactions) { + free(nsockets); + return CURLE_OUT_OF_MEMORY; + } + memcpy(nsockets, ps->sockets, ps->count * sizeof(ps->sockets[0])); + memcpy(nactions, ps->actions, ps->count * sizeof(ps->actions[0])); + if(ps->sockets != ps->def_sockets) + free(ps->sockets); + ps->sockets = nsockets; + if(ps->actions != ps->def_actions) + free(ps->actions); + ps->actions = nactions; + ps->count = new_count; + } + DEBUGASSERT(i < ps->count); + if(i < ps->count) { + ps->sockets[i] = sock; + ps->actions[i] = (unsigned char)add_flags; + ps->n = i + 1; + } + } + return CURLE_OK; +} + +CURLcode Curl_pollset_set(struct Curl_easy *data, + struct easy_pollset *ps, curl_socket_t sock, + bool do_in, bool do_out) +{ + return Curl_pollset_change(data, ps, sock, + (do_in ? CURL_POLL_IN : 0)| + (do_out ? CURL_POLL_OUT : 0), + (!do_in ? CURL_POLL_IN : 0)| + (!do_out ? CURL_POLL_OUT : 0)); +} + +int Curl_pollset_poll(struct Curl_easy *data, + struct easy_pollset *ps, + timediff_t timeout_ms) +{ + struct pollfd *pfds; + unsigned int i, npfds; + int result; + + (void)data; + DEBUGASSERT(data); + DEBUGASSERT(data->conn); + + if(!ps->n) + return curlx_wait_ms(timeout_ms); + + pfds = calloc(ps->n, sizeof(*pfds)); + if(!pfds) + return -1; + + npfds = 0; + for(i = 0; i < ps->n; ++i) { + short events = 0; + if(ps->actions[i] & CURL_POLL_IN) { + events |= POLLIN; + } + if(ps->actions[i] & CURL_POLL_OUT) { + events |= POLLOUT; + } + if(events) { + pfds[npfds].fd = ps->sockets[i]; + pfds[npfds].events = events; + ++npfds; + } + } + + result = Curl_poll(pfds, npfds, timeout_ms); + free(pfds); + return result; +} + +void Curl_pollset_check(struct Curl_easy *data, + struct easy_pollset *ps, curl_socket_t sock, + bool *pwant_read, bool *pwant_write) +{ + unsigned int i; + + (void)data; + DEBUGASSERT(VALID_SOCK(sock)); + for(i = 0; i < ps->n; ++i) { + if(ps->sockets[i] == sock) { + *pwant_read = !!(ps->actions[i] & CURL_POLL_IN); + *pwant_write = !!(ps->actions[i] & CURL_POLL_OUT); + return; + } + } + *pwant_read = *pwant_write = FALSE; +} + +bool Curl_pollset_want_read(struct Curl_easy *data, + struct easy_pollset *ps, + curl_socket_t sock) +{ + unsigned int i; + (void)data; + for(i = 0; i < ps->n; ++i) { + if((ps->sockets[i] == sock) && (ps->actions[i] & CURL_POLL_IN)) + return TRUE; + } + return FALSE; +} diff --git a/vendor/curl/lib/select.h b/vendor/curl/lib/select.h index 10968fab7f8..47cdd31267f 100644 --- a/vendor/curl/lib/select.h +++ b/vendor/curl/lib/select.h @@ -82,7 +82,6 @@ int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2, Curl_socket_check(CURL_SOCKET_BAD, CURL_SOCKET_BAD, x, z) int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms); -int Curl_wait_ms(timediff_t timeout_ms); /* With Winsock the valid range is [0..INVALID_SOCKET-1] according to @@ -111,6 +110,90 @@ int Curl_wait_ms(timediff_t timeout_ms); } while(0) #endif + +/* Keep the sockets to poll for an easy handle. + * `actions` are bitmaps of CURL_POLL_IN and CURL_POLL_OUT. + * Starts with small capacity, grows on demand. + */ +#define EZ_POLLSET_DEF_COUNT 2 + +struct easy_pollset { + curl_socket_t *sockets; + unsigned char *actions; + unsigned int n; + unsigned int count; +#ifdef DEBUGBUILD + int init; +#endif + curl_socket_t def_sockets[EZ_POLLSET_DEF_COUNT]; + unsigned char def_actions[EZ_POLLSET_DEF_COUNT]; +}; + +#ifdef DEBUGBUILD +#define CURL_EASY_POLLSET_MAGIC 0x7a657370 +#endif + + +/* allocate and initialise */ +struct easy_pollset *Curl_pollset_create(void); + +/* Initialize before first use */ +void Curl_pollset_init(struct easy_pollset *ps); +/* Free any allocated resources */ +void Curl_pollset_cleanup(struct easy_pollset *ps); +/* Reset to an empty pollset */ +void Curl_pollset_reset(struct easy_pollset *ps); +/* Move pollset from to pollset to, replacing all in to, + * leaving from empty. */ +void Curl_pollset_move(struct easy_pollset *to, struct easy_pollset *from); + +/* Change the poll flags (CURL_POLL_IN/CURL_POLL_OUT) to the poll set for + * socket `sock`. If the socket is not already part of the poll set, it + * will be added. + * If the socket is present and all poll flags are cleared, it will be removed. + */ +CURLcode Curl_pollset_change(struct Curl_easy *data, + struct easy_pollset *ps, curl_socket_t sock, + int add_flags, int remove_flags); + +CURLcode Curl_pollset_set(struct Curl_easy *data, + struct easy_pollset *ps, curl_socket_t sock, + bool do_in, bool do_out); + +#define Curl_pollset_add_in(data, ps, sock) \ + Curl_pollset_change((data), (ps), (sock), CURL_POLL_IN, 0) +#define Curl_pollset_add_out(data, ps, sock) \ + Curl_pollset_change((data), (ps), (sock), CURL_POLL_OUT, 0) +#define Curl_pollset_add_inout(data, ps, sock) \ + Curl_pollset_change((data), (ps), (sock), \ + CURL_POLL_IN|CURL_POLL_OUT, 0) +#define Curl_pollset_set_in_only(data, ps, sock) \ + Curl_pollset_change((data), (ps), (sock), \ + CURL_POLL_IN, CURL_POLL_OUT) +#define Curl_pollset_set_out_only(data, ps, sock) \ + Curl_pollset_change((data), (ps), (sock), \ + CURL_POLL_OUT, CURL_POLL_IN) + +/* return < = on error, 0 on timeout or how many sockets are ready */ +int Curl_pollset_poll(struct Curl_easy *data, + struct easy_pollset *ps, + timediff_t timeout_ms); + +/** + * Check if the pollset, as is, wants to read and/or write regarding + * the given socket. + */ +void Curl_pollset_check(struct Curl_easy *data, + struct easy_pollset *ps, curl_socket_t sock, + bool *pwant_read, bool *pwant_write); + +/** + * Return TRUE if the pollset contains socket with CURL_POLL_IN. + */ +bool Curl_pollset_want_read(struct Curl_easy *data, + struct easy_pollset *ps, + curl_socket_t sock); + struct curl_pollfds { struct pollfd *pfds; unsigned int n; diff --git a/vendor/curl/lib/sendf.c b/vendor/curl/lib/sendf.c index feb4598b063..6bd4b1bfbaf 100644 --- a/vendor/curl/lib/sendf.c +++ b/vendor/curl/lib/sendf.c @@ -38,6 +38,7 @@ #include "urldata.h" #include "sendf.h" +#include "transfer.h" #include "cfilters.h" #include "connect.h" #include "content_encoding.h" @@ -176,8 +177,8 @@ void Curl_creader_set_rewind(struct Curl_easy *data, bool enable) /* Write data using an unencoding writer stack. */ CURLcode Curl_cwriter_write(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - const char *buf, size_t nbytes) + struct Curl_cwriter *writer, int type, + const char *buf, size_t nbytes) { if(!writer) return CURLE_WRITE_ERROR; @@ -202,8 +203,8 @@ CURLcode Curl_cwriter_def_write(struct Curl_easy *data, void Curl_cwriter_def_close(struct Curl_easy *data, struct Curl_cwriter *writer) { - (void) data; - (void) writer; + (void)data; + (void)writer; } static size_t get_max_body_write_len(struct Curl_easy *data, curl_off_t limit) @@ -280,7 +281,7 @@ static CURLcode cw_download_write(struct Curl_easy *data, * This gives deterministic BODY writes on varying buffer receive * lengths. */ nwrite = nbytes; - if(-1 != data->req.maxdownload) { + if(data->req.maxdownload != -1) { size_t wmax = get_max_body_write_len(data, data->req.maxdownload); if(nwrite > wmax) { excess_len = nbytes - wmax; @@ -376,9 +377,9 @@ static const struct Curl_cwtype cw_raw = { /* Create an unencoding writer stage using the given handler. */ CURLcode Curl_cwriter_create(struct Curl_cwriter **pwriter, - struct Curl_easy *data, - const struct Curl_cwtype *cwt, - Curl_cwriter_phase phase) + struct Curl_easy *data, + const struct Curl_cwtype *cwt, + Curl_cwriter_phase phase) { struct Curl_cwriter *writer = NULL; CURLcode result = CURLE_OUT_OF_MEMORY; @@ -403,7 +404,7 @@ CURLcode Curl_cwriter_create(struct Curl_cwriter **pwriter, } void Curl_cwriter_free(struct Curl_easy *data, - struct Curl_cwriter *writer) + struct Curl_cwriter *writer) { if(writer) { writer->cwt->do_close(data, writer); @@ -660,6 +661,7 @@ static CURLcode cr_in_read(struct Curl_easy *data, size_t *pnread, bool *peos) { struct cr_in_ctx *ctx = reader->ctx; + CURLcode result = CURLE_OK; size_t nread; ctx->is_paused = FALSE; @@ -697,7 +699,8 @@ static CURLcode cr_in_read(struct Curl_easy *data, failf(data, "client read function EOF fail, " "only %"FMT_OFF_T"/%"FMT_OFF_T " of needed bytes read", ctx->read_len, ctx->total_len); - return CURLE_READ_ERROR; + result = CURLE_READ_ERROR; + break; } *pnread = 0; *peos = TRUE; @@ -710,7 +713,8 @@ static CURLcode cr_in_read(struct Curl_easy *data, *peos = FALSE; ctx->errored = TRUE; ctx->error_result = CURLE_ABORTED_BY_CALLBACK; - return CURLE_ABORTED_BY_CALLBACK; + result = CURLE_ABORTED_BY_CALLBACK; + break; case CURL_READFUNC_PAUSE: if(data->conn->handler->flags & PROTOPT_NONETWORK) { @@ -718,14 +722,15 @@ static CURLcode cr_in_read(struct Curl_easy *data, actually only FILE:// just now, and it cannot pause since the transfer is not done using the "normal" procedure. */ failf(data, "Read callback asked for PAUSE when not supported"); - return CURLE_READ_ERROR; + result = CURLE_READ_ERROR; + break; } /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */ CURL_TRC_READ(data, "cr_in_read, callback returned CURL_READFUNC_PAUSE"); ctx->is_paused = TRUE; - data->req.keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */ *pnread = 0; *peos = FALSE; + result = Curl_xfer_pause_send(data, TRUE); break; /* nothing was read */ default: @@ -736,7 +741,8 @@ static CURLcode cr_in_read(struct Curl_easy *data, *peos = FALSE; ctx->errored = TRUE; ctx->error_result = CURLE_READ_ERROR; - return CURLE_READ_ERROR; + result = CURLE_READ_ERROR; + break; } ctx->read_len += nread; if(ctx->total_len >= 0) @@ -747,9 +753,9 @@ static CURLcode cr_in_read(struct Curl_easy *data, } CURL_TRC_READ(data, "cr_in_read(len=%zu, total=%"FMT_OFF_T ", read=%"FMT_OFF_T") -> %d, nread=%zu, eos=%d", - blen, ctx->total_len, ctx->read_len, CURLE_OK, + blen, ctx->total_len, ctx->read_len, result, *pnread, *peos); - return CURLE_OK; + return result; } static bool cr_in_needs_rewind(struct Curl_easy *data, @@ -873,7 +879,7 @@ static CURLcode cr_in_rewind(struct Curl_easy *data, int err = fseek(data->state.in, 0, SEEK_SET); CURL_TRC_READ(data, "cr_in, rewind via fseek -> %d(%d)", (int)err, (int)errno); - if(-1 != err) + if(err != -1) /* successful rewind */ return CURLE_OK; } @@ -1362,7 +1368,7 @@ static const struct Curl_crtype cr_buf = { }; CURLcode Curl_creader_set_buf(struct Curl_easy *data, - const char *buf, size_t blen) + const char *buf, size_t blen) { CURLcode result; struct Curl_creader *r; diff --git a/vendor/curl/lib/setopt.c b/vendor/curl/lib/setopt.c index d5ddf6d0c26..16841773823 100644 --- a/vendor/curl/lib/setopt.c +++ b/vendor/curl/lib/setopt.c @@ -60,6 +60,34 @@ #include "curl_memory.h" #include "memdebug.h" +static CURLcode setopt_set_timeout_sec(timediff_t *ptimeout_ms, long secs) +{ + if(secs < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; +#if LONG_MAX > (TIMEDIFF_T_MAX/1000) + if(secs > (TIMEDIFF_T_MAX/1000)) { + *ptimeout_ms = TIMEDIFF_T_MAX; + return CURLE_OK; + } +#endif + *ptimeout_ms = (timediff_t)secs * 1000; + return CURLE_OK; +} + +static CURLcode setopt_set_timeout_ms(timediff_t *ptimeout_ms, long ms) +{ + if(ms < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; +#if LONG_MAX > TIMEDIFF_T_MAX + if(ms > TIMEDIFF_T_MAX) { + *ptimeout_ms = TIMEDIFF_T_MAX; + return CURLE_OK; + } +#endif + *ptimeout_ms = (timediff_t)ms; + return CURLE_OK; +} + CURLcode Curl_setstropt(char **charp, const char *s) { /* Release the previous storage at `charp' and replace by a dynamic storage @@ -211,6 +239,7 @@ static CURLcode protocol2num(const char *str, curl_prot_t *val) return CURLE_OK; } +#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_PROXY) static CURLcode httpauth(struct Curl_easy *data, bool proxy, unsigned long auth) { @@ -255,6 +284,7 @@ static CURLcode httpauth(struct Curl_easy *data, bool proxy, data->set.httpauth = auth; return CURLE_OK; } +#endif /* !CURL_DISABLE_HTTP || !CURL_DISABLE_PROXY */ #ifndef CURL_DISABLE_HTTP static CURLcode setopt_HTTP_VERSION(struct Curl_easy *data, long arg) @@ -296,8 +326,8 @@ static CURLcode setopt_HTTP_VERSION(struct Curl_easy *data, long arg) #endif /* ! CURL_DISABLE_HTTP */ #ifdef USE_SSL -static CURLcode setopt_SSLVERSION(struct Curl_easy *data, CURLoption option, - long arg) +CURLcode Curl_setopt_SSLVERSION(struct Curl_easy *data, CURLoption option, + long arg) { /* * Set explicit SSL version to try to connect with, as some SSL @@ -322,6 +352,8 @@ static CURLcode setopt_SSLVERSION(struct Curl_easy *data, CURLoption option, version_max < CURL_SSLVERSION_MAX_NONE || version_max >= CURL_SSLVERSION_MAX_LAST) return CURLE_BAD_FUNCTION_ARGUMENT; + if(version == CURL_SSLVERSION_DEFAULT) + version = CURL_SSLVERSION_TLSv1_2; primary->version = (unsigned char)version; primary->version_max = (unsigned int)version_max; @@ -407,67 +439,38 @@ static void set_ssl_options(struct ssl_config_data *ssl, } #endif -static CURLcode setopt_long(struct Curl_easy *data, CURLoption option, - long arg) +static CURLcode setopt_bool(struct Curl_easy *data, CURLoption option, + long arg, bool *set) { - bool enabled = (0 != arg); - unsigned long uarg = (unsigned long)arg; + bool enabled = !!arg; + struct UserDefined *s = &data->set; switch(option) { - case CURLOPT_DNS_CACHE_TIMEOUT: - if(arg < -1) - return CURLE_BAD_FUNCTION_ARGUMENT; - else if(arg > INT_MAX) - arg = INT_MAX; - - data->set.dns_cache_timeout = (int)arg; - break; - case CURLOPT_CA_CACHE_TIMEOUT: - if(Curl_ssl_supports(data, SSLSUPP_CA_CACHE)) { - if(arg < -1) - return CURLE_BAD_FUNCTION_ARGUMENT; - else if(arg > INT_MAX) - arg = INT_MAX; - - data->set.general_ssl.ca_cache_timeout = (int)arg; - } - else - return CURLE_NOT_BUILT_IN; - break; - case CURLOPT_MAXCONNECTS: - /* - * Set the absolute number of maximum simultaneous alive connection that - * libcurl is allowed to have. - */ - if(uarg > UINT_MAX) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.maxconnects = (unsigned int)uarg; - break; case CURLOPT_FORBID_REUSE: /* * When this transfer is done, it must not be left to be reused by a * subsequent transfer but shall be closed immediately. */ - data->set.reuse_forbid = enabled; + s->reuse_forbid = enabled; break; case CURLOPT_FRESH_CONNECT: /* * This transfer shall not use a previously cached connection but * should be made with a fresh new connect! */ - data->set.reuse_fresh = enabled; + s->reuse_fresh = enabled; break; case CURLOPT_VERBOSE: /* * Verbose means infof() calls that give a lot of information about * the connection and transfer procedures as well as internal choices. */ - data->set.verbose = enabled; + s->verbose = enabled; break; case CURLOPT_HEADER: /* * Set to include the header in the general data output stream. */ - data->set.include_header = enabled; + s->include_header = enabled; break; case CURLOPT_NOPROGRESS: /* @@ -479,13 +482,13 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option, /* * Do not include the body part in the output data stream. */ - data->set.opt_no_body = enabled; + s->opt_no_body = enabled; #ifndef CURL_DISABLE_HTTP - if(data->set.opt_no_body) + if(s->opt_no_body) /* in HTTP lingo, no body means using the HEAD request... */ - data->set.method = HTTPREQ_HEAD; - else if(data->set.method == HTTPREQ_HEAD) - data->set.method = HTTPREQ_GET; + s->method = HTTPREQ_HEAD; + else if(s->method == HTTPREQ_HEAD) + s->method = HTTPREQ_GET; #endif break; case CURLOPT_FAILONERROR: @@ -493,10 +496,10 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option, * Do not output the >=400 error code HTML-page, but instead only * return error. */ - data->set.http_fail_on_error = enabled; + s->http_fail_on_error = enabled; break; case CURLOPT_KEEP_SENDING_ON_ERROR: - data->set.http_keep_sending_on_error = enabled; + s->http_keep_sending_on_error = enabled; break; case CURLOPT_UPLOAD: case CURLOPT_PUT: @@ -504,125 +507,27 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option, * We want to sent data to the remote host. If this is HTTP, that equals * using the PUT request. */ - if(arg) { + if(enabled) { /* If this is HTTP, PUT is what's needed to "upload" */ - data->set.method = HTTPREQ_PUT; - data->set.opt_no_body = FALSE; /* this is implied */ + s->method = HTTPREQ_PUT; + s->opt_no_body = FALSE; /* this is implied */ } else /* In HTTP, the opposite of upload is GET (unless NOBODY is true as then this can be changed to HEAD later on) */ - data->set.method = HTTPREQ_GET; + s->method = HTTPREQ_GET; break; case CURLOPT_FILETIME: /* * Try to get the file time of the remote document. The time will * later (possibly) become available using curl_easy_getinfo(). */ - data->set.get_filetime = enabled; - break; - case CURLOPT_SERVER_RESPONSE_TIMEOUT: - /* - * Option that specifies how quickly a server response must be obtained - * before it is considered failure. For pingpong protocols. - */ - if((arg >= 0) && (arg <= (INT_MAX/1000))) - data->set.server_response_timeout = (unsigned int)arg * 1000; - else - return CURLE_BAD_FUNCTION_ARGUMENT; - break; - case CURLOPT_SERVER_RESPONSE_TIMEOUT_MS: - /* - * Option that specifies how quickly a server response must be obtained - * before it is considered failure. For pingpong protocols. - */ - if((arg >= 0) && (arg <= INT_MAX)) - data->set.server_response_timeout = (unsigned int)arg; - else - return CURLE_BAD_FUNCTION_ARGUMENT; - break; -#ifndef CURL_DISABLE_TFTP - case CURLOPT_TFTP_NO_OPTIONS: - /* - * Option that prevents libcurl from sending TFTP option requests to the - * server. - */ - data->set.tftp_no_options = enabled; - break; - case CURLOPT_TFTP_BLKSIZE: - /* - * TFTP option that specifies the block size to use for data transmission. - */ - if(arg < TFTP_BLKSIZE_MIN) - arg = 512; - else if(arg > TFTP_BLKSIZE_MAX) - arg = TFTP_BLKSIZE_MAX; - data->set.tftp_blksize = arg; - break; -#endif -#ifndef CURL_DISABLE_NETRC - case CURLOPT_NETRC: - /* - * Parse the $HOME/.netrc file - */ - if((arg < CURL_NETRC_IGNORED) || (arg >= CURL_NETRC_LAST)) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.use_netrc = (unsigned char)arg; - break; -#endif - case CURLOPT_TRANSFERTEXT: - /* - * This option was previously named 'FTPASCII'. Renamed to work with - * more protocols than merely FTP. - * - * Transfer using ASCII (instead of BINARY). - */ - data->set.prefer_ascii = enabled; - break; - case CURLOPT_TIMECONDITION: - /* - * Set HTTP time condition. This must be one of the defines in the - * curl/curl.h header file. - */ - if((arg < CURL_TIMECOND_NONE) || (arg >= CURL_TIMECOND_LAST)) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.timecondition = (unsigned char)arg; - break; - case CURLOPT_TIMEVALUE: - /* - * This is the value to compare with the remote document with the - * method set with CURLOPT_TIMECONDITION - */ - data->set.timevalue = (time_t)arg; - break; - case CURLOPT_SSLVERSION: -#ifndef CURL_DISABLE_PROXY - case CURLOPT_PROXY_SSLVERSION: -#endif -#ifdef USE_SSL - return setopt_SSLVERSION(data, option, arg); -#else - return CURLE_NOT_BUILT_IN; -#endif - - case CURLOPT_POSTFIELDSIZE: - /* - * The size of the POSTFIELD data to prevent libcurl to do strlen() to - * figure it out. Enables binary posts. - */ - if(arg < -1) - return CURLE_BAD_FUNCTION_ARGUMENT; - - if(data->set.postfieldsize < arg && - data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { - /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ - Curl_safefree(data->set.str[STRING_COPYPOSTFIELDS]); - data->set.postfields = NULL; - } - - data->set.postfieldsize = arg; + s->get_filetime = enabled; break; #ifndef CURL_DISABLE_HTTP + case CURLOPT_HTTP09_ALLOWED: + s->http09_allowed = enabled; + break; #if !defined(CURL_DISABLE_COOKIES) case CURLOPT_COOKIESESSION: /* @@ -631,171 +536,80 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option, * cookies that are marked as being session cookies, as they belong to a * previous session. */ - data->set.cookiesession = enabled; + s->cookiesession = enabled; break; #endif case CURLOPT_AUTOREFERER: /* * Switch on automatic referer that gets set if curl follows locations. */ - data->set.http_auto_referer = enabled; + s->http_auto_referer = enabled; break; case CURLOPT_TRANSFER_ENCODING: - data->set.http_transfer_encoding = enabled; - break; - - case CURLOPT_FOLLOWLOCATION: - /* - * Follow Location: header hints on an HTTP-server. - */ - if(uarg > 3) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.http_follow_mode = (unsigned char)uarg; + s->http_transfer_encoding = enabled; break; - case CURLOPT_UNRESTRICTED_AUTH: /* * Send authentication (user+password) when following locations, even when * hostname changed. */ - data->set.allow_auth_to_other_hosts = enabled; - break; - - case CURLOPT_MAXREDIRS: - /* - * The maximum amount of hops you allow curl to follow Location: - * headers. This should mostly be used to detect never-ending loops. - */ - if(arg < -1) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.maxredirs = arg; + s->allow_auth_to_other_hosts = enabled; break; - case CURLOPT_POSTREDIR: + case CURLOPT_HTTP_TRANSFER_DECODING: /* - * Set the behavior of POST when redirecting - * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302 - * CURL_REDIR_POST_301 - POST is kept as POST after 301 - * CURL_REDIR_POST_302 - POST is kept as POST after 302 - * CURL_REDIR_POST_303 - POST is kept as POST after 303 - * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303 - * other - POST is kept as POST after 301 and 302 + * disable libcurl transfer encoding is used */ - if(arg < CURL_REDIR_GET_ALL) - /* no return error on too high numbers since the bitmask could be - extended in a future */ - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.keep_post = arg & CURL_REDIR_POST_ALL; + s->http_te_skip = !enabled; /* reversed */ break; - case CURLOPT_POST: - /* Does this option serve a purpose anymore? Yes it does, when - CURLOPT_POSTFIELDS is not used and the POST data is read off the - callback! */ - if(arg) { - data->set.method = HTTPREQ_POST; - data->set.opt_no_body = FALSE; /* this is implied */ - } - else - data->set.method = HTTPREQ_GET; - break; - case CURLOPT_HEADEROPT: + case CURLOPT_HTTP_CONTENT_DECODING: /* - * Set header option. + * raw data passed to the application when content encoding is used */ - data->set.sep_headers = !!(arg & CURLHEADER_SEPARATE); + s->http_ce_skip = !enabled; /* reversed */ break; - case CURLOPT_HTTPAUTH: - return httpauth(data, FALSE, uarg); case CURLOPT_HTTPGET: /* * Set to force us do HTTP GET */ if(enabled) { - data->set.method = HTTPREQ_GET; - data->set.opt_no_body = FALSE; /* this is implied */ + s->method = HTTPREQ_GET; + s->opt_no_body = FALSE; /* this is implied */ } break; - - case CURLOPT_HTTP_VERSION: - return setopt_HTTP_VERSION(data, arg); - - case CURLOPT_EXPECT_100_TIMEOUT_MS: - /* - * Time to wait for a response to an HTTP request containing an - * Expect: 100-continue header before sending the data anyway. - */ - if(arg < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.expect_100_timeout = arg; - break; - - case CURLOPT_HTTP09_ALLOWED: - data->set.http09_allowed = enabled; + case CURLOPT_POST: + /* Does this option serve a purpose anymore? Yes it does, when + CURLOPT_POSTFIELDS is not used and the POST data is read off the + callback! */ + if(enabled) { + s->method = HTTPREQ_POST; + s->opt_no_body = FALSE; /* this is implied */ + } + else + s->method = HTTPREQ_GET; break; #endif /* ! CURL_DISABLE_HTTP */ - -#ifndef CURL_DISABLE_MIME - case CURLOPT_MIME_OPTIONS: - data->set.mime_formescape = !!(arg & CURLMIMEOPT_FORMESCAPE); - break; -#endif #ifndef CURL_DISABLE_PROXY case CURLOPT_HTTPPROXYTUNNEL: /* * Tunnel operations through the proxy instead of normal proxy use */ - data->set.tunnel_thru_httpproxy = enabled; - break; - - case CURLOPT_PROXYPORT: - /* - * Explicitly set HTTP proxy port number. - */ - if((arg < 0) || (arg > 65535)) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.proxyport = (unsigned short)arg; - break; - - case CURLOPT_PROXYAUTH: - return httpauth(data, TRUE, uarg); - - case CURLOPT_PROXYTYPE: - /* - * Set proxy type. - */ - if((arg < CURLPROXY_HTTP) || (arg > CURLPROXY_SOCKS5_HOSTNAME)) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.proxytype = (unsigned char)(curl_proxytype)arg; - break; - - case CURLOPT_PROXY_TRANSFER_MODE: - /* - * set transfer mode (;type=) when doing FTP via an HTTP proxy - */ - if(uarg > 1) - /* reserve other values for future use */ - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.proxy_transfer_mode = (bool)uarg; - break; - case CURLOPT_SOCKS5_AUTH: - if(uarg & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI)) - return CURLE_NOT_BUILT_IN; - data->set.socks5auth = (unsigned char)uarg; + s->tunnel_thru_httpproxy = enabled; break; case CURLOPT_HAPROXYPROTOCOL: /* * Set to send the HAProxy Proxy Protocol header */ - data->set.haproxyprotocol = enabled; + s->haproxyprotocol = enabled; break; case CURLOPT_PROXY_SSL_VERIFYPEER: /* * Enable peer SSL verifying for proxy. */ - data->set.proxy_ssl.primary.verifypeer = enabled; + s->proxy_ssl.primary.verifypeer = enabled; /* Update the current connection proxy_ssl_config. */ Curl_ssl_conn_config_update(data, TRUE); @@ -804,19 +618,24 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option, /* * Enable verification of the hostname in the peer certificate for proxy */ - data->set.proxy_ssl.primary.verifyhost = enabled; + s->proxy_ssl.primary.verifyhost = enabled; /* Update the current connection proxy_ssl_config. */ Curl_ssl_conn_config_update(data, TRUE); break; + case CURLOPT_PROXY_TRANSFER_MODE: + /* + * set transfer mode (;type=) when doing FTP via an HTTP proxy + */ + s->proxy_transfer_mode = enabled; + break; #endif /* ! CURL_DISABLE_PROXY */ - #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) case CURLOPT_SOCKS5_GSSAPI_NEC: /* * Set flag for NEC SOCK5 support */ - data->set.socks5_gssapi_nec = enabled; + s->socks5_gssapi_nec = enabled; break; #endif #ifdef CURL_LIST_ONLY_PROTOCOL @@ -825,7 +644,7 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option, * An option that changes the command to one that asks for a list only, no * file info details. Used for FTP, POP3 and SFTP. */ - data->set.list_only = enabled; + s->list_only = enabled; break; #endif case CURLOPT_APPEND: @@ -833,322 +652,485 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option, * We want to upload and append to an existing file. Used for FTP and * SFTP. */ - data->set.remote_append = enabled; + s->remote_append = enabled; break; - #ifndef CURL_DISABLE_FTP - case CURLOPT_FTP_FILEMETHOD: - /* - * How do access files over FTP. - */ - if((arg < CURLFTPMETHOD_DEFAULT) || (arg >= CURLFTPMETHOD_LAST)) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.ftp_filemethod = (unsigned char)arg; - break; case CURLOPT_FTP_USE_EPRT: - data->set.ftp_use_eprt = enabled; + s->ftp_use_eprt = enabled; break; case CURLOPT_FTP_USE_EPSV: - data->set.ftp_use_epsv = enabled; + s->ftp_use_epsv = enabled; break; case CURLOPT_FTP_USE_PRET: - data->set.ftp_use_pret = enabled; - break; - - case CURLOPT_FTP_SSL_CCC: - if((arg < CURLFTPSSL_CCC_NONE) || (arg >= CURLFTPSSL_CCC_LAST)) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.ftp_ccc = (unsigned char)arg; + s->ftp_use_pret = enabled; break; - case CURLOPT_FTP_SKIP_PASV_IP: /* * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the * bypass of the IP address in PASV responses. */ - data->set.ftp_skip_ip = enabled; + s->ftp_skip_ip = enabled; break; - - case CURLOPT_FTPSSLAUTH: + case CURLOPT_WILDCARDMATCH: + s->wildcard_enabled = enabled; + break; +#endif + case CURLOPT_CRLF: /* - * Set a specific auth for FTP-SSL transfers. + * Kludgy option to enable CRLF conversions. Subject for removal. */ - if((arg < CURLFTPAUTH_DEFAULT) || (arg >= CURLFTPAUTH_LAST)) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.ftpsslauth = (unsigned char)(curl_ftpauth)arg; + s->crlf = enabled; break; - case CURLOPT_ACCEPTTIMEOUT_MS: + +#ifndef CURL_DISABLE_TFTP + case CURLOPT_TFTP_NO_OPTIONS: /* - * The maximum time for curl to wait for FTP server connect + * Option that prevents libcurl from sending TFTP option requests to the + * server. */ - if(uarg > UINT_MAX) - uarg = UINT_MAX; - data->set.accepttimeout = (unsigned int)uarg; - break; - case CURLOPT_WILDCARDMATCH: - data->set.wildcard_enabled = enabled; + s->tftp_no_options = enabled; break; -#endif /* ! CURL_DISABLE_FTP */ -#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) - case CURLOPT_FTP_CREATE_MISSING_DIRS: +#endif /* ! CURL_DISABLE_TFTP */ + case CURLOPT_TRANSFERTEXT: /* - * An FTP/SFTP option that modifies an upload to create missing - * directories on the server. + * This option was previously named 'FTPASCII'. Renamed to work with + * more protocols than merely FTP. + * + * Transfer using ASCII (instead of BINARY). */ - /* reserve other values for future use */ - if((arg < CURLFTP_CREATE_DIR_NONE) || (arg > CURLFTP_CREATE_DIR_RETRY)) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.ftp_create_missing_dirs = (unsigned char)arg; + s->prefer_ascii = enabled; break; -#endif /* ! CURL_DISABLE_FTP || USE_SSH */ - case CURLOPT_INFILESIZE: + case CURLOPT_SSL_VERIFYPEER: /* - * If known, this should inform curl about the file size of the - * to-be-uploaded file. + * Enable peer SSL verifying. */ - if(arg < -1) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.filesize = arg; + s->ssl.primary.verifypeer = enabled; + + /* Update the current connection ssl_config. */ + Curl_ssl_conn_config_update(data, FALSE); break; - case CURLOPT_LOW_SPEED_LIMIT: +#ifndef CURL_DISABLE_DOH + case CURLOPT_DOH_SSL_VERIFYPEER: /* - * The low speed limit that if transfers are below this for - * CURLOPT_LOW_SPEED_TIME, the transfer is aborted. + * Enable peer SSL verifying for DoH. */ - if(arg < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.low_speed_limit = arg; + s->doh_verifypeer = enabled; break; - case CURLOPT_LOW_SPEED_TIME: + case CURLOPT_DOH_SSL_VERIFYHOST: /* - * The low speed time that if transfers are below the set - * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted. + * Enable verification of the hostname in the peer certificate for DoH */ - if(arg < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.low_speed_time = arg; + s->doh_verifyhost = enabled; break; - case CURLOPT_PORT: + case CURLOPT_DOH_SSL_VERIFYSTATUS: /* - * The port number to use when getting the URL. 0 disables it. + * Enable certificate status verifying for DoH. */ - if((arg < 0) || (arg > 65535)) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.use_port = (unsigned short)arg; + if(!Curl_ssl_cert_status_request()) + return CURLE_NOT_BUILT_IN; + + s->doh_verifystatus = enabled; break; - case CURLOPT_TIMEOUT: +#endif /* ! CURL_DISABLE_DOH */ + case CURLOPT_SSL_VERIFYHOST: /* - * The maximum time you allow curl to use for a single transfer - * operation. + * Enable verification of the hostname in the peer certificate */ - if((arg >= 0) && (arg <= (INT_MAX/1000))) - data->set.timeout = (unsigned int)arg * 1000; - else - return CURLE_BAD_FUNCTION_ARGUMENT; - break; - case CURLOPT_TIMEOUT_MS: - if(uarg > UINT_MAX) - uarg = UINT_MAX; - data->set.timeout = (unsigned int)uarg; + /* Obviously people are not reading documentation and too many thought + this argument took a boolean when it was not and misused it. + Treat 1 and 2 the same */ + s->ssl.primary.verifyhost = enabled; + + /* Update the current connection ssl_config. */ + Curl_ssl_conn_config_update(data, FALSE); break; + case CURLOPT_SSL_VERIFYSTATUS: + /* + * Enable certificate status verifying. + */ + if(!Curl_ssl_cert_status_request()) + return CURLE_NOT_BUILT_IN; - case CURLOPT_CONNECTTIMEOUT: + s->ssl.primary.verifystatus = enabled; + + /* Update the current connection ssl_config. */ + Curl_ssl_conn_config_update(data, FALSE); + break; + case CURLOPT_CERTINFO: +#ifdef USE_SSL + if(Curl_ssl_supports(data, SSLSUPP_CERTINFO)) + s->ssl.certinfo = enabled; + else +#endif + return CURLE_NOT_BUILT_IN; + break; + case CURLOPT_NOSIGNAL: /* - * The maximum time you allow curl to use to connect. + * The application asks not to set any signal() or alarm() handlers, + * even when using a timeout. */ - if((arg >= 0) && (arg <= (INT_MAX/1000))) - data->set.connecttimeout = (unsigned int)arg * 1000; + s->no_signal = enabled; + break; + case CURLOPT_TCP_NODELAY: + /* + * Enable or disable TCP_NODELAY, which will disable/enable the Nagle + * algorithm + */ + s->tcp_nodelay = enabled; + break; + + case CURLOPT_IGNORE_CONTENT_LENGTH: + s->ignorecl = enabled; + break; + case CURLOPT_SSL_SESSIONID_CACHE: + s->ssl.primary.cache_session = enabled; +#ifndef CURL_DISABLE_PROXY + s->proxy_ssl.primary.cache_session = + s->ssl.primary.cache_session; +#endif + break; +#ifdef USE_SSH + case CURLOPT_SSH_COMPRESSION: + s->ssh_compression = enabled; + break; +#endif /* ! USE_SSH */ +#ifndef CURL_DISABLE_SMTP + case CURLOPT_MAIL_RCPT_ALLOWFAILS: + /* allow RCPT TO command to fail for some recipients */ + s->mail_rcpt_allowfails = enabled; + break; +#endif /* !CURL_DISABLE_SMTP */ + case CURLOPT_SASL_IR: + /* Enable/disable SASL initial response */ + s->sasl_ir = enabled; + break; + case CURLOPT_TCP_KEEPALIVE: + s->tcp_keepalive = enabled; + break; + case CURLOPT_TCP_FASTOPEN: +#if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN) || \ + defined(TCP_FASTOPEN_CONNECT) + s->tcp_fastopen = enabled; +#else + return CURLE_NOT_BUILT_IN; +#endif + break; + case CURLOPT_SSL_ENABLE_ALPN: + s->ssl_enable_alpn = enabled; + break; + case CURLOPT_PATH_AS_IS: + s->path_as_is = enabled; + break; + case CURLOPT_PIPEWAIT: + s->pipewait = enabled; + break; + case CURLOPT_SUPPRESS_CONNECT_HEADERS: + s->suppress_connect_headers = enabled; + break; +#ifndef CURL_DISABLE_SHUFFLE_DNS + case CURLOPT_DNS_SHUFFLE_ADDRESSES: + s->dns_shuffle_addresses = enabled; + break; +#endif + case CURLOPT_DISALLOW_USERNAME_IN_URL: + s->disallow_username_in_url = enabled; + break; + case CURLOPT_QUICK_EXIT: + s->quick_exit = enabled; + break; + default: + return CURLE_OK; + } + if((arg > 1) || (arg < 0)) + /* reserve other values for future use */ + infof(data, "boolean setopt(%d) got unsupported argument %ld," + " treated as %d", option, arg, enabled); + + *set = TRUE; + return CURLE_OK; +} + +static CURLcode value_range(long *value, long below_error, long min, long max) +{ + if(*value < below_error) + return CURLE_BAD_FUNCTION_ARGUMENT; + else if(*value < min) + *value = min; + else if(*value > max) + *value = max; + return CURLE_OK; +} + +static CURLcode setopt_long(struct Curl_easy *data, CURLoption option, + long arg) +{ + unsigned long uarg = (unsigned long)arg; + bool set = FALSE; + CURLcode result = setopt_bool(data, option, arg, &set); + struct UserDefined *s = &data->set; + if(set || result) + return result; + + switch(option) { + case CURLOPT_DNS_CACHE_TIMEOUT: + return setopt_set_timeout_sec(&s->dns_cache_timeout_ms, arg); + + case CURLOPT_CA_CACHE_TIMEOUT: + if(Curl_ssl_supports(data, SSLSUPP_CA_CACHE)) { + result = value_range(&arg, -1, -1, INT_MAX); + if(result) + return result; + + s->general_ssl.ca_cache_timeout = (int)arg; + } else + return CURLE_NOT_BUILT_IN; + break; + case CURLOPT_MAXCONNECTS: + result = value_range(&arg, 1, 1, UINT_MAX); + if(result) + return result; + s->maxconnects = (unsigned int)arg; + break; + case CURLOPT_SERVER_RESPONSE_TIMEOUT: + return setopt_set_timeout_sec(&s->server_response_timeout, arg); + + case CURLOPT_SERVER_RESPONSE_TIMEOUT_MS: + return setopt_set_timeout_ms(&s->server_response_timeout, arg); + +#ifndef CURL_DISABLE_TFTP + case CURLOPT_TFTP_BLKSIZE: + result = value_range(&arg, 0, TFTP_BLKSIZE_MIN, TFTP_BLKSIZE_MAX); + if(result) + return result; + s->tftp_blksize = (unsigned short)arg; + break; +#endif +#ifndef CURL_DISABLE_NETRC + case CURLOPT_NETRC: + if((arg < CURL_NETRC_IGNORED) || (arg >= CURL_NETRC_LAST)) return CURLE_BAD_FUNCTION_ARGUMENT; + s->use_netrc = (unsigned char)arg; break; +#endif + case CURLOPT_TIMECONDITION: + if((arg < CURL_TIMECOND_NONE) || (arg >= CURL_TIMECOND_LAST)) + return CURLE_BAD_FUNCTION_ARGUMENT; + s->timecondition = (unsigned char)arg; + break; + case CURLOPT_TIMEVALUE: + s->timevalue = (time_t)arg; + break; + case CURLOPT_SSLVERSION: +#ifndef CURL_DISABLE_PROXY + case CURLOPT_PROXY_SSLVERSION: +#endif + return Curl_setopt_SSLVERSION(data, option, arg); - case CURLOPT_CONNECTTIMEOUT_MS: - if(uarg > UINT_MAX) - uarg = UINT_MAX; - data->set.connecttimeout = (unsigned int)uarg; + case CURLOPT_POSTFIELDSIZE: + if(arg < -1) + return CURLE_BAD_FUNCTION_ARGUMENT; + + if(s->postfieldsize < arg && + s->postfields == s->str[STRING_COPYPOSTFIELDS]) { + /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ + Curl_safefree(s->str[STRING_COPYPOSTFIELDS]); + s->postfields = NULL; + } + + s->postfieldsize = arg; + break; +#ifndef CURL_DISABLE_HTTP + case CURLOPT_FOLLOWLOCATION: + if(uarg > 3) + return CURLE_BAD_FUNCTION_ARGUMENT; + s->http_follow_mode = (unsigned char)uarg; break; - case CURLOPT_RESUME_FROM: - /* - * Resume transfer at the given file position - */ + case CURLOPT_MAXREDIRS: + result = value_range(&arg, -1, 0, 0x7fff); + if(result) + return result; + s->maxredirs = (short)arg; + break; + + case CURLOPT_POSTREDIR: + if(arg < CURL_REDIR_GET_ALL) + /* no return error on too high numbers since the bitmask could be + extended in a future */ + return CURLE_BAD_FUNCTION_ARGUMENT; + s->keep_post = arg & CURL_REDIR_POST_ALL; + break; + + case CURLOPT_HEADEROPT: + s->sep_headers = !!(arg & CURLHEADER_SEPARATE); + break; + case CURLOPT_HTTPAUTH: + return httpauth(data, FALSE, uarg); + + case CURLOPT_HTTP_VERSION: + return setopt_HTTP_VERSION(data, arg); + + case CURLOPT_EXPECT_100_TIMEOUT_MS: + result = value_range(&arg, 0, 0, 0xffff); + if(result) + return result; + s->expect_100_timeout = (unsigned short)arg; + break; + +#endif /* ! CURL_DISABLE_HTTP */ + +#ifndef CURL_DISABLE_MIME + case CURLOPT_MIME_OPTIONS: + s->mime_formescape = !!(arg & CURLMIMEOPT_FORMESCAPE); + break; +#endif +#ifndef CURL_DISABLE_PROXY + case CURLOPT_PROXYPORT: + if((arg < 0) || (arg > 65535)) + return CURLE_BAD_FUNCTION_ARGUMENT; + s->proxyport = (unsigned short)arg; + break; + + case CURLOPT_PROXYAUTH: + return httpauth(data, TRUE, uarg); + + case CURLOPT_PROXYTYPE: + if((arg < CURLPROXY_HTTP) || (arg > CURLPROXY_SOCKS5_HOSTNAME)) + return CURLE_BAD_FUNCTION_ARGUMENT; + s->proxytype = (unsigned char)arg; + break; + + case CURLOPT_SOCKS5_AUTH: + if(uarg & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI)) + return CURLE_NOT_BUILT_IN; + s->socks5auth = (unsigned char)uarg; + break; +#endif /* ! CURL_DISABLE_PROXY */ + +#ifndef CURL_DISABLE_FTP + case CURLOPT_FTP_FILEMETHOD: + if((arg < CURLFTPMETHOD_DEFAULT) || (arg >= CURLFTPMETHOD_LAST)) + return CURLE_BAD_FUNCTION_ARGUMENT; + s->ftp_filemethod = (unsigned char)arg; + break; + case CURLOPT_FTP_SSL_CCC: + if((arg < CURLFTPSSL_CCC_NONE) || (arg >= CURLFTPSSL_CCC_LAST)) + return CURLE_BAD_FUNCTION_ARGUMENT; + s->ftp_ccc = (unsigned char)arg; + break; + + case CURLOPT_FTPSSLAUTH: + if((arg < CURLFTPAUTH_DEFAULT) || (arg >= CURLFTPAUTH_LAST)) + return CURLE_BAD_FUNCTION_ARGUMENT; + s->ftpsslauth = (unsigned char)arg; + break; + case CURLOPT_ACCEPTTIMEOUT_MS: + return setopt_set_timeout_ms(&s->accepttimeout, arg); +#endif /* ! CURL_DISABLE_FTP */ +#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) + case CURLOPT_FTP_CREATE_MISSING_DIRS: + if((arg < CURLFTP_CREATE_DIR_NONE) || (arg > CURLFTP_CREATE_DIR_RETRY)) + return CURLE_BAD_FUNCTION_ARGUMENT; + s->ftp_create_missing_dirs = (unsigned char)arg; + break; +#endif /* ! CURL_DISABLE_FTP || USE_SSH */ + case CURLOPT_INFILESIZE: + if(arg < -1) + return CURLE_BAD_FUNCTION_ARGUMENT; + s->filesize = arg; + break; + case CURLOPT_LOW_SPEED_LIMIT: + if(arg < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + s->low_speed_limit = arg; + break; + case CURLOPT_LOW_SPEED_TIME: + if(arg < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + s->low_speed_time = arg; + break; + case CURLOPT_PORT: + if((arg < 0) || (arg > 65535)) + return CURLE_BAD_FUNCTION_ARGUMENT; + s->use_port = (unsigned short)arg; + break; + case CURLOPT_TIMEOUT: + return setopt_set_timeout_sec(&s->timeout, arg); + + case CURLOPT_TIMEOUT_MS: + return setopt_set_timeout_ms(&s->timeout, arg); + + case CURLOPT_CONNECTTIMEOUT: + return setopt_set_timeout_sec(&s->connecttimeout, arg); + + case CURLOPT_CONNECTTIMEOUT_MS: + return setopt_set_timeout_ms(&s->connecttimeout, arg); + + case CURLOPT_RESUME_FROM: if(arg < -1) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.set_resume_from = arg; - break; - - case CURLOPT_CRLF: - /* - * Kludgy option to enable CRLF conversions. Subject for removal. - */ - data->set.crlf = enabled; + s->set_resume_from = arg; break; #ifndef CURL_DISABLE_BINDLOCAL case CURLOPT_LOCALPORT: - /* - * Set what local port to bind the socket to when performing an operation. - */ if((arg < 0) || (arg > 65535)) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.localport = curlx_sltous(arg); + s->localport = curlx_sltous(arg); break; case CURLOPT_LOCALPORTRANGE: - /* - * Set number of local ports to try, starting with CURLOPT_LOCALPORT. - */ if((arg < 0) || (arg > 65535)) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.localportrange = curlx_sltous(arg); + s->localportrange = curlx_sltous(arg); break; #endif #ifdef HAVE_GSSAPI case CURLOPT_GSSAPI_DELEGATION: - /* - * GSS-API credential delegation bitmask - */ - data->set.gssapi_delegation = (unsigned char)uarg& + s->gssapi_delegation = (unsigned char)uarg& (CURLGSSAPI_DELEGATION_POLICY_FLAG|CURLGSSAPI_DELEGATION_FLAG); break; #endif - case CURLOPT_SSL_VERIFYPEER: - /* - * Enable peer SSL verifying. - */ - data->set.ssl.primary.verifypeer = enabled; - - /* Update the current connection ssl_config. */ - Curl_ssl_conn_config_update(data, FALSE); - break; -#ifndef CURL_DISABLE_DOH - case CURLOPT_DOH_SSL_VERIFYPEER: - /* - * Enable peer SSL verifying for DoH. - */ - data->set.doh_verifypeer = enabled; - break; - case CURLOPT_DOH_SSL_VERIFYHOST: - /* - * Enable verification of the hostname in the peer certificate for DoH - */ - data->set.doh_verifyhost = enabled; - break; - case CURLOPT_DOH_SSL_VERIFYSTATUS: - /* - * Enable certificate status verifying for DoH. - */ - if(!Curl_ssl_cert_status_request()) - return CURLE_NOT_BUILT_IN; - - data->set.doh_verifystatus = enabled; - break; -#endif /* ! CURL_DISABLE_DOH */ - case CURLOPT_SSL_VERIFYHOST: - /* - * Enable verification of the hostname in the peer certificate - */ - - /* Obviously people are not reading documentation and too many thought - this argument took a boolean when it was not and misused it. - Treat 1 and 2 the same */ - data->set.ssl.primary.verifyhost = enabled; - - /* Update the current connection ssl_config. */ - Curl_ssl_conn_config_update(data, FALSE); - break; - case CURLOPT_SSL_VERIFYSTATUS: - /* - * Enable certificate status verifying. - */ - if(!Curl_ssl_cert_status_request()) - return CURLE_NOT_BUILT_IN; - - data->set.ssl.primary.verifystatus = enabled; - /* Update the current connection ssl_config. */ - Curl_ssl_conn_config_update(data, FALSE); - break; case CURLOPT_SSL_FALSESTART: - /* - * Enable TLS false start. - */ - if(!Curl_ssl_false_start()) - return CURLE_NOT_BUILT_IN; - - data->set.ssl.falsestart = enabled; - break; - case CURLOPT_CERTINFO: -#ifdef USE_SSL - if(Curl_ssl_supports(data, SSLSUPP_CERTINFO)) - data->set.ssl.certinfo = enabled; - else -#endif - return CURLE_NOT_BUILT_IN; - break; + return CURLE_NOT_BUILT_IN; case CURLOPT_BUFFERSIZE: - /* - * The application kindly asks for a differently sized receive buffer. - * If it seems reasonable, we will use it. - */ - if(arg > READBUFFER_MAX) - arg = READBUFFER_MAX; - else if(arg < 1) - arg = READBUFFER_SIZE; - else if(arg < READBUFFER_MIN) - arg = READBUFFER_MIN; - - data->set.buffer_size = (unsigned int)arg; + result = value_range(&arg, 0, READBUFFER_MIN, READBUFFER_MAX); + if(result) + return result; + s->buffer_size = (unsigned int)arg; break; case CURLOPT_UPLOAD_BUFFERSIZE: - /* - * The application kindly asks for a differently sized upload buffer. - * Cap it to sensible. - */ - if(arg > UPLOADBUFFER_MAX) - arg = UPLOADBUFFER_MAX; - else if(arg < UPLOADBUFFER_MIN) - arg = UPLOADBUFFER_MIN; - - data->set.upload_buffer_size = (unsigned int)arg; + result = value_range(&arg, 0, UPLOADBUFFER_MIN, UPLOADBUFFER_MAX); + if(result) + return result; + s->upload_buffer_size = (unsigned int)arg; break; - case CURLOPT_NOSIGNAL: - /* - * The application asks not to set any signal() or alarm() handlers, - * even when using a timeout. - */ - data->set.no_signal = enabled; - break; case CURLOPT_MAXFILESIZE: - /* - * Set the maximum size of a file to download. - */ if(arg < 0) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.max_filesize = arg; + s->max_filesize = arg; break; #ifdef USE_SSL case CURLOPT_USE_SSL: - /* - * Make transfers attempt to use SSL/TLS. - */ if((arg < CURLUSESSL_NONE) || (arg >= CURLUSESSL_LAST)) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.use_ssl = (unsigned char)arg; + s->use_ssl = (unsigned char)arg; break; case CURLOPT_SSL_OPTIONS: - set_ssl_options(&data->set.ssl, &data->set.ssl.primary, arg); + set_ssl_options(&s->ssl, &s->ssl.primary, arg); break; #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_SSL_OPTIONS: - set_ssl_options(&data->set.proxy_ssl, &data->set.proxy_ssl.primary, arg); + set_ssl_options(&s->proxy_ssl, &s->proxy_ssl.primary, arg); break; #endif @@ -1156,225 +1138,109 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option, case CURLOPT_IPRESOLVE: if((arg < CURL_IPRESOLVE_WHATEVER) || (arg > CURL_IPRESOLVE_V6)) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.ipver = (unsigned char) arg; - break; - case CURLOPT_TCP_NODELAY: - /* - * Enable or disable TCP_NODELAY, which will disable/enable the Nagle - * algorithm - */ - data->set.tcp_nodelay = enabled; - break; - - case CURLOPT_IGNORE_CONTENT_LENGTH: - data->set.ignorecl = enabled; + s->ipver = (unsigned char) arg; break; case CURLOPT_CONNECT_ONLY: - /* - * No data transfer. - * (1) - only do connection - * (2) - do first get request but get no content - */ - if(arg > 2) + if(arg < 0 || arg > 2) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.connect_only = !!arg; - data->set.connect_only_ws = (arg == 2); + s->connect_only = !!arg; + s->connect_only_ws = (arg == 2); break; - case CURLOPT_SSL_SESSIONID_CACHE: - data->set.ssl.primary.cache_session = enabled; -#ifndef CURL_DISABLE_PROXY - data->set.proxy_ssl.primary.cache_session = - data->set.ssl.primary.cache_session; -#endif - break; #ifdef USE_SSH - /* we only include SSH options if explicitly built to support SSH */ case CURLOPT_SSH_AUTH_TYPES: - data->set.ssh_auth_types = (int)arg; - break; - case CURLOPT_SSH_COMPRESSION: - data->set.ssh_compression = enabled; + s->ssh_auth_types = (int)arg; break; #endif - case CURLOPT_HTTP_TRANSFER_DECODING: - /* - * disable libcurl transfer encoding is used - */ - data->set.http_te_skip = !enabled; /* reversed */ - break; - - case CURLOPT_HTTP_CONTENT_DECODING: - /* - * raw data passed to the application when content encoding is used - */ - data->set.http_ce_skip = !enabled; /* reversed */ - break; - #if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) case CURLOPT_NEW_FILE_PERMS: - /* - * Uses these permissions instead of 0644 - */ if((arg < 0) || (arg > 0777)) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.new_file_perms = (unsigned int)arg; + s->new_file_perms = (unsigned int)arg; break; #endif #ifdef USE_SSH case CURLOPT_NEW_DIRECTORY_PERMS: - /* - * Uses these permissions instead of 0755 - */ if((arg < 0) || (arg > 0777)) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.new_directory_perms = (unsigned int)arg; + s->new_directory_perms = (unsigned int)arg; break; #endif #ifdef USE_IPV6 case CURLOPT_ADDRESS_SCOPE: - /* - * Use this scope id when using IPv6 - * We always get longs when passed plain numericals so we should check - * that the value fits into an unsigned 32-bit integer. - */ #if SIZEOF_LONG > 4 if(uarg > UINT_MAX) return CURLE_BAD_FUNCTION_ARGUMENT; #endif - data->set.scope_id = (unsigned int)uarg; + s->scope_id = (unsigned int)uarg; break; #endif case CURLOPT_PROTOCOLS: - /* 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. */ - data->set.allowed_protocols = (curl_prot_t)arg; + s->allowed_protocols = (curl_prot_t)arg; break; case CURLOPT_REDIR_PROTOCOLS: - /* 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. */ - data->set.redir_protocols = (curl_prot_t)arg; + s->redir_protocols = (curl_prot_t)arg; break; -#ifndef CURL_DISABLE_SMTP - case CURLOPT_MAIL_RCPT_ALLOWFAILS: - /* allow RCPT TO command to fail for some recipients */ - data->set.mail_rcpt_allowfails = enabled; - break; -#endif /* !CURL_DISABLE_SMTP */ - case CURLOPT_SASL_IR: - /* Enable/disable SASL initial response */ - data->set.sasl_ir = enabled; - break; #ifndef CURL_DISABLE_RTSP case CURLOPT_RTSP_REQUEST: return setopt_RTSP_REQUEST(data, arg); case CURLOPT_RTSP_CLIENT_CSEQ: - /* - * Set the CSEQ number to issue for the next RTSP request. Useful if the - * application is resuming a previously broken connection. The CSEQ - * will increment from this new number henceforth. - */ data->state.rtsp_next_client_CSeq = arg; break; case CURLOPT_RTSP_SERVER_CSEQ: - /* Same as the above, but for server-initiated requests */ data->state.rtsp_next_server_CSeq = arg; break; #endif /* ! CURL_DISABLE_RTSP */ - case CURLOPT_TCP_KEEPALIVE: - data->set.tcp_keepalive = enabled; - break; case CURLOPT_TCP_KEEPIDLE: - if(arg < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; - else if(arg > INT_MAX) - arg = INT_MAX; - data->set.tcp_keepidle = (int)arg; + result = value_range(&arg, 0, 0, INT_MAX); + if(result) + return result; + s->tcp_keepidle = (int)arg; break; case CURLOPT_TCP_KEEPINTVL: - if(arg < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; - else if(arg > INT_MAX) - arg = INT_MAX; - data->set.tcp_keepintvl = (int)arg; + result = value_range(&arg, 0, 0, INT_MAX); + if(result) + return result; + s->tcp_keepintvl = (int)arg; break; case CURLOPT_TCP_KEEPCNT: - if(arg < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; - else if(arg > INT_MAX) - arg = INT_MAX; - data->set.tcp_keepcnt = (int)arg; - break; - case CURLOPT_TCP_FASTOPEN: -#if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN) || \ - defined(TCP_FASTOPEN_CONNECT) - data->set.tcp_fastopen = enabled; -#else - return CURLE_NOT_BUILT_IN; -#endif + result = value_range(&arg, 0, 0, INT_MAX); + if(result) + return result; + s->tcp_keepcnt = (int)arg; break; case CURLOPT_SSL_ENABLE_NPN: break; - case CURLOPT_SSL_ENABLE_ALPN: - data->set.ssl_enable_alpn = enabled; - break; - case CURLOPT_PATH_AS_IS: - data->set.path_as_is = enabled; - break; - case CURLOPT_PIPEWAIT: - data->set.pipewait = enabled; - break; case CURLOPT_STREAM_WEIGHT: #if defined(USE_HTTP2) || defined(USE_HTTP3) if((arg >= 1) && (arg <= 256)) - data->set.priority.weight = (int)arg; + s->priority.weight = (int)arg; break; #else return CURLE_NOT_BUILT_IN; #endif - case CURLOPT_SUPPRESS_CONNECT_HEADERS: - data->set.suppress_connect_headers = enabled; - break; case CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS: - if(uarg > UINT_MAX) - uarg = UINT_MAX; - data->set.happy_eyeballs_timeout = (unsigned int)uarg; - break; -#ifndef CURL_DISABLE_SHUFFLE_DNS - case CURLOPT_DNS_SHUFFLE_ADDRESSES: - data->set.dns_shuffle_addresses = enabled; - break; -#endif - case CURLOPT_DISALLOW_USERNAME_IN_URL: - data->set.disallow_username_in_url = enabled; - break; + return setopt_set_timeout_ms(&s->happy_eyeballs_timeout, arg); case CURLOPT_UPKEEP_INTERVAL_MS: if(arg < 0) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.upkeep_interval_ms = arg; + s->upkeep_interval_ms = arg; break; case CURLOPT_MAXAGE_CONN: - if(arg < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.maxage_conn = arg; - break; + return setopt_set_timeout_sec(&s->conn_max_idle_ms, arg); + case CURLOPT_MAXLIFETIME_CONN: - if(arg < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.maxlifetime_conn = arg; - break; + return setopt_set_timeout_sec(&s->conn_max_age_ms, arg); + #ifndef CURL_DISABLE_HSTS case CURLOPT_HSTS_CTRL: if(arg & CURLHSTS_ENABLE) { @@ -1403,27 +1269,20 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option, #endif /* ! CURL_DISABLE_ALTSVC */ #ifndef CURL_DISABLE_WEBSOCKETS case CURLOPT_WS_OPTIONS: - data->set.ws_raw_mode = (bool)(arg & CURLWS_RAW_MODE); - data->set.ws_no_auto_pong = (bool)(arg & CURLWS_NOAUTOPONG); + s->ws_raw_mode = (bool)(arg & CURLWS_RAW_MODE); + s->ws_no_auto_pong = (bool)(arg & CURLWS_NOAUTOPONG); break; #endif - case CURLOPT_QUICK_EXIT: - data->set.quick_exit = enabled; - break; case CURLOPT_DNS_USE_GLOBAL_CACHE: /* deprecated */ break; case CURLOPT_SSLENGINE_DEFAULT: - /* - * flag to set engine as default. - */ - Curl_safefree(data->set.str[STRING_SSL_ENGINE]); + Curl_safefree(s->str[STRING_SSL_ENGINE]); return Curl_ssl_set_engine_default(data); case CURLOPT_UPLOAD_FLAGS: - data->set.upload_flags = (unsigned char)arg; + s->upload_flags = (unsigned char)arg; break; default: - /* unknown option */ return CURLE_UNKNOWN_OPTION; } return CURLE_OK; @@ -1433,6 +1292,7 @@ static CURLcode setopt_slist(struct Curl_easy *data, CURLoption option, struct curl_slist *slist) { CURLcode result = CURLE_OK; + struct UserDefined *s = &data->set; switch(option) { #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXYHEADER: @@ -1446,7 +1306,7 @@ static CURLcode setopt_slist(struct Curl_easy *data, CURLoption option, * * Set this option to NULL to restore the previous behavior. */ - data->set.proxyheaders = slist; + s->proxyheaders = slist; break; #endif #ifndef CURL_DISABLE_HTTP @@ -1454,7 +1314,7 @@ static CURLcode setopt_slist(struct Curl_easy *data, CURLoption option, /* * Set a list of aliases for HTTP 200 in response header */ - data->set.http200aliases = slist; + s->http200aliases = slist; break; #endif #if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) @@ -1462,19 +1322,19 @@ static CURLcode setopt_slist(struct Curl_easy *data, CURLoption option, /* * List of RAW FTP commands to use after a transfer */ - data->set.postquote = slist; + s->postquote = slist; break; case CURLOPT_PREQUOTE: /* * List of RAW FTP commands to use prior to RETR (Wesley Laxton) */ - data->set.prequote = slist; + s->prequote = slist; break; case CURLOPT_QUOTE: /* * List of RAW FTP commands to use before a transfer */ - data->set.quote = slist; + s->quote = slist; break; #endif case CURLOPT_RESOLVE: @@ -1491,15 +1351,15 @@ static CURLcode setopt_slist(struct Curl_easy *data, CURLoption option, * This API can remove any entry from the DNS cache, but only entries * that are not actually in use right now will be pruned immediately. */ - data->set.resolve = slist; - data->state.resolve = data->set.resolve; + s->resolve = slist; + data->state.resolve = s->resolve; break; #if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MIME) case CURLOPT_HTTPHEADER: /* * Set a list with HTTP headers to use (or replace internals with) */ - data->set.headers = slist; + s->headers = slist; break; #endif #ifndef CURL_DISABLE_TELNET @@ -1507,17 +1367,17 @@ static CURLcode setopt_slist(struct Curl_easy *data, CURLoption option, /* * Set a linked list of telnet options */ - data->set.telnet_options = slist; + s->telnet_options = slist; break; #endif #ifndef CURL_DISABLE_SMTP case CURLOPT_MAIL_RCPT: /* Set the list of mail recipients */ - data->set.mail_rcpt = slist; + s->mail_rcpt = slist; break; #endif case CURLOPT_CONNECT_TO: - data->set.connect_to = slist; + s->connect_to = slist; break; default: return CURLE_UNKNOWN_OPTION; @@ -1530,6 +1390,7 @@ static CURLcode setopt_pointers(struct Curl_easy *data, CURLoption option, va_list param) { CURLcode result = CURLE_OK; + struct UserDefined *s = &data->set; switch(option) { #ifndef CURL_DISABLE_HTTP #ifndef CURL_DISABLE_FORM_API @@ -1537,9 +1398,9 @@ static CURLcode setopt_pointers(struct Curl_easy *data, CURLoption option, /* * Set to make us do HTTP POST. Legacy API-style. */ - data->set.httppost = va_arg(param, struct curl_httppost *); - data->set.method = HTTPREQ_POST_FORM; - data->set.opt_no_body = FALSE; /* this is implied */ + s->httppost = va_arg(param, struct curl_httppost *); + s->method = HTTPREQ_POST_FORM; + s->opt_no_body = FALSE; /* this is implied */ Curl_mime_cleanpart(data->state.formp); Curl_safefree(data->state.formp); data->state.mimepost = NULL; @@ -1553,12 +1414,12 @@ static CURLcode setopt_pointers(struct Curl_easy *data, CURLoption option, /* * Set to make us do MIME POST */ - result = Curl_mime_set_subparts(&data->set.mimepost, + result = Curl_mime_set_subparts(&s->mimepost, va_arg(param, curl_mime *), FALSE); if(!result) { - data->set.method = HTTPREQ_POST_MIME; - data->set.opt_no_body = FALSE; /* this is implied */ + s->method = HTTPREQ_POST_MIME; + s->opt_no_body = FALSE; /* this is implied */ #ifndef CURL_DISABLE_FORM_API Curl_mime_cleanpart(data->state.formp); Curl_safefree(data->state.formp); @@ -1573,9 +1434,9 @@ static CURLcode setopt_pointers(struct Curl_easy *data, CURLoption option, * Set to a FILE * that should receive all error writes. This * defaults to stderr for normal operations. */ - data->set.err = va_arg(param, FILE *); - if(!data->set.err) - data->set.err = stderr; + s->err = va_arg(param, FILE *); + if(!s->err) + s->err = stderr; break; case CURLOPT_SHARE: { @@ -1662,22 +1523,115 @@ static CURLcode setopt_pointers(struct Curl_easy *data, CURLoption option, return result; } +#ifndef CURL_DISABLE_COOKIES +static CURLcode cookielist(struct Curl_easy *data, + const char *ptr) +{ + if(!ptr) + return CURLE_OK; + + if(curl_strequal(ptr, "ALL")) { + /* clear all cookies */ + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); + Curl_cookie_clearall(data->cookies); + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); + } + else if(curl_strequal(ptr, "SESS")) { + /* clear session cookies */ + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); + Curl_cookie_clearsess(data->cookies); + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); + } + else if(curl_strequal(ptr, "FLUSH")) { + /* flush cookies to file, takes care of the locking */ + Curl_flush_cookies(data, FALSE); + } + else if(curl_strequal(ptr, "RELOAD")) { + /* reload cookies from file */ + Curl_cookie_loadfiles(data); + } + else { + if(!data->cookies) { + /* if cookie engine was not running, activate it */ + data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE); + if(!data->cookies) + return CURLE_OUT_OF_MEMORY; + } + + /* general protection against mistakes and abuse */ + if(strlen(ptr) > CURL_MAX_INPUT_LENGTH) + return CURLE_BAD_FUNCTION_ARGUMENT; + + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); + if(checkprefix("Set-Cookie:", ptr)) + /* HTTP Header format line */ + Curl_cookie_add(data, data->cookies, TRUE, FALSE, ptr + 11, NULL, + NULL, TRUE); + else + /* Netscape format line */ + Curl_cookie_add(data, data->cookies, FALSE, FALSE, ptr, NULL, + NULL, TRUE); + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); + } + return CURLE_OK; +} + +static CURLcode cookiefile(struct Curl_easy *data, + const char *ptr) +{ + /* + * Set cookie file to read and parse. Can be used multiple times. + */ + if(ptr) { + struct curl_slist *cl; + /* general protection against mistakes and abuse */ + if(strlen(ptr) > CURL_MAX_INPUT_LENGTH) + return CURLE_BAD_FUNCTION_ARGUMENT; + /* append the cookie filename to the list of filenames, and deal with + them later */ + cl = curl_slist_append(data->state.cookielist, ptr); + if(!cl) { + curl_slist_free_all(data->state.cookielist); + data->state.cookielist = NULL; + return CURLE_OUT_OF_MEMORY; + } + data->state.cookielist = cl; /* store the list for later use */ + } + else { + /* clear the list of cookie files */ + curl_slist_free_all(data->state.cookielist); + data->state.cookielist = NULL; + + if(!data->share || !data->share->cookies) { + /* throw away all existing cookies if this is not a shared cookie + container */ + Curl_cookie_clearall(data->cookies); + Curl_cookie_cleanup(data->cookies); + } + /* disable the cookie engine */ + data->cookies = NULL; + } + return CURLE_OK; +} +#endif + static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, char *ptr) { CURLcode result = CURLE_OK; + struct UserDefined *s = &data->set; switch(option) { case CURLOPT_SSL_CIPHER_LIST: if(Curl_ssl_supports(data, SSLSUPP_CIPHER_LIST)) /* set a list of cipher we want to use in the SSL connection */ - return Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST], ptr); + return Curl_setstropt(&s->str[STRING_SSL_CIPHER_LIST], ptr); else return CURLE_NOT_BUILT_IN; #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_SSL_CIPHER_LIST: if(Curl_ssl_supports(data, SSLSUPP_CIPHER_LIST)) { /* set a list of cipher we want to use in the SSL connection for proxy */ - return Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_PROXY], + return Curl_setstropt(&s->str[STRING_SSL_CIPHER_LIST_PROXY], ptr); } else @@ -1686,7 +1640,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, case CURLOPT_TLS13_CIPHERS: if(Curl_ssl_supports(data, SSLSUPP_TLS13_CIPHERSUITES)) { /* set preferred list of TLS 1.3 cipher suites */ - return Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST], ptr); + return Curl_setstropt(&s->str[STRING_SSL_CIPHER13_LIST], ptr); } else return CURLE_NOT_BUILT_IN; @@ -1694,7 +1648,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, case CURLOPT_PROXY_TLS13_CIPHERS: if(Curl_ssl_supports(data, SSLSUPP_TLS13_CIPHERSUITES)) /* set preferred list of TLS 1.3 cipher suites for proxy */ - return Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST_PROXY], + return Curl_setstropt(&s->str[STRING_SSL_CIPHER13_LIST_PROXY], ptr); else return CURLE_NOT_BUILT_IN; @@ -1704,13 +1658,13 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, case CURLOPT_EGDSOCKET: break; case CURLOPT_REQUEST_TARGET: - return Curl_setstropt(&data->set.str[STRING_TARGET], ptr); + return Curl_setstropt(&s->str[STRING_TARGET], ptr); #ifndef CURL_DISABLE_NETRC case CURLOPT_NETRC_FILE: /* * Use this file instead of the $HOME/.netrc file */ - return Curl_setstropt(&data->set.str[STRING_NETRC_FILE], ptr); + return Curl_setstropt(&s->str[STRING_NETRC_FILE], ptr); #endif #if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MQTT) @@ -1720,16 +1674,16 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to * CURLOPT_COPYPOSTFIELDS and not altered later. */ - if(!ptr || data->set.postfieldsize == -1) - result = Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], ptr); + if(!ptr || s->postfieldsize == -1) + result = Curl_setstropt(&s->str[STRING_COPYPOSTFIELDS], ptr); else { - if(data->set.postfieldsize < 0) + if(s->postfieldsize < 0) return CURLE_BAD_FUNCTION_ARGUMENT; #if SIZEOF_CURL_OFF_T > SIZEOF_SIZE_T /* * Check that requested length does not overflow the size_t type. */ - else if(data->set.postfieldsize > SIZE_T_MAX) + else if(s->postfieldsize > SIZE_T_MAX) return CURLE_OUT_OF_MEMORY; #endif else { @@ -1738,28 +1692,28 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, mark that postfields is used rather than read function or form data. */ - char *p = Curl_memdup0(ptr, (size_t)data->set.postfieldsize); + char *p = Curl_memdup0(ptr, (size_t)s->postfieldsize); if(!p) return CURLE_OUT_OF_MEMORY; else { - free(data->set.str[STRING_COPYPOSTFIELDS]); - data->set.str[STRING_COPYPOSTFIELDS] = p; + free(s->str[STRING_COPYPOSTFIELDS]); + s->str[STRING_COPYPOSTFIELDS] = p; } } } - data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS]; - data->set.method = HTTPREQ_POST; + s->postfields = s->str[STRING_COPYPOSTFIELDS]; + s->method = HTTPREQ_POST; break; case CURLOPT_POSTFIELDS: /* * Like above, but use static data instead of copying it. */ - data->set.postfields = ptr; + s->postfields = ptr; /* Release old copied data. */ - Curl_safefree(data->set.str[STRING_COPYPOSTFIELDS]); - data->set.method = HTTPREQ_POST; + Curl_safefree(s->str[STRING_COPYPOSTFIELDS]); + s->method = HTTPREQ_POST; break; #endif /* ! CURL_DISABLE_HTTP || ! CURL_DISABLE_MQTT */ @@ -1777,22 +1731,22 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, if(ptr && !*ptr) { char all[256]; Curl_all_content_encodings(all, sizeof(all)); - return Curl_setstropt(&data->set.str[STRING_ENCODING], all); + return Curl_setstropt(&s->str[STRING_ENCODING], all); } - return Curl_setstropt(&data->set.str[STRING_ENCODING], ptr); + return Curl_setstropt(&s->str[STRING_ENCODING], ptr); -#if !defined(CURL_DISABLE_AWS) +#ifndef CURL_DISABLE_AWS case CURLOPT_AWS_SIGV4: /* * String that is merged to some authentication * parameters are used by the algorithm. */ - result = Curl_setstropt(&data->set.str[STRING_AWS_SIGV4], ptr); + result = Curl_setstropt(&s->str[STRING_AWS_SIGV4], ptr); /* * Basic been set by default it need to be unset here */ - if(data->set.str[STRING_AWS_SIGV4]) - data->set.httpauth = CURLAUTH_AWS_SIGV4; + if(s->str[STRING_AWS_SIGV4]) + s->httpauth = CURLAUTH_AWS_SIGV4; break; #endif case CURLOPT_REFERER: @@ -1803,70 +1757,38 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, Curl_safefree(data->state.referer); data->state.referer_alloc = FALSE; } - result = Curl_setstropt(&data->set.str[STRING_SET_REFERER], ptr); - data->state.referer = data->set.str[STRING_SET_REFERER]; + result = Curl_setstropt(&s->str[STRING_SET_REFERER], ptr); + data->state.referer = s->str[STRING_SET_REFERER]; break; case CURLOPT_USERAGENT: /* * String to use in the HTTP User-Agent field */ - return Curl_setstropt(&data->set.str[STRING_USERAGENT], ptr); + return Curl_setstropt(&s->str[STRING_USERAGENT], ptr); -#if !defined(CURL_DISABLE_COOKIES) +#ifndef CURL_DISABLE_COOKIES case CURLOPT_COOKIE: /* * Cookie string to send to the remote server in the request. */ - return Curl_setstropt(&data->set.str[STRING_COOKIE], ptr); + return Curl_setstropt(&s->str[STRING_COOKIE], ptr); case CURLOPT_COOKIEFILE: - /* - * Set cookie file to read and parse. Can be used multiple times. - */ - if(ptr) { - struct curl_slist *cl; - /* general protection against mistakes and abuse */ - if(strlen(ptr) > CURL_MAX_INPUT_LENGTH) - return CURLE_BAD_FUNCTION_ARGUMENT; - /* append the cookie filename to the list of filenames, and deal with - them later */ - cl = curl_slist_append(data->state.cookielist, ptr); - if(!cl) { - curl_slist_free_all(data->state.cookielist); - data->state.cookielist = NULL; - return CURLE_OUT_OF_MEMORY; - } - data->state.cookielist = cl; /* store the list for later use */ - } - else { - /* clear the list of cookie files */ - curl_slist_free_all(data->state.cookielist); - data->state.cookielist = NULL; - - if(!data->share || !data->share->cookies) { - /* throw away all existing cookies if this is not a shared cookie - container */ - Curl_cookie_clearall(data->cookies); - Curl_cookie_cleanup(data->cookies); - } - /* disable the cookie engine */ - data->cookies = NULL; - } - break; + return cookiefile(data, ptr); case CURLOPT_COOKIEJAR: /* * Set cookie filename to dump all cookies to when we are done. */ - result = Curl_setstropt(&data->set.str[STRING_COOKIEJAR], ptr); + result = Curl_setstropt(&s->str[STRING_COOKIEJAR], ptr); if(!result) { /* * Activate the cookie parser. This may or may not already * have been made. */ struct CookieInfo *newcookies = - Curl_cookie_init(data, NULL, data->cookies, data->set.cookiesession); + Curl_cookie_init(data, NULL, data->cookies, s->cookiesession); if(!newcookies) result = CURLE_OUT_OF_MEMORY; data->cookies = newcookies; @@ -1874,54 +1796,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, break; case CURLOPT_COOKIELIST: - if(!ptr) - break; - - if(strcasecompare(ptr, "ALL")) { - /* clear all cookies */ - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - Curl_cookie_clearall(data->cookies); - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - } - else if(strcasecompare(ptr, "SESS")) { - /* clear session cookies */ - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - Curl_cookie_clearsess(data->cookies); - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - } - else if(strcasecompare(ptr, "FLUSH")) { - /* flush cookies to file, takes care of the locking */ - Curl_flush_cookies(data, FALSE); - } - else if(strcasecompare(ptr, "RELOAD")) { - /* reload cookies from file */ - Curl_cookie_loadfiles(data); - break; - } - else { - if(!data->cookies) { - /* if cookie engine was not running, activate it */ - data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE); - if(!data->cookies) - return CURLE_OUT_OF_MEMORY; - } - - /* general protection against mistakes and abuse */ - if(strlen(ptr) > CURL_MAX_INPUT_LENGTH) - return CURLE_BAD_FUNCTION_ARGUMENT; - - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - if(checkprefix("Set-Cookie:", ptr)) - /* HTTP Header format line */ - Curl_cookie_add(data, data->cookies, TRUE, FALSE, ptr + 11, NULL, - NULL, TRUE); - else - /* Netscape format line */ - Curl_cookie_add(data, data->cookies, FALSE, FALSE, ptr, NULL, - NULL, TRUE); - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - } - break; + return cookielist(data, ptr); #endif /* !CURL_DISABLE_COOKIES */ #endif /* ! CURL_DISABLE_HTTP */ @@ -1930,10 +1805,10 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, /* * Set a custom string to use as request */ - return Curl_setstropt(&data->set.str[STRING_CUSTOMREQUEST], ptr); + return Curl_setstropt(&s->str[STRING_CUSTOMREQUEST], ptr); /* we do not set - data->set.method = HTTPREQ_CUSTOM; + s->method = HTTPREQ_CUSTOM; here, we continue as if we were using the already set type and this just changes the actual request keyword */ @@ -1949,7 +1824,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * Setting it to NULL, means no proxy but allows the environment variables * to decide for us (if CURLOPT_SOCKS_PROXY setting it to NULL). */ - return Curl_setstropt(&data->set.str[STRING_PROXY], ptr); + return Curl_setstropt(&s->str[STRING_PROXY], ptr); case CURLOPT_PRE_PROXY: /* @@ -1958,7 +1833,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * If the proxy is set to "" or NULL we explicitly say that we do not want * to use the socks proxy. */ - return Curl_setstropt(&data->set.str[STRING_PRE_PROXY], ptr); + return Curl_setstropt(&s->str[STRING_PRE_PROXY], ptr); #endif /* CURL_DISABLE_PROXY */ #ifndef CURL_DISABLE_PROXY @@ -1967,58 +1842,58 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, /* * Set proxy authentication service name for Kerberos 5 and SPNEGO */ - return Curl_setstropt(&data->set.str[STRING_PROXY_SERVICE_NAME], ptr); + return Curl_setstropt(&s->str[STRING_PROXY_SERVICE_NAME], ptr); #endif case CURLOPT_SERVICE_NAME: /* * Set authentication service name for DIGEST-MD5, Kerberos 5 and SPNEGO */ - return Curl_setstropt(&data->set.str[STRING_SERVICE_NAME], ptr); + return Curl_setstropt(&s->str[STRING_SERVICE_NAME], ptr); case CURLOPT_HEADERDATA: /* * Custom pointer to pass the header write callback function */ - data->set.writeheader = ptr; + s->writeheader = ptr; break; case CURLOPT_READDATA: /* * FILE pointer to read the file to be uploaded from. Or possibly used as * argument to the read callback. */ - data->set.in_set = ptr; + s->in_set = ptr; break; case CURLOPT_WRITEDATA: /* * FILE pointer to write to. Or possibly used as argument to the write * callback. */ - data->set.out = ptr; + s->out = ptr; break; case CURLOPT_DEBUGDATA: /* * Set to a void * that should receive all error writes. This * defaults to CURLOPT_STDERR for normal operations. */ - data->set.debugdata = ptr; + s->debugdata = ptr; break; case CURLOPT_PROGRESSDATA: /* * Custom client data to pass to the progress callback */ - data->set.progress_client = ptr; + s->progress_client = ptr; break; case CURLOPT_SEEKDATA: /* * Seek control callback. Might be NULL. */ - data->set.seek_client = ptr; + s->seek_client = ptr; break; case CURLOPT_IOCTLDATA: /* * I/O control data pointer. Might be NULL. */ - data->set.ioctl_client = ptr; + s->ioctl_client = ptr; break; case CURLOPT_SSL_CTX_DATA: /* @@ -2026,7 +1901,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, */ #ifdef USE_SSL if(Curl_ssl_supports(data, SSLSUPP_SSL_CTX)) { - data->set.ssl.fsslctxp = ptr; + s->ssl.fsslctxp = ptr; break; } else @@ -2036,33 +1911,33 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, /* * socket callback data pointer. Might be NULL. */ - data->set.sockopt_client = ptr; + s->sockopt_client = ptr; break; case CURLOPT_OPENSOCKETDATA: /* * socket callback data pointer. Might be NULL. */ - data->set.opensocket_client = ptr; + s->opensocket_client = ptr; break; case CURLOPT_RESOLVER_START_DATA: /* * resolver start callback data pointer. Might be NULL. */ - data->set.resolver_start_client = ptr; + s->resolver_start_client = ptr; break; case CURLOPT_CLOSESOCKETDATA: /* * socket callback data pointer. Might be NULL. */ - data->set.closesocket_client = ptr; + s->closesocket_client = ptr; break; case CURLOPT_TRAILERDATA: #ifndef CURL_DISABLE_HTTP - data->set.trailer_data = ptr; + s->trailer_data = ptr; #endif break; case CURLOPT_PREREQDATA: - data->set.prereq_userp = ptr; + s->prereq_userp = ptr; break; case CURLOPT_ERRORBUFFER: @@ -2070,7 +1945,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * Error buffer provided by the caller to get the human readable error * string in. */ - data->set.errorbuffer = ptr; + s->errorbuffer = ptr; break; #ifndef CURL_DISABLE_FTP @@ -2078,23 +1953,23 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, /* * Use FTP PORT, this also specifies which IP address to use */ - result = Curl_setstropt(&data->set.str[STRING_FTPPORT], ptr); - data->set.ftp_use_port = !!(data->set.str[STRING_FTPPORT]); + result = Curl_setstropt(&s->str[STRING_FTPPORT], ptr); + s->ftp_use_port = !!(s->str[STRING_FTPPORT]); break; case CURLOPT_FTP_ACCOUNT: - return Curl_setstropt(&data->set.str[STRING_FTP_ACCOUNT], ptr); + return Curl_setstropt(&s->str[STRING_FTP_ACCOUNT], ptr); case CURLOPT_FTP_ALTERNATIVE_TO_USER: - return Curl_setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER], ptr); + return Curl_setstropt(&s->str[STRING_FTP_ALTERNATIVE_TO_USER], ptr); #ifdef HAVE_GSSAPI case CURLOPT_KRBLEVEL: /* * A string that defines the kerberos security level. */ - result = Curl_setstropt(&data->set.str[STRING_KRB_LEVEL], ptr); - data->set.krb = !!(data->set.str[STRING_KRB_LEVEL]); + result = Curl_setstropt(&s->str[STRING_KRB_LEVEL], ptr); + s->krb = !!(s->str[STRING_KRB_LEVEL]); break; #endif #endif @@ -2106,40 +1981,40 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, Curl_safefree(data->state.url); data->state.url_alloc = FALSE; } - result = Curl_setstropt(&data->set.str[STRING_SET_URL], ptr); - data->state.url = data->set.str[STRING_SET_URL]; + result = Curl_setstropt(&s->str[STRING_SET_URL], ptr); + data->state.url = s->str[STRING_SET_URL]; break; case CURLOPT_USERPWD: /* * user:password to use in the operation */ - return setstropt_userpwd(ptr, &data->set.str[STRING_USERNAME], - &data->set.str[STRING_PASSWORD]); + return setstropt_userpwd(ptr, &s->str[STRING_USERNAME], + &s->str[STRING_PASSWORD]); case CURLOPT_USERNAME: /* * authentication username to use in the operation */ - return Curl_setstropt(&data->set.str[STRING_USERNAME], ptr); + return Curl_setstropt(&s->str[STRING_USERNAME], ptr); case CURLOPT_PASSWORD: /* * authentication password to use in the operation */ - return Curl_setstropt(&data->set.str[STRING_PASSWORD], ptr); + return Curl_setstropt(&s->str[STRING_PASSWORD], ptr); case CURLOPT_LOGIN_OPTIONS: /* * authentication options to use in the operation */ - return Curl_setstropt(&data->set.str[STRING_OPTIONS], ptr); + return Curl_setstropt(&s->str[STRING_OPTIONS], ptr); case CURLOPT_XOAUTH2_BEARER: /* * OAuth 2.0 bearer token to use in the operation */ - return Curl_setstropt(&data->set.str[STRING_BEARER], ptr); + return Curl_setstropt(&s->str[STRING_BEARER], ptr); #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXYUSERPWD: { @@ -2152,13 +2027,13 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, /* URL decode the components */ if(!result && u) { - Curl_safefree(data->set.str[STRING_PROXYUSERNAME]); - result = Curl_urldecode(u, 0, &data->set.str[STRING_PROXYUSERNAME], NULL, + Curl_safefree(s->str[STRING_PROXYUSERNAME]); + result = Curl_urldecode(u, 0, &s->str[STRING_PROXYUSERNAME], NULL, REJECT_ZERO); } if(!result && p) { - Curl_safefree(data->set.str[STRING_PROXYPASSWORD]); - result = Curl_urldecode(p, 0, &data->set.str[STRING_PROXYPASSWORD], NULL, + Curl_safefree(s->str[STRING_PROXYPASSWORD]); + result = Curl_urldecode(p, 0, &s->str[STRING_PROXYPASSWORD], NULL, REJECT_ZERO); } free(u); @@ -2169,26 +2044,26 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, /* * authentication username to use in the operation */ - return Curl_setstropt(&data->set.str[STRING_PROXYUSERNAME], ptr); + return Curl_setstropt(&s->str[STRING_PROXYUSERNAME], ptr); case CURLOPT_PROXYPASSWORD: /* * authentication password to use in the operation */ - return Curl_setstropt(&data->set.str[STRING_PROXYPASSWORD], ptr); + return Curl_setstropt(&s->str[STRING_PROXYPASSWORD], ptr); case CURLOPT_NOPROXY: /* * proxy exception list */ - return Curl_setstropt(&data->set.str[STRING_NOPROXY], ptr); + return Curl_setstropt(&s->str[STRING_NOPROXY], ptr); #endif /* ! CURL_DISABLE_PROXY */ case CURLOPT_RANGE: /* * What range of the file you want to transfer */ - return Curl_setstropt(&data->set.str[STRING_SET_RANGE], ptr); + return Curl_setstropt(&s->str[STRING_SET_RANGE], ptr); case CURLOPT_CURLU: /* @@ -2200,77 +2075,77 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, } else data->state.url = NULL; - Curl_safefree(data->set.str[STRING_SET_URL]); - data->set.uh = (CURLU *)ptr; + Curl_safefree(s->str[STRING_SET_URL]); + s->uh = (CURLU *)ptr; break; case CURLOPT_SSLCERT: /* * String that holds filename of the SSL certificate to use */ - return Curl_setstropt(&data->set.str[STRING_CERT], ptr); + return Curl_setstropt(&s->str[STRING_CERT], ptr); #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_SSLCERT: /* * String that holds filename of the SSL certificate to use for proxy */ - return Curl_setstropt(&data->set.str[STRING_CERT_PROXY], ptr); + return Curl_setstropt(&s->str[STRING_CERT_PROXY], ptr); #endif case CURLOPT_SSLCERTTYPE: /* * String that holds file type of the SSL certificate to use */ - return Curl_setstropt(&data->set.str[STRING_CERT_TYPE], ptr); + return Curl_setstropt(&s->str[STRING_CERT_TYPE], ptr); #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_SSLCERTTYPE: /* * String that holds file type of the SSL certificate to use for proxy */ - return Curl_setstropt(&data->set.str[STRING_CERT_TYPE_PROXY], ptr); + return Curl_setstropt(&s->str[STRING_CERT_TYPE_PROXY], ptr); #endif case CURLOPT_SSLKEY: /* * String that holds filename of the SSL key to use */ - return Curl_setstropt(&data->set.str[STRING_KEY], ptr); + return Curl_setstropt(&s->str[STRING_KEY], ptr); #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_SSLKEY: /* * String that holds filename of the SSL key to use for proxy */ - return Curl_setstropt(&data->set.str[STRING_KEY_PROXY], ptr); + return Curl_setstropt(&s->str[STRING_KEY_PROXY], ptr); #endif case CURLOPT_SSLKEYTYPE: /* * String that holds file type of the SSL key to use */ - return Curl_setstropt(&data->set.str[STRING_KEY_TYPE], ptr); + return Curl_setstropt(&s->str[STRING_KEY_TYPE], ptr); #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_SSLKEYTYPE: /* * String that holds file type of the SSL key to use for proxy */ - return Curl_setstropt(&data->set.str[STRING_KEY_TYPE_PROXY], ptr); + return Curl_setstropt(&s->str[STRING_KEY_TYPE_PROXY], ptr); #endif case CURLOPT_KEYPASSWD: /* * String that holds the SSL or SSH private key password. */ - return Curl_setstropt(&data->set.str[STRING_KEY_PASSWD], ptr); + return Curl_setstropt(&s->str[STRING_KEY_PASSWD], ptr); #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_KEYPASSWD: /* * String that holds the SSL private key password for proxy. */ - return Curl_setstropt(&data->set.str[STRING_KEY_PASSWD_PROXY], ptr); + return Curl_setstropt(&s->str[STRING_KEY_PASSWD_PROXY], ptr); #endif case CURLOPT_SSLENGINE: @@ -2278,7 +2153,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * String that holds the SSL crypto engine. */ if(ptr && ptr[0]) { - result = Curl_setstropt(&data->set.str[STRING_SSL_ENGINE], ptr); + result = Curl_setstropt(&s->str[STRING_SSL_ENGINE], ptr); if(!result) { result = Curl_ssl_set_engine(data, ptr); } @@ -2290,9 +2165,9 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, /* * Set the client IP to send through HAProxy PROXY protocol */ - result = Curl_setstropt(&data->set.str[STRING_HAPROXY_CLIENT_IP], ptr); + result = Curl_setstropt(&s->str[STRING_HAPROXY_CLIENT_IP], ptr); /* enable the HAProxy protocol */ - data->set.haproxyprotocol = TRUE; + s->haproxyprotocol = TRUE; break; #endif @@ -2302,9 +2177,9 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * performing an operation and thus what from-IP your connection will use. */ return setstropt_interface(ptr, - &data->set.str[STRING_DEVICE], - &data->set.str[STRING_INTERFACE], - &data->set.str[STRING_BINDHOST]); + &s->str[STRING_DEVICE], + &s->str[STRING_INTERFACE], + &s->str[STRING_BINDHOST]); case CURLOPT_PINNEDPUBLICKEY: /* @@ -2313,7 +2188,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, */ #ifdef USE_SSL if(Curl_ssl_supports(data, SSLSUPP_PINNEDPUBKEY)) - return Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY], ptr); + return Curl_setstropt(&s->str[STRING_SSL_PINNEDPUBLICKEY], ptr); #endif return CURLE_NOT_BUILT_IN; @@ -2325,7 +2200,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, */ #ifdef USE_SSL if(Curl_ssl_supports(data, SSLSUPP_PINNEDPUBKEY)) - return Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY], + return Curl_setstropt(&s->str[STRING_SSL_PINNEDPUBLICKEY_PROXY], ptr); #endif return CURLE_NOT_BUILT_IN; @@ -2334,7 +2209,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, /* * Set CA info for SSL connection. Specify filename of the CA certificate */ - return Curl_setstropt(&data->set.str[STRING_SSL_CAFILE], ptr); + return Curl_setstropt(&s->str[STRING_SSL_CAFILE], ptr); #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_CAINFO: @@ -2342,7 +2217,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * Set CA info SSL connection for proxy. Specify filename of the * CA certificate */ - return Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_PROXY], ptr); + return Curl_setstropt(&s->str[STRING_SSL_CAFILE_PROXY], ptr); #endif case CURLOPT_CAPATH: @@ -2353,7 +2228,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, #ifdef USE_SSL if(Curl_ssl_supports(data, SSLSUPP_CA_PATH)) /* This does not work on Windows. */ - return Curl_setstropt(&data->set.str[STRING_SSL_CAPATH], ptr); + return Curl_setstropt(&s->str[STRING_SSL_CAPATH], ptr); #endif return CURLE_NOT_BUILT_IN; #ifndef CURL_DISABLE_PROXY @@ -2365,7 +2240,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, #ifdef USE_SSL if(Curl_ssl_supports(data, SSLSUPP_CA_PATH)) /* This does not work on Windows. */ - return Curl_setstropt(&data->set.str[STRING_SSL_CAPATH_PROXY], ptr); + return Curl_setstropt(&s->str[STRING_SSL_CAPATH_PROXY], ptr); #endif return CURLE_NOT_BUILT_IN; #endif @@ -2374,7 +2249,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * Set CRL file info for SSL connection. Specify filename of the CRL * to check certificates revocation */ - return Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE], ptr); + return Curl_setstropt(&s->str[STRING_SSL_CRLFILE], ptr); #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_CRLFILE: @@ -2382,7 +2257,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * Set CRL file info for SSL connection for proxy. Specify filename of the * CRL to check certificates revocation */ - return Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE_PROXY], ptr); + return Curl_setstropt(&s->str[STRING_SSL_CRLFILE_PROXY], ptr); #endif case CURLOPT_ISSUERCERT: @@ -2390,7 +2265,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * Set Issuer certificate file * to check certificates issuer */ - return Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT], ptr); + return Curl_setstropt(&s->str[STRING_SSL_ISSUERCERT], ptr); #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_ISSUERCERT: @@ -2398,14 +2273,14 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * Set Issuer certificate file * to check certificates issuer */ - return Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT_PROXY], ptr); + return Curl_setstropt(&s->str[STRING_SSL_ISSUERCERT_PROXY], ptr); #endif case CURLOPT_PRIVATE: /* * Set private data pointer. */ - data->set.private_data = ptr; + s->private_data = ptr; break; #ifdef USE_SSL @@ -2414,7 +2289,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * Set accepted curves in SSL connection setup. * Specify colon-delimited list of curve algorithm names. */ - return Curl_setstropt(&data->set.str[STRING_SSL_EC_CURVES], ptr); + return Curl_setstropt(&s->str[STRING_SSL_EC_CURVES], ptr); case CURLOPT_SSL_SIGNATURE_ALGORITHMS: /* @@ -2422,7 +2297,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * Specify colon-delimited list of signature scheme names. */ if(Curl_ssl_supports(data, SSLSUPP_SIGNATURE_ALGORITHMS)) - return Curl_setstropt(&data->set.str[STRING_SSL_SIGNATURE_ALGORITHMS], + return Curl_setstropt(&s->str[STRING_SSL_SIGNATURE_ALGORITHMS], ptr); return CURLE_NOT_BUILT_IN; #endif @@ -2431,13 +2306,13 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, /* * Use this file instead of the $HOME/.ssh/id_dsa.pub file */ - return Curl_setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY], ptr); + return Curl_setstropt(&s->str[STRING_SSH_PUBLIC_KEY], ptr); case CURLOPT_SSH_PRIVATE_KEYFILE: /* * Use this file instead of the $HOME/.ssh/id_dsa file */ - return Curl_setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY], ptr); + return Curl_setstropt(&s->str[STRING_SSH_PRIVATE_KEY], ptr); #if defined(USE_LIBSSH2) || defined(USE_LIBSSH) case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5: @@ -2445,19 +2320,19 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * Option to allow for the MD5 of the host public key to be checked * for validation purposes. */ - return Curl_setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], ptr); + return Curl_setstropt(&s->str[STRING_SSH_HOST_PUBLIC_KEY_MD5], ptr); case CURLOPT_SSH_KNOWNHOSTS: /* * Store the filename to read known hosts from. */ - return Curl_setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS], ptr); + return Curl_setstropt(&s->str[STRING_SSH_KNOWNHOSTS], ptr); #endif case CURLOPT_SSH_KEYDATA: /* * Custom client data to pass to the SSH keyfunc callback */ - data->set.ssh_keyfunc_userp = ptr; + s->ssh_keyfunc_userp = ptr; break; #ifdef USE_LIBSSH2 case CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256: @@ -2465,47 +2340,47 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * Option to allow for the SHA256 of the host public key to be checked * for validation purposes. */ - return Curl_setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_SHA256], + return Curl_setstropt(&s->str[STRING_SSH_HOST_PUBLIC_KEY_SHA256], ptr); case CURLOPT_SSH_HOSTKEYDATA: /* * Custom client data to pass to the SSH keyfunc callback */ - data->set.ssh_hostkeyfunc_userp = ptr; + s->ssh_hostkeyfunc_userp = ptr; break; #endif /* USE_LIBSSH2 */ #endif /* USE_SSH */ case CURLOPT_PROTOCOLS_STR: if(ptr) - return protocol2num(ptr, &data->set.allowed_protocols); + return protocol2num(ptr, &s->allowed_protocols); /* make a NULL argument reset to default */ - data->set.allowed_protocols = (curl_prot_t) CURLPROTO_ALL; + s->allowed_protocols = (curl_prot_t) CURLPROTO_ALL; break; case CURLOPT_REDIR_PROTOCOLS_STR: if(ptr) - return protocol2num(ptr, &data->set.redir_protocols); + return protocol2num(ptr, &s->redir_protocols); /* make a NULL argument reset to default */ - data->set.redir_protocols = (curl_prot_t) CURLPROTO_REDIR; + s->redir_protocols = (curl_prot_t) CURLPROTO_REDIR; break; case CURLOPT_DEFAULT_PROTOCOL: /* Set the protocol to use when the URL does not include any protocol */ - return Curl_setstropt(&data->set.str[STRING_DEFAULT_PROTOCOL], ptr); + return Curl_setstropt(&s->str[STRING_DEFAULT_PROTOCOL], ptr); #ifndef CURL_DISABLE_SMTP case CURLOPT_MAIL_FROM: /* Set the SMTP mail originator */ - return Curl_setstropt(&data->set.str[STRING_MAIL_FROM], ptr); + return Curl_setstropt(&s->str[STRING_MAIL_FROM], ptr); case CURLOPT_MAIL_AUTH: /* Set the SMTP auth originator */ - return Curl_setstropt(&data->set.str[STRING_MAIL_AUTH], ptr); + return Curl_setstropt(&s->str[STRING_MAIL_AUTH], ptr); #endif case CURLOPT_SASL_AUTHZID: /* Authorization identity (identity to act as) */ - return Curl_setstropt(&data->set.str[STRING_SASL_AUTHZID], ptr); + return Curl_setstropt(&s->str[STRING_SASL_AUTHZID], ptr); #ifndef CURL_DISABLE_RTSP case CURLOPT_RTSP_SESSION_ID: @@ -2513,81 +2388,81 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * Set the RTSP Session ID manually. Useful if the application is * resuming a previously established RTSP session */ - return Curl_setstropt(&data->set.str[STRING_RTSP_SESSION_ID], ptr); + return Curl_setstropt(&s->str[STRING_RTSP_SESSION_ID], ptr); case CURLOPT_RTSP_STREAM_URI: /* * Set the Stream URI for the RTSP request. Unless the request is * for generic server options, the application will need to set this. */ - return Curl_setstropt(&data->set.str[STRING_RTSP_STREAM_URI], ptr); + return Curl_setstropt(&s->str[STRING_RTSP_STREAM_URI], ptr); case CURLOPT_RTSP_TRANSPORT: /* * The content of the Transport: header for the RTSP request */ - return Curl_setstropt(&data->set.str[STRING_RTSP_TRANSPORT], ptr); + return Curl_setstropt(&s->str[STRING_RTSP_TRANSPORT], ptr); case CURLOPT_INTERLEAVEDATA: - data->set.rtp_out = ptr; + s->rtp_out = ptr; break; #endif /* ! CURL_DISABLE_RTSP */ #ifndef CURL_DISABLE_FTP case CURLOPT_CHUNK_DATA: - data->set.wildcardptr = ptr; + s->wildcardptr = ptr; break; case CURLOPT_FNMATCH_DATA: - data->set.fnmatch_data = ptr; + s->fnmatch_data = ptr; break; #endif #ifdef USE_TLS_SRP case CURLOPT_TLSAUTH_USERNAME: - return Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME], ptr); + return Curl_setstropt(&s->str[STRING_TLSAUTH_USERNAME], ptr); #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_TLSAUTH_USERNAME: - return Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_PROXY], ptr); + return Curl_setstropt(&s->str[STRING_TLSAUTH_USERNAME_PROXY], ptr); #endif case CURLOPT_TLSAUTH_PASSWORD: - return Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD], ptr); + return Curl_setstropt(&s->str[STRING_TLSAUTH_PASSWORD], ptr); #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_TLSAUTH_PASSWORD: - return Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_PROXY], ptr); + return Curl_setstropt(&s->str[STRING_TLSAUTH_PASSWORD_PROXY], ptr); #endif case CURLOPT_TLSAUTH_TYPE: - if(ptr && !strcasecompare(ptr, "SRP")) + if(ptr && !curl_strequal(ptr, "SRP")) return CURLE_BAD_FUNCTION_ARGUMENT; break; #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_TLSAUTH_TYPE: - if(ptr && !strcasecompare(ptr, "SRP")) + if(ptr && !curl_strequal(ptr, "SRP")) return CURLE_BAD_FUNCTION_ARGUMENT; break; #endif #endif #ifdef CURLRES_ARES case CURLOPT_DNS_SERVERS: - result = Curl_setstropt(&data->set.str[STRING_DNS_SERVERS], ptr); + result = Curl_setstropt(&s->str[STRING_DNS_SERVERS], ptr); if(result) return result; return Curl_async_ares_set_dns_servers(data); case CURLOPT_DNS_INTERFACE: - result = Curl_setstropt(&data->set.str[STRING_DNS_INTERFACE], ptr); + result = Curl_setstropt(&s->str[STRING_DNS_INTERFACE], ptr); if(result) return result; return Curl_async_ares_set_dns_interface(data); case CURLOPT_DNS_LOCAL_IP4: - result = Curl_setstropt(&data->set.str[STRING_DNS_LOCAL_IP4], ptr); + result = Curl_setstropt(&s->str[STRING_DNS_LOCAL_IP4], ptr); if(result) return result; return Curl_async_ares_set_dns_local_ip4(data); case CURLOPT_DNS_LOCAL_IP6: - result = Curl_setstropt(&data->set.str[STRING_DNS_LOCAL_IP6], ptr); + result = Curl_setstropt(&s->str[STRING_DNS_LOCAL_IP6], ptr); if(result) return result; return Curl_async_ares_set_dns_local_ip6(data); @@ -2595,27 +2470,27 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, #endif #ifdef USE_UNIX_SOCKETS case CURLOPT_UNIX_SOCKET_PATH: - data->set.abstract_unix_socket = FALSE; - return Curl_setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH], ptr); + s->abstract_unix_socket = FALSE; + return Curl_setstropt(&s->str[STRING_UNIX_SOCKET_PATH], ptr); case CURLOPT_ABSTRACT_UNIX_SOCKET: - data->set.abstract_unix_socket = TRUE; - return Curl_setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH], ptr); + s->abstract_unix_socket = TRUE; + return Curl_setstropt(&s->str[STRING_UNIX_SOCKET_PATH], ptr); #endif #ifndef CURL_DISABLE_DOH case CURLOPT_DOH_URL: - result = Curl_setstropt(&data->set.str[STRING_DOH], ptr); - data->set.doh = !!(data->set.str[STRING_DOH]); + result = Curl_setstropt(&s->str[STRING_DOH], ptr); + s->doh = !!(s->str[STRING_DOH]); break; #endif #ifndef CURL_DISABLE_HSTS case CURLOPT_HSTSREADDATA: - data->set.hsts_read_userp = ptr; + s->hsts_read_userp = ptr; break; case CURLOPT_HSTSWRITEDATA: - data->set.hsts_write_userp = ptr; + s->hsts_write_userp = ptr; break; case CURLOPT_HSTS: { struct curl_slist *h; @@ -2625,7 +2500,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, return CURLE_OUT_OF_MEMORY; } if(ptr) { - result = Curl_setstropt(&data->set.str[STRING_HSTS], ptr); + result = Curl_setstropt(&s->str[STRING_HSTS], ptr); if(result) return result; /* this needs to build a list of filenames to read from, so that it can @@ -2657,7 +2532,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, if(!data->asi) return CURLE_OUT_OF_MEMORY; } - result = Curl_setstropt(&data->set.str[STRING_ALTSVC], ptr); + result = Curl_setstropt(&s->str[STRING_ALTSVC], ptr); if(result) return result; if(ptr) @@ -2669,35 +2544,35 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, size_t plen = 0; if(!ptr) { - data->set.tls_ech = CURLECH_DISABLE; + s->tls_ech = CURLECH_DISABLE; return CURLE_OK; } plen = strlen(ptr); if(plen > CURL_MAX_INPUT_LENGTH) { - data->set.tls_ech = CURLECH_DISABLE; + s->tls_ech = CURLECH_DISABLE; return CURLE_BAD_FUNCTION_ARGUMENT; } /* set tls_ech flag value, preserving CLA_CFG bit */ if(!strcmp(ptr, "false")) - data->set.tls_ech = CURLECH_DISABLE | - (data->set.tls_ech & CURLECH_CLA_CFG); + s->tls_ech = CURLECH_DISABLE | + (s->tls_ech & CURLECH_CLA_CFG); else if(!strcmp(ptr, "grease")) - data->set.tls_ech = CURLECH_GREASE | - (data->set.tls_ech & CURLECH_CLA_CFG); + s->tls_ech = CURLECH_GREASE | + (s->tls_ech & CURLECH_CLA_CFG); else if(!strcmp(ptr, "true")) - data->set.tls_ech = CURLECH_ENABLE | - (data->set.tls_ech & CURLECH_CLA_CFG); + s->tls_ech = CURLECH_ENABLE | + (s->tls_ech & CURLECH_CLA_CFG); else if(!strcmp(ptr, "hard")) - data->set.tls_ech = CURLECH_HARD | - (data->set.tls_ech & CURLECH_CLA_CFG); + s->tls_ech = CURLECH_HARD | + (s->tls_ech & CURLECH_CLA_CFG); else if(plen > 5 && !strncmp(ptr, "ecl:", 4)) { - result = Curl_setstropt(&data->set.str[STRING_ECH_CONFIG], ptr + 4); + result = Curl_setstropt(&s->str[STRING_ECH_CONFIG], ptr + 4); if(result) return result; - data->set.tls_ech |= CURLECH_CLA_CFG; + s->tls_ech |= CURLECH_CLA_CFG; } else if(plen > 4 && !strncmp(ptr, "pn:", 3)) { - result = Curl_setstropt(&data->set.str[STRING_ECH_PUBLIC], ptr + 3); + result = Curl_setstropt(&s->str[STRING_ECH_PUBLIC], ptr + 3); if(result) return result; } @@ -2713,13 +2588,14 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, static CURLcode setopt_func(struct Curl_easy *data, CURLoption option, va_list param) { + struct UserDefined *s = &data->set; switch(option) { case CURLOPT_PROGRESSFUNCTION: /* * Progress callback function */ - data->set.fprogress = va_arg(param, curl_progress_callback); - if(data->set.fprogress) + s->fprogress = va_arg(param, curl_progress_callback); + if(s->fprogress) data->progress.callback = TRUE; /* no longer internal */ else data->progress.callback = FALSE; /* NULL enforces internal */ @@ -2729,8 +2605,8 @@ static CURLcode setopt_func(struct Curl_easy *data, CURLoption option, /* * Transfer info callback function */ - data->set.fxferinfo = va_arg(param, curl_xferinfo_callback); - if(data->set.fxferinfo) + s->fxferinfo = va_arg(param, curl_xferinfo_callback); + if(s->fxferinfo) data->progress.callback = TRUE; /* no longer internal */ else data->progress.callback = FALSE; /* NULL enforces internal */ @@ -2740,7 +2616,7 @@ static CURLcode setopt_func(struct Curl_easy *data, CURLoption option, /* * stderr write callback. */ - data->set.fdebug = va_arg(param, curl_debug_callback); + s->fdebug = va_arg(param, curl_debug_callback); /* * if the callback provided is NULL, it will use the default callback */ @@ -2749,41 +2625,41 @@ static CURLcode setopt_func(struct Curl_easy *data, CURLoption option, /* * Set header write callback */ - data->set.fwrite_header = va_arg(param, curl_write_callback); + s->fwrite_header = va_arg(param, curl_write_callback); break; case CURLOPT_WRITEFUNCTION: /* * Set data write callback */ - data->set.fwrite_func = va_arg(param, curl_write_callback); - if(!data->set.fwrite_func) + s->fwrite_func = va_arg(param, curl_write_callback); + if(!s->fwrite_func) /* When set to NULL, reset to our internal default function */ - data->set.fwrite_func = (curl_write_callback)fwrite; + s->fwrite_func = (curl_write_callback)fwrite; break; case CURLOPT_READFUNCTION: /* * Read data callback */ - data->set.fread_func_set = va_arg(param, curl_read_callback); - if(!data->set.fread_func_set) { - data->set.is_fread_set = 0; + s->fread_func_set = va_arg(param, curl_read_callback); + if(!s->fread_func_set) { + s->is_fread_set = 0; /* When set to NULL, reset to our internal default function */ - data->set.fread_func_set = (curl_read_callback)fread; + s->fread_func_set = (curl_read_callback)fread; } else - data->set.is_fread_set = 1; + s->is_fread_set = 1; break; case CURLOPT_SEEKFUNCTION: /* * Seek callback. Might be NULL. */ - data->set.seek_func = va_arg(param, curl_seek_callback); + s->seek_func = va_arg(param, curl_seek_callback); break; case CURLOPT_IOCTLFUNCTION: /* * I/O control callback. Might be NULL. */ - data->set.ioctl_func = va_arg(param, curl_ioctl_callback); + s->ioctl_func = va_arg(param, curl_ioctl_callback); break; case CURLOPT_SSL_CTX_FUNCTION: /* @@ -2791,7 +2667,7 @@ static CURLcode setopt_func(struct Curl_easy *data, CURLoption option, */ #ifdef USE_SSL if(Curl_ssl_supports(data, SSLSUPP_SSL_CTX)) { - data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback); + s->ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback); break; } else @@ -2802,7 +2678,7 @@ static CURLcode setopt_func(struct Curl_easy *data, CURLoption option, /* * socket callback function: called after socket() but before connect() */ - data->set.fsockopt = va_arg(param, curl_sockopt_callback); + s->fsockopt = va_arg(param, curl_sockopt_callback); break; case CURLOPT_OPENSOCKETFUNCTION: @@ -2810,7 +2686,7 @@ static CURLcode setopt_func(struct Curl_easy *data, CURLoption option, * open/create socket callback function: called instead of socket(), * before connect() */ - data->set.fopensocket = va_arg(param, curl_opensocket_callback); + s->fopensocket = va_arg(param, curl_opensocket_callback); break; case CURLOPT_CLOSESOCKETFUNCTION: @@ -2818,7 +2694,7 @@ static CURLcode setopt_func(struct Curl_easy *data, CURLoption option, * close socket callback function: called instead of close() * when shutting down a connection */ - data->set.fclosesocket = va_arg(param, curl_closesocket_callback); + s->fclosesocket = va_arg(param, curl_closesocket_callback); break; case CURLOPT_RESOLVER_START_FUNCTION: @@ -2826,21 +2702,21 @@ static CURLcode setopt_func(struct Curl_easy *data, CURLoption option, * resolver start callback function: called before a new resolver request * is started */ - data->set.resolver_start = va_arg(param, curl_resolver_start_callback); + s->resolver_start = va_arg(param, curl_resolver_start_callback); break; #ifdef USE_SSH #ifdef USE_LIBSSH2 case CURLOPT_SSH_HOSTKEYFUNCTION: /* the callback to check the hostkey without the knownhost file */ - data->set.ssh_hostkeyfunc = va_arg(param, curl_sshhostkeycallback); + s->ssh_hostkeyfunc = va_arg(param, curl_sshhostkeycallback); break; #endif case CURLOPT_SSH_KEYFUNCTION: /* setting to NULL is fine since the ssh.c functions themselves will then revert to use the internal default */ - data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback); + s->ssh_keyfunc = va_arg(param, curl_sshkeycallback); break; #endif /* USE_SSH */ @@ -2848,35 +2724,35 @@ static CURLcode setopt_func(struct Curl_easy *data, CURLoption option, #ifndef CURL_DISABLE_RTSP case CURLOPT_INTERLEAVEFUNCTION: /* Set the user defined RTP write function */ - data->set.fwrite_rtp = va_arg(param, curl_write_callback); + s->fwrite_rtp = va_arg(param, curl_write_callback); break; #endif #ifndef CURL_DISABLE_FTP case CURLOPT_CHUNK_BGN_FUNCTION: - data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback); + s->chunk_bgn = va_arg(param, curl_chunk_bgn_callback); break; case CURLOPT_CHUNK_END_FUNCTION: - data->set.chunk_end = va_arg(param, curl_chunk_end_callback); + s->chunk_end = va_arg(param, curl_chunk_end_callback); break; case CURLOPT_FNMATCH_FUNCTION: - data->set.fnmatch = va_arg(param, curl_fnmatch_callback); + s->fnmatch = va_arg(param, curl_fnmatch_callback); break; #endif #ifndef CURL_DISABLE_HTTP case CURLOPT_TRAILERFUNCTION: - data->set.trailer_callback = va_arg(param, curl_trailer_callback); + s->trailer_callback = va_arg(param, curl_trailer_callback); break; #endif #ifndef CURL_DISABLE_HSTS case CURLOPT_HSTSREADFUNCTION: - data->set.hsts_read = va_arg(param, curl_hstsread_callback); + s->hsts_read = va_arg(param, curl_hstsread_callback); break; case CURLOPT_HSTSWRITEFUNCTION: - data->set.hsts_write = va_arg(param, curl_hstswrite_callback); + s->hsts_write = va_arg(param, curl_hstswrite_callback); break; #endif case CURLOPT_PREREQFUNCTION: - data->set.fprereq = va_arg(param, curl_prereq_callback); + s->fprereq = va_arg(param, curl_prereq_callback); break; default: return CURLE_UNKNOWN_OPTION; @@ -2887,13 +2763,14 @@ static CURLcode setopt_func(struct Curl_easy *data, CURLoption option, static CURLcode setopt_offt(struct Curl_easy *data, CURLoption option, curl_off_t offt) { + struct UserDefined *s = &data->set; switch(option) { case CURLOPT_TIMEVALUE_LARGE: /* * This is the value to compare with the remote document with the * method set with CURLOPT_TIMECONDITION */ - data->set.timevalue = (time_t)offt; + s->timevalue = (time_t)offt; break; /* MQTT "borrows" some of the HTTP options */ @@ -2905,13 +2782,13 @@ static CURLcode setopt_offt(struct Curl_easy *data, CURLoption option, if(offt < -1) return CURLE_BAD_FUNCTION_ARGUMENT; - if(data->set.postfieldsize < offt && - data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { + if(s->postfieldsize < offt && + s->postfields == s->str[STRING_COPYPOSTFIELDS]) { /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ - Curl_safefree(data->set.str[STRING_COPYPOSTFIELDS]); - data->set.postfields = NULL; + Curl_safefree(s->str[STRING_COPYPOSTFIELDS]); + s->postfields = NULL; } - data->set.postfieldsize = offt; + s->postfieldsize = offt; break; case CURLOPT_INFILESIZE_LARGE: /* @@ -2920,7 +2797,7 @@ static CURLcode setopt_offt(struct Curl_easy *data, CURLoption option, */ if(offt < -1) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.filesize = offt; + s->filesize = offt; break; case CURLOPT_MAX_SEND_SPEED_LARGE: /* @@ -2929,7 +2806,7 @@ static CURLcode setopt_offt(struct Curl_easy *data, CURLoption option, */ if(offt < 0) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.max_send_speed = offt; + s->max_send_speed = offt; break; case CURLOPT_MAX_RECV_SPEED_LARGE: /* @@ -2938,7 +2815,7 @@ static CURLcode setopt_offt(struct Curl_easy *data, CURLoption option, */ if(offt < 0) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.max_recv_speed = offt; + s->max_recv_speed = offt; break; case CURLOPT_RESUME_FROM_LARGE: /* @@ -2946,7 +2823,7 @@ static CURLcode setopt_offt(struct Curl_easy *data, CURLoption option, */ if(offt < -1) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.set_resume_from = offt; + s->set_resume_from = offt; break; case CURLOPT_MAXFILESIZE_LARGE: /* @@ -2954,7 +2831,7 @@ static CURLcode setopt_offt(struct Curl_easy *data, CURLoption option, */ if(offt < 0) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.max_filesize = offt; + s->max_filesize = offt; break; default: @@ -2966,23 +2843,24 @@ static CURLcode setopt_offt(struct Curl_easy *data, CURLoption option, static CURLcode setopt_blob(struct Curl_easy *data, CURLoption option, struct curl_blob *blob) { + struct UserDefined *s = &data->set; switch(option) { case CURLOPT_SSLCERT_BLOB: /* * Blob that holds file content of the SSL certificate to use */ - return Curl_setblobopt(&data->set.blobs[BLOB_CERT], blob); + return Curl_setblobopt(&s->blobs[BLOB_CERT], blob); #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_SSLCERT_BLOB: /* * Blob that holds file content of the SSL certificate to use for proxy */ - return Curl_setblobopt(&data->set.blobs[BLOB_CERT_PROXY], blob); + return Curl_setblobopt(&s->blobs[BLOB_CERT_PROXY], blob); case CURLOPT_PROXY_SSLKEY_BLOB: /* * Blob that holds file content of the SSL key to use for proxy */ - return Curl_setblobopt(&data->set.blobs[BLOB_KEY_PROXY], blob); + return Curl_setblobopt(&s->blobs[BLOB_KEY_PROXY], blob); case CURLOPT_PROXY_CAINFO_BLOB: /* * Blob that holds CA info for SSL connection proxy. @@ -2990,21 +2868,21 @@ static CURLcode setopt_blob(struct Curl_easy *data, CURLoption option, */ #ifdef USE_SSL if(Curl_ssl_supports(data, SSLSUPP_CAINFO_BLOB)) - return Curl_setblobopt(&data->set.blobs[BLOB_CAINFO_PROXY], blob); + return Curl_setblobopt(&s->blobs[BLOB_CAINFO_PROXY], blob); #endif return CURLE_NOT_BUILT_IN; case CURLOPT_PROXY_ISSUERCERT_BLOB: /* * Blob that holds Issuer certificate to check certificates issuer */ - return Curl_setblobopt(&data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY], + return Curl_setblobopt(&s->blobs[BLOB_SSL_ISSUERCERT_PROXY], blob); #endif case CURLOPT_SSLKEY_BLOB: /* * Blob that holds file content of the SSL key to use */ - return Curl_setblobopt(&data->set.blobs[BLOB_KEY], blob); + return Curl_setblobopt(&s->blobs[BLOB_KEY], blob); case CURLOPT_CAINFO_BLOB: /* * Blob that holds CA info for SSL connection. @@ -3012,14 +2890,14 @@ static CURLcode setopt_blob(struct Curl_easy *data, CURLoption option, */ #ifdef USE_SSL if(Curl_ssl_supports(data, SSLSUPP_CAINFO_BLOB)) - return Curl_setblobopt(&data->set.blobs[BLOB_CAINFO], blob); + return Curl_setblobopt(&s->blobs[BLOB_CAINFO], blob); #endif return CURLE_NOT_BUILT_IN; case CURLOPT_ISSUERCERT_BLOB: /* * Blob that holds Issuer certificate to check certificates issuer */ - return Curl_setblobopt(&data->set.blobs[BLOB_SSL_ISSUERCERT], blob); + return Curl_setblobopt(&s->blobs[BLOB_SSL_ISSUERCERT], blob); default: return CURLE_UNKNOWN_OPTION; diff --git a/vendor/curl/lib/setopt.h b/vendor/curl/lib/setopt.h index b0237467bd6..c323dd74a37 100644 --- a/vendor/curl/lib/setopt.h +++ b/vendor/curl/lib/setopt.h @@ -24,6 +24,13 @@ * ***************************************************************************/ +#ifdef USE_SSL +CURLcode Curl_setopt_SSLVERSION(struct Curl_easy *data, CURLoption option, + long arg); +#else +#define Curl_setopt_SSLVERSION(a,b,c) CURLE_NOT_BUILT_IN +#endif + CURLcode Curl_setstropt(char **charp, const char *s) WARN_UNUSED_RESULT; CURLcode Curl_setblobopt(struct curl_blob **blobp, const struct curl_blob *blob) WARN_UNUSED_RESULT; diff --git a/vendor/curl/lib/setup-vms.h b/vendor/curl/lib/setup-vms.h index d74f4ad6305..0fd5e542b77 100644 --- a/vendor/curl/lib/setup-vms.h +++ b/vendor/curl/lib/setup-vms.h @@ -374,11 +374,9 @@ static struct passwd *vms_getpwuid(uid_t uid) #ifdef HAVE_NETDB_H #include #ifndef AI_NUMERICHOST -#ifdef USE_IPV6 #undef USE_IPV6 #endif #endif -#endif /* VAX symbols are always in uppercase */ #ifdef __VAX diff --git a/vendor/curl/lib/setup-win32.h b/vendor/curl/lib/setup-win32.h index 35fe513a842..02177a7a3b7 100644 --- a/vendor/curl/lib/setup-win32.h +++ b/vendor/curl/lib/setup-win32.h @@ -30,10 +30,10 @@ /* ---------------------------------------------------------------- */ #ifdef USE_WATT32 # include +# include # undef byte # undef word # define HAVE_SYS_IOCTL_H -# define HAVE_SYS_SOCKET_H # define HAVE_NETINET_IN_H # define HAVE_NETDB_H # define HAVE_ARPA_INET_H @@ -82,9 +82,6 @@ # include # include # include -# ifdef UNICODE - typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str); -# endif #endif /* diff --git a/vendor/curl/lib/sha256.c b/vendor/curl/lib/sha256.c index d73e0ef0937..ca026782a3d 100644 --- a/vendor/curl/lib/sha256.c +++ b/vendor/curl/lib/sha256.c @@ -25,8 +25,8 @@ #include "curl_setup.h" -#if !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) \ - || defined(USE_LIBSSH2) || defined(USE_SSL) +#if !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) || \ + defined(USE_LIBSSH2) || defined(USE_SSL) #include "curlx/warnless.h" #include "curl_sha256.h" @@ -134,10 +134,10 @@ typedef mbedtls_sha256_context my_sha256_ctx; static CURLcode my_sha256_init(void *ctx) { -#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS) - (void) mbedtls_sha256_starts(ctx, 0); +#ifndef HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS + (void)mbedtls_sha256_starts(ctx, 0); #else - (void) mbedtls_sha256_starts_ret(ctx, 0); + (void)mbedtls_sha256_starts_ret(ctx, 0); #endif return CURLE_OK; } @@ -146,19 +146,19 @@ static void my_sha256_update(void *ctx, const unsigned char *data, unsigned int length) { -#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS) - (void) mbedtls_sha256_update(ctx, data, length); +#ifndef HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS + (void)mbedtls_sha256_update(ctx, data, length); #else - (void) mbedtls_sha256_update_ret(ctx, data, length); + (void)mbedtls_sha256_update_ret(ctx, data, length); #endif } static void my_sha256_final(unsigned char *digest, void *ctx) { -#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS) - (void) mbedtls_sha256_finish(ctx, digest); +#ifndef HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS + (void)mbedtls_sha256_finish(ctx, digest); #else - (void) mbedtls_sha256_finish_ret(ctx, digest); + (void)mbedtls_sha256_finish_ret(ctx, digest); #endif } @@ -167,7 +167,7 @@ typedef CC_SHA256_CTX my_sha256_ctx; static CURLcode my_sha256_init(void *ctx) { - (void) CC_SHA256_Init(ctx); + (void)CC_SHA256_Init(ctx); return CURLE_OK; } @@ -175,12 +175,12 @@ static void my_sha256_update(void *ctx, const unsigned char *data, unsigned int length) { - (void) CC_SHA256_Update(ctx, data, length); + (void)CC_SHA256_Update(ctx, data, length); } static void my_sha256_final(unsigned char *digest, void *ctx) { - (void) CC_SHA256_Final(digest, ctx); + (void)CC_SHA256_Final(digest, ctx); } #elif defined(USE_WIN32_CRYPTO) @@ -191,7 +191,8 @@ struct sha256_ctx { }; typedef struct sha256_ctx my_sha256_ctx; -#if !defined(CALG_SHA_256) +/* Offered when targeting Vista (XP SP2+) */ +#ifndef CALG_SHA_256 #define CALG_SHA_256 0x0000800c #endif diff --git a/vendor/curl/lib/smb.c b/vendor/curl/lib/smb.c index ceca9564bf1..81cf6e7cc1f 100644 --- a/vendor/curl/lib/smb.c +++ b/vendor/curl/lib/smb.c @@ -36,6 +36,7 @@ #include "connect.h" #include "progress.h" #include "transfer.h" +#include "select.h" #include "vtls/vtls.h" #include "curl_ntlm_core.h" #include "escape.h" @@ -298,8 +299,8 @@ static CURLcode smb_connect(struct Curl_easy *data, bool *done); static CURLcode smb_connection_state(struct Curl_easy *data, bool *done); static CURLcode smb_do(struct Curl_easy *data, bool *done); static CURLcode smb_request_state(struct Curl_easy *data, bool *done); -static int smb_getsock(struct Curl_easy *data, struct connectdata *conn, - curl_socket_t *socks); +static CURLcode smb_pollset(struct Curl_easy *data, + struct easy_pollset *ps); static CURLcode smb_parse_url_path(struct Curl_easy *data, struct smb_conn *smbc, struct smb_request *req); @@ -316,10 +317,10 @@ const struct Curl_handler Curl_handler_smb = { smb_connect, /* connect_it */ smb_connection_state, /* connecting */ smb_request_state, /* doing */ - smb_getsock, /* proto_getsock */ - smb_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + smb_pollset, /* proto_pollset */ + smb_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ ZERO_NULL, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -345,10 +346,10 @@ const struct Curl_handler Curl_handler_smbs = { smb_connect, /* connect_it */ smb_connection_state, /* connecting */ smb_request_state, /* doing */ - smb_getsock, /* proto_getsock */ - smb_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + smb_pollset, /* proto_pollset */ + smb_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ ZERO_NULL, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -496,7 +497,7 @@ static CURLcode smb_connect(struct Curl_easy *data, bool *done) struct smb_conn *smbc = Curl_conn_meta_get(conn, CURL_META_SMB_CONN); char *slash; - (void) done; + (void)done; if(!smbc) return CURLE_FAILED_INIT; @@ -543,7 +544,7 @@ static CURLcode smb_recv_message(struct Curl_easy *data, void **msg) { char *buf = smbc->recv_buf; - ssize_t bytes_read; + size_t bytes_read; size_t nbt_size; size_t msg_size; size_t len = MAX_MESSAGE_SIZE - smbc->got; @@ -999,8 +1000,8 @@ static CURLcode smb_connection_state(struct Curl_easy *data, bool *done) */ static void get_posix_time(time_t *out, curl_off_t timestamp) { - if(timestamp >= CURL_OFF_T_C(116444736000000000)) { - timestamp -= CURL_OFF_T_C(116444736000000000); + if(timestamp >= (curl_off_t)116444736000000000) { + timestamp -= (curl_off_t)116444736000000000; timestamp /= 10000000; #if SIZEOF_TIME_T < SIZEOF_CURL_OFF_T if(timestamp > TIME_T_MAX) @@ -1204,12 +1205,10 @@ static CURLcode smb_request_state(struct Curl_easy *data, bool *done) return CURLE_OK; } -static int smb_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks) +static CURLcode smb_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { - (void)data; - socks[0] = conn->sock[FIRSTSOCKET]; - return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0); + return Curl_pollset_add_inout(data, ps, data->conn->sock[FIRSTSOCKET]); } static CURLcode smb_do(struct Curl_easy *data, bool *done) @@ -1267,5 +1266,4 @@ static CURLcode smb_parse_url_path(struct Curl_easy *data, return CURLE_OK; } -#endif /* CURL_DISABLE_SMB && USE_CURL_NTLM_CORE && - SIZEOF_CURL_OFF_T > 4 */ +#endif /* CURL_DISABLE_SMB && USE_CURL_NTLM_CORE && SIZEOF_CURL_OFF_T > 4 */ diff --git a/vendor/curl/lib/smb.h b/vendor/curl/lib/smb.h index eb4df6550a3..aa0be881c13 100644 --- a/vendor/curl/lib/smb.h +++ b/vendor/curl/lib/smb.h @@ -26,12 +26,11 @@ ***************************************************************************/ #if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \ - (SIZEOF_CURL_OFF_T > 4) + (SIZEOF_CURL_OFF_T > 4) extern const struct Curl_handler Curl_handler_smb; extern const struct Curl_handler Curl_handler_smbs; -#endif /* CURL_DISABLE_SMB && USE_CURL_NTLM_CORE && - SIZEOF_CURL_OFF_T > 4 */ +#endif /* CURL_DISABLE_SMB && USE_CURL_NTLM_CORE && SIZEOF_CURL_OFF_T > 4 */ #endif /* HEADER_CURL_SMB_H */ diff --git a/vendor/curl/lib/smtp.c b/vendor/curl/lib/smtp.c index d39bb58d5de..97083e41f8b 100644 --- a/vendor/curl/lib/smtp.c +++ b/vendor/curl/lib/smtp.c @@ -68,7 +68,6 @@ #include "mime.h" #include "socks.h" #include "smtp.h" -#include "strcase.h" #include "vtls/vtls.h" #include "cfilters.h" #include "connect.h" @@ -158,8 +157,8 @@ static CURLcode smtp_connect(struct Curl_easy *data, bool *done); static CURLcode smtp_disconnect(struct Curl_easy *data, struct connectdata *conn, bool dead); static CURLcode smtp_multi_statemach(struct Curl_easy *data, bool *done); -static int smtp_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks); +static CURLcode smtp_pollset(struct Curl_easy *data, + struct easy_pollset *ps); static CURLcode smtp_doing(struct Curl_easy *data, bool *dophase_done); static CURLcode smtp_setup_connection(struct Curl_easy *data, struct connectdata *conn); @@ -170,7 +169,8 @@ static CURLcode smtp_parse_url_path(struct Curl_easy *data, static CURLcode smtp_parse_custom_request(struct Curl_easy *data, struct SMTP *smtp); static CURLcode smtp_parse_address(const char *fqma, - char **address, struct hostname *host); + char **address, struct hostname *host, + const char **suffix); static CURLcode smtp_perform_auth(struct Curl_easy *data, const char *mech, const struct bufref *initresp); static CURLcode smtp_continue_auth(struct Curl_easy *data, const char *mech, @@ -192,10 +192,10 @@ const struct Curl_handler Curl_handler_smtp = { smtp_connect, /* connect_it */ smtp_multi_statemach, /* connecting */ smtp_doing, /* doing */ - smtp_getsock, /* proto_getsock */ - smtp_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + smtp_pollset, /* proto_pollset */ + smtp_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ smtp_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -223,10 +223,10 @@ const struct Curl_handler Curl_handler_smtps = { smtp_connect, /* connect_it */ smtp_multi_statemach, /* connecting */ smtp_doing, /* doing */ - smtp_getsock, /* proto_getsock */ - smtp_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + smtp_pollset, /* proto_pollset */ + smtp_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ smtp_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -358,7 +358,7 @@ static void smtp_state(struct Curl_easy *data, struct smtp_conn *smtpc, smtpstate newstate) { -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) +#ifndef CURL_DISABLE_VERBOSE_STRINGS /* for debug purposes */ static const char * const names[] = { "STOP", @@ -380,6 +380,8 @@ static void smtp_state(struct Curl_easy *data, if(smtpc->state != newstate) CURL_TRC_SMTP(data, "state change from %s to %s", names[smtpc->state], names[newstate]); +#else + (void)data; #endif smtpc->state = newstate; @@ -619,11 +621,12 @@ static CURLcode smtp_perform_command(struct Curl_easy *data, if((!smtp->custom) || (!smtp->custom[0])) { char *address = NULL; struct hostname host = { NULL, NULL, NULL, NULL }; + const char *suffix = ""; /* Parse the mailbox to verify into the local address and hostname parts, converting the hostname to an IDN A-label if necessary */ result = smtp_parse_address(smtp->rcpt->data, - &address, &host); + &address, &host, &suffix); if(result) return result; @@ -693,11 +696,12 @@ static CURLcode smtp_perform_mail(struct Curl_easy *data, if(data->set.str[STRING_MAIL_FROM]) { char *address = NULL; struct hostname host = { NULL, NULL, NULL, NULL }; + const char *suffix = ""; /* Parse the FROM mailbox into the local address and hostname parts, converting the hostname to an IDN A-label if necessary */ result = smtp_parse_address(data->set.str[STRING_MAIL_FROM], - &address, &host); + &address, &host, &suffix); if(result) goto out; @@ -708,14 +712,14 @@ static CURLcode smtp_perform_mail(struct Curl_easy *data, (!Curl_is_ASCII_name(host.name))); if(host.name) { - from = aprintf("<%s@%s>", address, host.name); + from = aprintf("<%s@%s>%s", address, host.name, suffix); Curl_free_idnconverted_hostname(&host); } else /* An invalid mailbox was provided but we will simply let the server worry about that and reply with a 501 error */ - from = aprintf("<%s>", address); + from = aprintf("<%s>%s", address, suffix); free(address); } @@ -733,11 +737,12 @@ static CURLcode smtp_perform_mail(struct Curl_easy *data, if(data->set.str[STRING_MAIL_AUTH][0] != '\0') { char *address = NULL; struct hostname host = { NULL, NULL, NULL, NULL }; + const char *suffix = ""; /* Parse the AUTH mailbox into the local address and hostname parts, converting the hostname to an IDN A-label if necessary */ result = smtp_parse_address(data->set.str[STRING_MAIL_AUTH], - &address, &host); + &address, &host, &suffix); if(result) goto out; @@ -749,14 +754,14 @@ static CURLcode smtp_perform_mail(struct Curl_easy *data, utf8 = TRUE; if(host.name) { - auth = aprintf("<%s@%s>", address, host.name); + auth = aprintf("<%s@%s>%s", address, host.name, suffix); Curl_free_idnconverted_hostname(&host); } else /* An invalid mailbox was provided but we will simply let the server worry about it */ - auth = aprintf("<%s>", address); + auth = aprintf("<%s>%s", address, suffix); free(address); } else @@ -866,22 +871,24 @@ static CURLcode smtp_perform_rcpt_to(struct Curl_easy *data, CURLcode result = CURLE_OK; char *address = NULL; struct hostname host = { NULL, NULL, NULL, NULL }; + const char *suffix = ""; /* Parse the recipient mailbox into the local address and hostname parts, converting the hostname to an IDN A-label if necessary */ result = smtp_parse_address(smtp->rcpt->data, - &address, &host); + &address, &host, &suffix); if(result) return result; /* Send the RCPT TO command */ if(host.name) - result = Curl_pp_sendf(data, &smtpc->pp, "RCPT TO:<%s@%s>", - address, host.name); + result = Curl_pp_sendf(data, &smtpc->pp, "RCPT TO:<%s@%s>%s", + address, host.name, suffix); else /* An invalid mailbox was provided but we will simply let the server worry about that and reply with a 501 error */ - result = Curl_pp_sendf(data, &smtpc->pp, "RCPT TO:<%s>", address); + result = Curl_pp_sendf(data, &smtpc->pp, "RCPT TO:<%s>%s", + address, suffix); Curl_free_idnconverted_hostname(&host); free(address); @@ -1250,7 +1257,7 @@ static CURLcode smtp_state_data_resp(struct Curl_easy *data, Curl_pgrsSetUploadSize(data, data->state.infilesize); /* SMTP upload */ - Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE); + Curl_xfer_setup_send(data, FIRSTSOCKET); /* End of DO phase */ smtp_state(data, smtpc, SMTP_STOP); @@ -1406,12 +1413,12 @@ static CURLcode smtp_block_statemach(struct Curl_easy *data, } /* For the SMTP "protocol connect" and "doing" phases only */ -static int smtp_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks) +static CURLcode smtp_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { - struct smtp_conn *smtpc = Curl_conn_meta_get(conn, CURL_META_SMTP_CONN); - return smtpc ? - Curl_pp_getsock(data, &smtpc->pp, socks) : GETSOCK_BLANK; + struct smtp_conn *smtpc = + Curl_conn_meta_get(data->conn, CURL_META_SMTP_CONN); + return smtpc ? Curl_pp_pollset(data, &smtpc->pp, ps) : CURLE_OK; } /*********************************************************************** @@ -1625,13 +1632,12 @@ static CURLcode smtp_disconnect(struct Curl_easy *data, bad in any way, sending quit and waiting around here will make the disconnect wait in vain and cause more problems than we need to. */ - if(!dead_connection && conn->bits.protoconnstart) { + if(!dead_connection && conn->bits.protoconnstart && + !Curl_pp_needs_flush(data, &smtpc->pp)) { if(!smtp_perform_quit(data, smtpc)) (void)smtp_block_statemach(data, smtpc, TRUE); /* ignore on QUIT */ } - /* Cleanup the SASL module */ - Curl_sasl_cleanup(conn, smtpc->sasl.authused); CURL_TRC_SMTP(data, "smtp_disconnect(), finished"); return CURLE_OK; } @@ -1776,7 +1782,7 @@ static CURLcode smtp_parse_url_options(struct connectdata *conn, while(*ptr && *ptr != ';') ptr++; - if(strncasecompare(key, "AUTH=", 5)) + if(curl_strnequal(key, "AUTH=", 5)) result = Curl_sasl_parse_url_auth_option(&smtpc->sasl, value, ptr - value); else @@ -1868,10 +1874,11 @@ static CURLcode smtp_parse_custom_request(struct Curl_easy *data, * the address part with the hostname being NULL. */ static CURLcode smtp_parse_address(const char *fqma, char **address, - struct hostname *host) + struct hostname *host, const char **suffix) { CURLcode result = CURLE_OK; size_t length; + char *addressend; /* Duplicate the fully qualified email address so we can manipulate it, ensuring it does not contain the delimiters if specified */ @@ -1879,10 +1886,19 @@ static CURLcode smtp_parse_address(const char *fqma, char **address, if(!dup) return CURLE_OUT_OF_MEMORY; - length = strlen(dup); - if(length) { - if(dup[length - 1] == '>') - dup[length - 1] = '\0'; + if(fqma[0] != '<') { + length = strlen(dup); + if(length) { + if(dup[length - 1] == '>') + dup[length - 1] = '\0'; + } + } + else { + addressend = strrchr(dup, '>'); + if(addressend) { + *addressend = '\0'; + *suffix = addressend + 1; + } } /* Extract the hostname from the address (if we can) */ @@ -1892,7 +1908,7 @@ static CURLcode smtp_parse_address(const char *fqma, char **address, host->name = host->name + 1; /* Attempt to convert the hostname to IDN ACE */ - (void) Curl_idnconvert_hostname(host); + (void)Curl_idnconvert_hostname(host); /* If Curl_idnconvert_hostname() fails then we shall attempt to continue and send the hostname using UTF-8 rather than as 7-bit ACE (which is @@ -2007,7 +2023,7 @@ static CURLcode cr_eob_read(struct Curl_easy *data, eob = &SMTP_EOB[2]; break; case 3: - /* ended with '\r\n.', we should escpe the last '.' */ + /* ended with '\r\n.', we should escape the last '.' */ eob = "." SMTP_EOB; break; default: diff --git a/vendor/curl/lib/socketpair.c b/vendor/curl/lib/socketpair.c index 1d1d5a66f30..93df9071eff 100644 --- a/vendor/curl/lib/socketpair.c +++ b/vendor/curl/lib/socketpair.c @@ -84,6 +84,7 @@ int Curl_pipe(curl_socket_t socks[2], bool nonblocking) #ifndef CURL_DISABLE_SOCKETPAIR #ifdef HAVE_SOCKETPAIR +#ifdef USE_SOCKETPAIR int Curl_socketpair(int domain, int type, int protocol, curl_socket_t socks[2], bool nonblocking) { @@ -104,6 +105,7 @@ int Curl_socketpair(int domain, int type, int protocol, #endif return 0; } +#endif /* USE_SOCKETPAIR */ #else /* !HAVE_SOCKETPAIR */ #ifdef _WIN32 /* diff --git a/vendor/curl/lib/socketpair.h b/vendor/curl/lib/socketpair.h index 5541899445b..e601f5f71be 100644 --- a/vendor/curl/lib/socketpair.h +++ b/vendor/curl/lib/socketpair.h @@ -66,8 +66,9 @@ int Curl_pipe(curl_socket_t socks[2], bool nonblocking); #define SOCKETPAIR_TYPE SOCK_STREAM #endif -#define wakeup_create(p,nb)\ -Curl_socketpair(SOCKETPAIR_FAMILY, SOCKETPAIR_TYPE, 0, p, nb) +#define USE_SOCKETPAIR +#define wakeup_create(p,nb) \ + Curl_socketpair(SOCKETPAIR_FAMILY, SOCKETPAIR_TYPE, 0, p, nb) #endif /* USE_EVENTFD */ diff --git a/vendor/curl/lib/socks.c b/vendor/curl/lib/socks.c index 08bc874f117..4f9c98dbaad 100644 --- a/vendor/curl/lib/socks.c +++ b/vendor/curl/lib/socks.c @@ -24,7 +24,7 @@ #include "curl_setup.h" -#if !defined(CURL_DISABLE_PROXY) +#ifndef CURL_DISABLE_PROXY #ifdef HAVE_NETINET_IN_H #include @@ -81,7 +81,7 @@ enum connect_t { struct socks_state { enum connect_t state; - ssize_t outstanding; /* send this many bytes more */ + size_t outstanding; /* send this many bytes more */ unsigned char buffer[CURL_SOCKS_BUF_SIZE]; unsigned char *outp; /* send from this pointer */ @@ -101,66 +101,55 @@ struct socks_state { int Curl_blockread_all(struct Curl_cfilter *cf, struct Curl_easy *data, /* transfer */ char *buf, /* store read data here */ - ssize_t buffersize, /* max amount to read */ - ssize_t *n) /* amount bytes read */ + size_t blen, /* space in buf */ + size_t *pnread) /* amount bytes read */ { - ssize_t nread = 0; - ssize_t allread = 0; - int result; - CURLcode err = CURLE_OK; + size_t nread = 0; + CURLcode err; - *n = 0; + *pnread = 0; for(;;) { timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); if(timeout_ms < 0) { /* we already got the timeout */ - result = CURLE_OPERATION_TIMEDOUT; - break; + return CURLE_OPERATION_TIMEDOUT; } if(!timeout_ms) timeout_ms = TIMEDIFF_T_MAX; if(SOCKET_READABLE(cf->conn->sock[cf->sockindex], timeout_ms) <= 0) { - result = ~CURLE_OK; - break; - } - nread = Curl_conn_cf_recv(cf->next, data, buf, buffersize, &err); - if(nread <= 0) { - result = (int)err; - if(CURLE_AGAIN == err) - continue; - if(err) { - break; - } + return ~CURLE_OK; } - - if(buffersize == nread) { - allread += nread; - *n = allread; - result = CURLE_OK; - break; - } - if(!nread) { - result = ~CURLE_OK; - break; + err = Curl_conn_cf_recv(cf->next, data, buf, blen, &nread); + if(CURLE_AGAIN == err) + continue; + else if(err) + return (int)err; + + if(blen == nread) { + *pnread += nread; + return CURLE_OK; } + if(!nread) /* EOF */ + return ~CURLE_OK; - buffersize -= nread; buf += nread; - allread += nread; + blen -= nread; + *pnread += nread; } - return result; } #endif #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) #define DEBUG_AND_VERBOSE -#define sxstate(x,d,y) socksstate(x,d,y, __LINE__) +#define sxstate(x,c,d,y) socksstate(x,c,d,y, __LINE__) #else -#define sxstate(x,d,y) socksstate(x,d,y) +#define sxstate(x,c,d,y) socksstate(x,c,d,y) #endif /* always use this function to change state, to make debugging easier */ -static void socksstate(struct socks_state *sx, struct Curl_easy *data, +static void socksstate(struct socks_state *sx, + struct Curl_cfilter *cf, + struct Curl_easy *data, enum connect_t state #ifdef DEBUG_AND_VERBOSE , int lineno @@ -192,6 +181,7 @@ static void socksstate(struct socks_state *sx, struct Curl_easy *data, }; #endif + (void)cf; (void)data; if(oldstate == state) /* do not bother when the new state is the same as the old state */ @@ -200,10 +190,8 @@ static void socksstate(struct socks_state *sx, struct Curl_easy *data, sx->state = state; #ifdef DEBUG_AND_VERBOSE - infof(data, - "SXSTATE: %s => %s; line %d", - socks_statename[oldstate], socks_statename[sx->state], - lineno); + CURL_TRC_CF(data, cf, "[%s] -> [%s] (line %d)", + socks_statename[oldstate], socks_statename[sx->state], lineno); #endif } @@ -213,24 +201,25 @@ static CURLproxycode socks_state_send(struct Curl_cfilter *cf, CURLproxycode failcode, const char *description) { - ssize_t nwritten; + size_t nwritten; CURLcode result; - nwritten = Curl_conn_cf_send(cf->next, data, (char *)sx->outp, - sx->outstanding, FALSE, &result); - if(nwritten <= 0) { - if(CURLE_AGAIN == result) { + result = Curl_conn_cf_send(cf->next, data, (char *)sx->outp, + sx->outstanding, FALSE, &nwritten); + if(result) { + if(CURLE_AGAIN == result) return CURLPX_OK; - } - else if(CURLE_OK == result) { - /* connection closed */ - failf(data, "connection to proxy closed"); - return CURLPX_CLOSED; - } + failf(data, "Failed to send %s: %s", description, curl_easy_strerror(result)); return failcode; } + else if(!nwritten) { + /* connection closed */ + failf(data, "connection to proxy closed"); + return CURLPX_CLOSED; + } + DEBUGASSERT(sx->outstanding >= nwritten); /* not done, remain in state */ sx->outstanding -= nwritten; @@ -244,24 +233,24 @@ static CURLproxycode socks_state_recv(struct Curl_cfilter *cf, CURLproxycode failcode, const char *description) { - ssize_t nread; + size_t nread; CURLcode result; - nread = Curl_conn_cf_recv(cf->next, data, (char *)sx->outp, - sx->outstanding, &result); - if(nread <= 0) { - if(CURLE_AGAIN == result) { + result = Curl_conn_cf_recv(cf->next, data, (char *)sx->outp, + sx->outstanding, &nread); + if(result) { + if(CURLE_AGAIN == result) return CURLPX_OK; - } - else if(CURLE_OK == result) { - /* connection closed */ - failf(data, "connection to proxy closed"); - return CURLPX_CLOSED; - } + failf(data, "SOCKS: Failed receiving %s: %s", description, curl_easy_strerror(result)); return failcode; } + else if(!nread) { + /* connection closed */ + failf(data, "connection to proxy closed"); + return CURLPX_CLOSED; + } /* remain in reading state */ DEBUGASSERT(sx->outstanding >= nread); sx->outstanding -= nread; @@ -296,12 +285,10 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf, case CONNECT_SOCKS_INIT: /* SOCKS4 can only do IPv4, insist! */ conn->ip_version = CURL_IPRESOLVE_V4; - if(conn->bits.httpproxy) - infof(data, "SOCKS4%s: connecting to HTTP proxy %s port %d", - protocol4a ? "a" : "", sx->hostname, sx->remote_port); - - infof(data, "SOCKS4 communication to %s:%d", - sx->hostname, sx->remote_port); + CURL_TRC_CF(data, cf, "SOCKS4%s communication to%s %s:%d", + protocol4a ? "a" : "", + conn->bits.httpproxy ? " HTTP proxy" : "", + sx->hostname, sx->remote_port); /* * Compose socks4 request @@ -325,18 +312,19 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf, cf->conn->ip_version, TRUE, &dns); if(result == CURLE_AGAIN) { - sxstate(sx, data, CONNECT_RESOLVING); - infof(data, "SOCKS4 non-blocking resolve of %s", sx->hostname); + sxstate(sx, cf, data, CONNECT_RESOLVING); + CURL_TRC_CF(data, cf, "SOCKS4 non-blocking resolve of %s", + sx->hostname); return CURLPX_OK; } else if(result) return CURLPX_RESOLVE_HOST; - sxstate(sx, data, CONNECT_RESOLVED); + sxstate(sx, cf, data, CONNECT_RESOLVED); goto CONNECT_RESOLVED; } /* socks4a does not resolve anything locally */ - sxstate(sx, data, CONNECT_REQ_INIT); + sxstate(sx, cf, data, CONNECT_REQ_INIT); goto CONNECT_REQ_INIT; case CONNECT_RESOLVING: @@ -374,8 +362,8 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf, socksreq[6] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[2]; socksreq[7] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[3]; - infof(data, "SOCKS4 connect to IPv4 %s (locally resolved)", buf); - + CURL_TRC_CF(data, cf, "SOCKS4 connect to IPv4 %s (locally resolved)", + buf); Curl_resolv_unlink(data, &dns); /* not used anymore from now on */ } else @@ -436,7 +424,7 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf, sx->outp = socksreq; DEBUGASSERT(packetsize <= sizeof(sx->buffer)); sx->outstanding = packetsize; - sxstate(sx, data, CONNECT_REQ_SENDING); + sxstate(sx, cf, data, CONNECT_REQ_SENDING); } FALLTHROUGH(); case CONNECT_REQ_SENDING: @@ -452,7 +440,7 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf, /* done sending! */ sx->outstanding = 8; /* receive data size */ sx->outp = socksreq; - sxstate(sx, data, CONNECT_SOCKS_READ); + sxstate(sx, cf, data, CONNECT_SOCKS_READ); FALLTHROUGH(); case CONNECT_SOCKS_READ: @@ -465,7 +453,7 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf, /* remain in reading state */ return CURLPX_OK; } - sxstate(sx, data, CONNECT_DONE); + sxstate(sx, cf, data, CONNECT_DONE); break; default: /* lots of unused states in SOCKS4 */ break; @@ -500,11 +488,11 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf, /* Result */ switch(socksreq[1]) { case 90: - infof(data, "SOCKS4%s request granted.", protocol4a ? "a" : ""); + CURL_TRC_CF(data, cf, "SOCKS4%s request granted.", protocol4a ? "a" : ""); break; case 91: failf(data, - "cannot complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" + "[SOCKS] cannot complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" ", request rejected or failed.", socksreq[4], socksreq[5], socksreq[6], socksreq[7], (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]), @@ -512,7 +500,7 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf, return CURLPX_REQUEST_FAILED; case 92: failf(data, - "cannot complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" + "[SOCKS] cannot complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" ", request rejected because SOCKS server cannot connect to " "identd on the client.", socksreq[4], socksreq[5], socksreq[6], socksreq[7], @@ -521,7 +509,7 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf, return CURLPX_IDENTD; case 93: failf(data, - "cannot complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" + "[SOCKS] cannot complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" ", request rejected because the client program and identd " "report different user-ids.", socksreq[4], socksreq[5], socksreq[6], socksreq[7], @@ -530,7 +518,7 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf, return CURLPX_IDENTD_DIFFER; default: failf(data, - "cannot complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" + "[SOCKS] cannot complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" ", Unknown.", socksreq[4], socksreq[5], socksreq[6], socksreq[7], (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]), @@ -581,8 +569,8 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, switch(sx->state) { case CONNECT_SOCKS_INIT: if(conn->bits.httpproxy) - infof(data, "SOCKS5: connecting to HTTP proxy %s port %d", - sx->hostname, sx->remote_port); + CURL_TRC_CF(data, cf, "SOCKS5: connecting to HTTP proxy %s port %d", + sx->hostname, sx->remote_port); /* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */ if(!socks5_resolve_local && hostname_len > 255) { @@ -592,9 +580,8 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, } if(auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI)) - infof(data, - "warning: unsupported value passed to CURLOPT_SOCKS5_AUTH: %u", - auth); + infof(data, "warning: unsupported value passed to " + "CURLOPT_SOCKS5_AUTH: %u", auth); if(!(auth & CURLAUTH_BASIC)) /* disable username/password auth */ sx->proxy_user = NULL; @@ -603,20 +590,23 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, allow_gssapi = TRUE; #endif - idx = 0; - socksreq[idx++] = 5; /* version */ - idx++; /* number of authentication methods */ - socksreq[idx++] = 0; /* no authentication */ - if(allow_gssapi) - socksreq[idx++] = 1; /* GSS-API */ - if(sx->proxy_user) - socksreq[idx++] = 2; /* username/password */ - /* write the number of authentication methods */ - socksreq[1] = (unsigned char) (idx - 2); + if(!sx->outstanding) { + idx = 0; + socksreq[idx++] = 5; /* version */ + idx++; /* number of authentication methods */ + socksreq[idx++] = 0; /* no authentication */ + if(allow_gssapi) + socksreq[idx++] = 1; /* GSS-API */ + if(sx->proxy_user) + socksreq[idx++] = 2; /* username/password */ + /* write the number of authentication methods */ + socksreq[1] = (unsigned char) (idx - 2); + + sx->outp = socksreq; + DEBUGASSERT(idx <= sizeof(sx->buffer)); + sx->outstanding = idx; + } - sx->outp = socksreq; - DEBUGASSERT(idx <= sizeof(sx->buffer)); - sx->outstanding = idx; presult = socks_state_send(cf, sx, data, CURLPX_SEND_CONNECT, "initial SOCKS5 request"); if(CURLPX_OK != presult) @@ -625,7 +615,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, /* remain in sending state */ return CURLPX_OK; } - sxstate(sx, data, CONNECT_SOCKS_READ); + sxstate(sx, cf, data, CONNECT_SOCKS_READ); goto CONNECT_SOCKS_READ_INIT; case CONNECT_SOCKS_SEND: presult = socks_state_send(cf, sx, data, CURLPX_SEND_CONNECT, @@ -657,17 +647,17 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, } else if(socksreq[1] == 0) { /* DONE! No authentication needed. Send request. */ - sxstate(sx, data, CONNECT_REQ_INIT); + sxstate(sx, cf, data, CONNECT_REQ_INIT); goto CONNECT_REQ_INIT; } else if(socksreq[1] == 2) { /* regular name + password authentication */ - sxstate(sx, data, CONNECT_AUTH_INIT); + sxstate(sx, cf, data, CONNECT_AUTH_INIT); goto CONNECT_AUTH_INIT; } #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) else if(allow_gssapi && (socksreq[1] == 1)) { - sxstate(sx, data, CONNECT_GSSAPI_INIT); + sxstate(sx, cf, data, CONNECT_GSSAPI_INIT); result = Curl_SOCKS5_gssapi_negotiate(cf, data); if(result) { failf(data, "Unable to negotiate SOCKS5 GSS-API context."); @@ -741,7 +731,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, memcpy(socksreq + len, sx->proxy_password, proxy_password_len); } len += proxy_password_len; - sxstate(sx, data, CONNECT_AUTH_SEND); + sxstate(sx, cf, data, CONNECT_AUTH_SEND); DEBUGASSERT(len <= sizeof(sx->buffer)); sx->outstanding = len; sx->outp = socksreq; @@ -758,7 +748,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, } sx->outp = socksreq; sx->outstanding = 2; - sxstate(sx, data, CONNECT_AUTH_READ); + sxstate(sx, cf, data, CONNECT_AUTH_READ); FALLTHROUGH(); case CONNECT_AUTH_READ: presult = socks_state_recv(cf, sx, data, CURLPX_RECV_AUTH, @@ -777,7 +767,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, } /* Everything is good so far, user was authenticated! */ - sxstate(sx, data, CONNECT_REQ_INIT); + sxstate(sx, cf, data, CONNECT_REQ_INIT); FALLTHROUGH(); case CONNECT_REQ_INIT: CONNECT_REQ_INIT: @@ -786,12 +776,12 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, cf->conn->ip_version, TRUE, &dns); if(result == CURLE_AGAIN) { - sxstate(sx, data, CONNECT_RESOLVING); + sxstate(sx, cf, data, CONNECT_RESOLVING); return CURLPX_OK; } else if(result) return CURLPX_RESOLVE_HOST; - sxstate(sx, data, CONNECT_RESOLVED); + sxstate(sx, cf, data, CONNECT_RESOLVED); goto CONNECT_RESOLVED; } goto CONNECT_RESOLVE_REMOTE; @@ -843,8 +833,8 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, socksreq[len++] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[i]; } - infof(data, "SOCKS5 connect to %s:%d (locally resolved)", dest, - sx->remote_port); + CURL_TRC_CF(data, cf, "SOCKS5 connect to %s:%d (locally resolved)", + dest, sx->remote_port); } #ifdef USE_IPV6 else if(hp->ai_family == AF_INET6) { @@ -858,8 +848,8 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, ((unsigned char *)&saddr_in6->sin6_addr.s6_addr)[i]; } - infof(data, "SOCKS5 connect to [%s]:%d (locally resolved)", dest, - sx->remote_port); + CURL_TRC_CF(data, cf, "SOCKS5 connect to [%s]:%d (locally resolved)", + dest, sx->remote_port); } #endif else { @@ -886,7 +876,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, #ifdef USE_IPV6 if(conn->bits.ipv6_ip) { char ip6[16]; - if(1 != curlx_inet_pton(AF_INET6, sx->hostname, ip6)) + if(curlx_inet_pton(AF_INET6, sx->hostname, ip6) != 1) return CURLPX_BAD_ADDRESS_TYPE; socksreq[len++] = 4; memcpy(&socksreq[len], ip6, sizeof(ip6)); @@ -894,7 +884,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, } else #endif - if(1 == curlx_inet_pton(AF_INET, sx->hostname, ip4)) { + if(curlx_inet_pton(AF_INET, sx->hostname, ip4) == 1) { socksreq[len++] = 1; memcpy(&socksreq[len], ip4, sizeof(ip4)); len += sizeof(ip4); @@ -905,8 +895,8 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, memcpy(&socksreq[len], sx->hostname, hostname_len); /* w/o NULL */ len += hostname_len; } - infof(data, "SOCKS5 connect to %s:%d (remotely resolved)", - sx->hostname, sx->remote_port); + CURL_TRC_CF(data, cf, "SOCKS5 connect to %s:%d (remotely resolved)", + sx->hostname, sx->remote_port); } FALLTHROUGH(); @@ -926,7 +916,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, sx->outp = socksreq; DEBUGASSERT(len <= sizeof(sx->buffer)); sx->outstanding = len; - sxstate(sx, data, CONNECT_REQ_SENDING); + sxstate(sx, cf, data, CONNECT_REQ_SENDING); FALLTHROUGH(); case CONNECT_REQ_SENDING: presult = socks_state_send(cf, sx, data, CURLPX_SEND_REQUEST, @@ -945,7 +935,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, #endif sx->outstanding = 10; /* minimum packet size is 10 */ sx->outp = socksreq; - sxstate(sx, data, CONNECT_REQ_READ); + sxstate(sx, cf, data, CONNECT_REQ_READ); FALLTHROUGH(); case CONNECT_REQ_READ: presult = socks_state_recv(cf, sx, data, CURLPX_RECV_REQACK, @@ -1027,10 +1017,10 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, DEBUGASSERT(len <= sizeof(sx->buffer)); sx->outstanding = len - 10; /* get the rest */ sx->outp = &socksreq[10]; - sxstate(sx, data, CONNECT_REQ_READ_MORE); + sxstate(sx, cf, data, CONNECT_REQ_READ_MORE); } else { - sxstate(sx, data, CONNECT_DONE); + sxstate(sx, cf, data, CONNECT_DONE); break; } #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) @@ -1046,9 +1036,9 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, /* remain in reading state */ return CURLPX_OK; } - sxstate(sx, data, CONNECT_DONE); + sxstate(sx, cf, data, CONNECT_DONE); } - infof(data, "SOCKS5 request granted."); + CURL_TRC_CF(data, cf, "SOCKS5 request granted."); return CURLPX_OK; /* Proxy was successful! */ } @@ -1129,7 +1119,7 @@ static CURLcode socks_proxy_cf_connect(struct Curl_cfilter *cf, /* for the secondary socket (FTP), use the "connect to host" * but ignore the "connect to port" (use the secondary port) */ - sxstate(sx, data, CONNECT_SOCKS_INIT); + sxstate(sx, cf, data, CONNECT_SOCKS_INIT); sx->hostname = conn->bits.httpproxy ? conn->http_proxy.host.name : @@ -1149,7 +1139,21 @@ static CURLcode socks_proxy_cf_connect(struct Curl_cfilter *cf, result = connect_SOCKS(cf, sx, data); if(!result && sx->state == CONNECT_DONE) { cf->connected = TRUE; - Curl_verboseconnect(data, conn, cf->sockindex); +#ifndef CURL_DISABLE_VERBOSE_STRINGS + if(Curl_trc_is_verbose(data)) { + struct ip_quadruple ipquad; + bool is_ipv6; + result = Curl_conn_cf_get_ip_info(cf->next, data, &is_ipv6, &ipquad); + if(result) + return result; + infof(data, "Opened %sSOCKS connection from %s port %u to %s port %u " + "(via %s port %u)", + (sockindex == SECONDARYSOCKET) ? "2nd " : "", + ipquad.local_ip, ipquad.local_port, + sx->hostname, sx->remote_port, + ipquad.remote_ip, ipquad.remote_port); + } +#endif socks_proxy_cf_free(cf); } @@ -1157,11 +1161,12 @@ static CURLcode socks_proxy_cf_connect(struct Curl_cfilter *cf, return result; } -static void socks_cf_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) +static CURLcode socks_cf_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { struct socks_state *sx = cf->ctx; + CURLcode result = CURLE_OK; if(!cf->connected && sx) { /* If we are not connected, the filter below is and has nothing @@ -1173,13 +1178,14 @@ static void socks_cf_adjust_pollset(struct Curl_cfilter *cf, case CONNECT_AUTH_READ: case CONNECT_REQ_READ: case CONNECT_REQ_READ_MORE: - Curl_pollset_set_in_only(data, ps, sock); + result = Curl_pollset_set_in_only(data, ps, sock); break; default: - Curl_pollset_set_out_only(data, ps, sock); + result = Curl_pollset_set_out_only(data, ps, sock); break; } } + return result; } static void socks_proxy_cf_close(struct Curl_cfilter *cf, @@ -1199,32 +1205,42 @@ static void socks_proxy_cf_destroy(struct Curl_cfilter *cf, socks_proxy_cf_free(cf); } -static void socks_cf_get_host(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char **phost, - const char **pdisplay_host, - int *pport) +static CURLcode socks_cf_query(struct Curl_cfilter *cf, + struct Curl_easy *data, + int query, int *pres1, void *pres2) { - (void)data; - if(!cf->connected) { - *phost = cf->conn->socks_proxy.host.name; - *pdisplay_host = cf->conn->http_proxy.host.dispname; - *pport = (int)cf->conn->socks_proxy.port; + struct socks_state *sx = cf->ctx; + + switch(query) { + case CF_QUERY_HOST_PORT: + if(sx) { + *pres1 = sx->remote_port; + *((const char **)pres2) = sx->hostname; + return CURLE_OK; + } + break; + case CF_QUERY_ALPN_NEGOTIATED: { + const char **palpn = pres2; + DEBUGASSERT(palpn); + *palpn = NULL; + return CURLE_OK; } - else { - cf->next->cft->get_host(cf->next, data, phost, pdisplay_host, pport); + default: + break; } + return cf->next ? + cf->next->cft->query(cf->next, data, query, pres1, pres2) : + CURLE_UNKNOWN_OPTION; } struct Curl_cftype Curl_cft_socks_proxy = { - "SOCKS-PROXYY", + "SOCKS", CF_TYPE_IP_CONNECT|CF_TYPE_PROXY, 0, socks_proxy_cf_destroy, socks_proxy_cf_connect, socks_proxy_cf_close, Curl_cf_def_shutdown, - socks_cf_get_host, socks_cf_adjust_pollset, Curl_cf_def_data_pending, Curl_cf_def_send, @@ -1232,7 +1248,7 @@ struct Curl_cftype Curl_cft_socks_proxy = { Curl_cf_def_cntrl, Curl_cf_def_conn_is_alive, Curl_cf_def_conn_keep_alive, - Curl_cf_def_query, + socks_cf_query, }; CURLcode Curl_cf_socks_proxy_insert_after(struct Curl_cfilter *cf_at, diff --git a/vendor/curl/lib/socks.h b/vendor/curl/lib/socks.h index a3adcc6e91c..d60796316f7 100644 --- a/vendor/curl/lib/socks.h +++ b/vendor/curl/lib/socks.h @@ -40,8 +40,8 @@ int Curl_blockread_all(struct Curl_cfilter *cf, struct Curl_easy *data, char *buf, - ssize_t buffersize, - ssize_t *n); + size_t blen, + size_t *pnread); #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) /* diff --git a/vendor/curl/lib/socks_gssapi.c b/vendor/curl/lib/socks_gssapi.c index 697e301b772..0a7ddd5ff1d 100644 --- a/vendor/curl/lib/socks_gssapi.c +++ b/vendor/curl/lib/socks_gssapi.c @@ -115,8 +115,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, struct connectdata *conn = cf->conn; curl_socket_t sock = conn->sock[cf->sockindex]; CURLcode code; - ssize_t actualread; - ssize_t nwritten; + size_t actualread; + size_t nwritten; int result; OM_uint32 gss_major_status, gss_minor_status, gss_status; OM_uint32 gss_ret_flags; @@ -199,7 +199,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, gss_release_name(&gss_status, &server); gss_release_buffer(&gss_status, &gss_recv_token); gss_release_buffer(&gss_status, &gss_send_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); failf(data, "Failed to initial GSS-API token."); return CURLE_COULDNT_CONNECT; } @@ -210,26 +210,26 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, us_length = htons((unsigned short)gss_send_token.length); memcpy(socksreq + 2, &us_length, sizeof(short)); - nwritten = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 4, - FALSE, &code); - if(code || (4 != nwritten)) { + code = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 4, + FALSE, &nwritten); + if(code || (nwritten != 4)) { failf(data, "Failed to send GSS-API authentication request."); gss_release_name(&gss_status, &server); gss_release_buffer(&gss_status, &gss_recv_token); gss_release_buffer(&gss_status, &gss_send_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_COULDNT_CONNECT; } - nwritten = Curl_conn_cf_send(cf->next, data, - (char *)gss_send_token.value, - gss_send_token.length, FALSE, &code); - if(code || ((ssize_t)gss_send_token.length != nwritten)) { + code = Curl_conn_cf_send(cf->next, data, + (char *)gss_send_token.value, + gss_send_token.length, FALSE, &nwritten); + if(code || (gss_send_token.length != nwritten)) { failf(data, "Failed to send GSS-API authentication token."); gss_release_name(&gss_status, &server); gss_release_buffer(&gss_status, &gss_recv_token); gss_release_buffer(&gss_status, &gss_send_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_COULDNT_CONNECT; } @@ -254,7 +254,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, if(result || (actualread != 4)) { failf(data, "Failed to receive GSS-API authentication response."); gss_release_name(&gss_status, &server); - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_COULDNT_CONNECT; } @@ -263,7 +263,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, failf(data, "User was rejected by the SOCKS5 server (%d %d).", socksreq[0], socksreq[1]); gss_release_name(&gss_status, &server); - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_COULDNT_CONNECT; } @@ -271,7 +271,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, failf(data, "Invalid GSS-API authentication response type (%d %d).", socksreq[0], socksreq[1]); gss_release_name(&gss_status, &server); - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_COULDNT_CONNECT; } @@ -285,7 +285,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, "Could not allocate memory for GSS-API authentication " "response token."); gss_release_name(&gss_status, &server); - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_OUT_OF_MEMORY; } @@ -296,7 +296,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, failf(data, "Failed to receive GSS-API authentication token."); gss_release_name(&gss_status, &server); gss_release_buffer(&gss_status, &gss_recv_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_COULDNT_CONNECT; } @@ -311,7 +311,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, NULL, NULL, NULL); if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_inquire_context")) { - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); gss_release_name(&gss_status, &gss_client_name); failf(data, "Failed to determine username."); return CURLE_COULDNT_CONNECT; @@ -320,7 +320,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, &gss_send_token, NULL); if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_display_name")) { - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); gss_release_name(&gss_status, &gss_client_name); gss_release_buffer(&gss_status, &gss_send_token); failf(data, "Failed to determine username."); @@ -328,7 +328,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, } user = malloc(gss_send_token.length + 1); if(!user) { - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); gss_release_name(&gss_status, &gss_client_name); gss_release_buffer(&gss_status, &gss_send_token); return CURLE_OUT_OF_MEMORY; @@ -397,7 +397,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, gss_send_token.length = 1; gss_send_token.value = Curl_memdup(&gss_enc, 1); if(!gss_send_token.value) { - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_OUT_OF_MEMORY; } @@ -408,7 +408,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_wrap")) { gss_release_buffer(&gss_status, &gss_send_token); gss_release_buffer(&gss_status, &gss_w_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); failf(data, "Failed to wrap GSS-API encryption value into token."); return CURLE_COULDNT_CONNECT; } @@ -418,33 +418,32 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, memcpy(socksreq + 2, &us_length, sizeof(short)); } - nwritten = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 4, FALSE, - &code); - if(code || (4 != nwritten)) { + code = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 4, FALSE, + &nwritten); + if(code || (nwritten != 4)) { failf(data, "Failed to send GSS-API encryption request."); gss_release_buffer(&gss_status, &gss_w_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_COULDNT_CONNECT; } if(data->set.socks5_gssapi_nec) { memcpy(socksreq, &gss_enc, 1); - nwritten = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 1, FALSE, - &code); - if(code || ( 1 != nwritten)) { + code = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 1, FALSE, + &nwritten); + if(code || (nwritten != 1)) { failf(data, "Failed to send GSS-API encryption type."); - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_COULDNT_CONNECT; } } else { - nwritten = Curl_conn_cf_send(cf->next, data, - (char *)gss_w_token.value, - gss_w_token.length, FALSE, &code); - if(code || ((ssize_t)gss_w_token.length != nwritten)) { + code = Curl_conn_cf_send(cf->next, data, (char *)gss_w_token.value, + gss_w_token.length, FALSE, &nwritten); + if(code || (gss_w_token.length != nwritten)) { failf(data, "Failed to send GSS-API encryption type."); gss_release_buffer(&gss_status, &gss_w_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_COULDNT_CONNECT; } gss_release_buffer(&gss_status, &gss_w_token); @@ -453,7 +452,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, result = Curl_blockread_all(cf, data, (char *)socksreq, 4, &actualread); if(result || (actualread != 4)) { failf(data, "Failed to receive GSS-API encryption response."); - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_COULDNT_CONNECT; } @@ -461,14 +460,14 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, if(socksreq[1] == 255) { /* status / message type */ failf(data, "User was rejected by the SOCKS5 server (%d %d).", socksreq[0], socksreq[1]); - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_COULDNT_CONNECT; } if(socksreq[1] != 2) { /* status / message type */ failf(data, "Invalid GSS-API encryption response type (%d %d).", socksreq[0], socksreq[1]); - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_COULDNT_CONNECT; } @@ -478,7 +477,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, gss_recv_token.length = us_length; gss_recv_token.value = malloc(gss_recv_token.length); if(!gss_recv_token.value) { - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_OUT_OF_MEMORY; } result = Curl_blockread_all(cf, data, (char *)gss_recv_token.value, @@ -487,7 +486,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, if(result || (actualread != us_length)) { failf(data, "Failed to receive GSS-API encryption type."); gss_release_buffer(&gss_status, &gss_recv_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_COULDNT_CONNECT; } @@ -499,7 +498,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_unwrap")) { gss_release_buffer(&gss_status, &gss_recv_token); gss_release_buffer(&gss_status, &gss_w_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); failf(data, "Failed to unwrap GSS-API encryption value into token."); return CURLE_COULDNT_CONNECT; } @@ -509,7 +508,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, failf(data, "Invalid GSS-API encryption response length (%zu).", gss_w_token.length); gss_release_buffer(&gss_status, &gss_w_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_COULDNT_CONNECT; } @@ -521,7 +520,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, failf(data, "Invalid GSS-API encryption response length (%zu).", gss_recv_token.length); gss_release_buffer(&gss_status, &gss_recv_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_COULDNT_CONNECT; } @@ -538,7 +537,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, conn->socks5_gssapi_enctype = socksreq[0]; if(socksreq[0] == 0) - gss_delete_sec_context(&gss_status, &gss_context, NULL); + Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_OK; } diff --git a/vendor/curl/lib/socks_sspi.c b/vendor/curl/lib/socks_sspi.c index 1f0846dda46..1e80ee18d90 100644 --- a/vendor/curl/lib/socks_sspi.c +++ b/vendor/curl/lib/socks_sspi.c @@ -69,8 +69,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, struct connectdata *conn = cf->conn; curl_socket_t sock = conn->sock[cf->sockindex]; CURLcode code; - ssize_t actualread; - ssize_t written; + size_t actualread; + size_t written; int result; /* Needs GSS-API authentication */ SECURITY_STATUS status; @@ -207,9 +207,9 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, us_length = htons((unsigned short)sspi_send_token.cbBuffer); memcpy(socksreq + 2, &us_length, sizeof(short)); - written = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 4, FALSE, - &code); - if(code || (4 != written)) { + code = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 4, FALSE, + &written); + if(code || (written != 4)) { failf(data, "Failed to send SSPI authentication request."); free(service_name); if(sspi_send_token.pvBuffer) @@ -221,10 +221,10 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, return CURLE_COULDNT_CONNECT; } - written = Curl_conn_cf_send(cf->next, data, - (char *)sspi_send_token.pvBuffer, - sspi_send_token.cbBuffer, FALSE, &code); - if(code || (sspi_send_token.cbBuffer != (size_t)written)) { + code = Curl_conn_cf_send(cf->next, data, + (char *)sspi_send_token.pvBuffer, + sspi_send_token.cbBuffer, FALSE, &written); + if(code || (sspi_send_token.cbBuffer != written)) { failf(data, "Failed to send SSPI authentication token."); free(service_name); if(sspi_send_token.pvBuffer) @@ -478,9 +478,9 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, memcpy(socksreq + 2, &us_length, sizeof(short)); } - written = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 4, FALSE, - &code); - if(code || (4 != written)) { + code = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 4, FALSE, + &written); + if(code || (written != 4)) { failf(data, "Failed to send SSPI encryption request."); if(sspi_send_token.pvBuffer) Curl_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); @@ -490,18 +490,18 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, if(data->set.socks5_gssapi_nec) { memcpy(socksreq, &gss_enc, 1); - written = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 1, FALSE, - &code); - if(code || (1 != written)) { + code = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 1, FALSE, + &written); + if(code || (written != 1)) { failf(data, "Failed to send SSPI encryption type."); Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_COULDNT_CONNECT; } } else { - written = Curl_conn_cf_send(cf->next, data, - (char *)sspi_send_token.pvBuffer, - sspi_send_token.cbBuffer, FALSE, &code); + code = Curl_conn_cf_send(cf->next, data, + (char *)sspi_send_token.pvBuffer, + sspi_send_token.cbBuffer, FALSE, &written); if(code || (sspi_send_token.cbBuffer != (size_t)written)) { failf(data, "Failed to send SSPI encryption type."); if(sspi_send_token.pvBuffer) diff --git a/vendor/curl/lib/speedcheck.c b/vendor/curl/lib/speedcheck.c index 16d7d72562c..b063e5d4f20 100644 --- a/vendor/curl/lib/speedcheck.c +++ b/vendor/curl/lib/speedcheck.c @@ -27,6 +27,7 @@ #include #include "urldata.h" #include "sendf.h" +#include "transfer.h" #include "multiif.h" #include "speedcheck.h" @@ -41,7 +42,7 @@ void Curl_speedinit(struct Curl_easy *data) CURLcode Curl_speedcheck(struct Curl_easy *data, struct curltime now) { - if(data->req.keepon & KEEP_RECV_PAUSE) + if(Curl_xfer_recv_is_paused(data)) /* A paused transfer is not qualified for speed checks */ return CURLE_OK; diff --git a/vendor/curl/lib/splay.c b/vendor/curl/lib/splay.c index 7a0e419ce68..3ca8678b2b2 100644 --- a/vendor/curl/lib/splay.c +++ b/vendor/curl/lib/splay.c @@ -94,6 +94,10 @@ struct Curl_tree *Curl_splay(struct curltime i, return t; } +static const struct curltime SPLAY_SUBNODE = { + ~0, -1 +}; + /* Insert key i into the tree t. Return a pointer to the resulting tree or * NULL if something went wrong. * @@ -103,10 +107,6 @@ struct Curl_tree *Curl_splayinsert(struct curltime i, struct Curl_tree *t, struct Curl_tree *node) { - static const struct curltime KEY_NOTUSED = { - ~0, -1 - }; /* will *NEVER* appear */ - DEBUGASSERT(node); if(t) { @@ -117,8 +117,7 @@ struct Curl_tree *Curl_splayinsert(struct curltime i, doubly-linked circular list of nodes. We add the new 'node' struct to the end of this list. */ - node->key = KEY_NOTUSED; /* we set the key in the sub node to NOTUSED - to quickly identify this node as a subnode */ + node->key = SPLAY_SUBNODE; /* identify this node as a subnode */ node->samen = t; node->samep = t->samep; t->samep->samen = node; @@ -214,9 +213,6 @@ int Curl_splayremove(struct Curl_tree *t, struct Curl_tree *removenode, struct Curl_tree **newroot) { - static const struct curltime KEY_NOTUSED = { - ~0, -1 - }; /* will *NEVER* appear */ struct Curl_tree *x; if(!t) @@ -224,11 +220,12 @@ int Curl_splayremove(struct Curl_tree *t, DEBUGASSERT(removenode); - if(compare(KEY_NOTUSED, removenode->key) == 0) { - /* Key set to NOTUSED means it is a subnode within a 'same' linked list - and thus we can unlink it easily. */ + if(compare(SPLAY_SUBNODE, removenode->key) == 0) { + /* It is a subnode within a 'same' linked list and thus we can unlink it + easily. */ + DEBUGASSERT(removenode->samen != removenode); if(removenode->samen == removenode) - /* A non-subnode should never be set to KEY_NOTUSED */ + /* A non-subnode should never be set to SPLAY_SUBNODE */ return 3; removenode->samep->samen = removenode->samen; @@ -249,8 +246,9 @@ int Curl_splayremove(struct Curl_tree *t, is not actually in the tree. We cannot just compare the keys here as a double remove in quick - succession of a node with key != KEY_NOTUSED && same != NULL + succession of a node with key != SPLAY_SUBNODE && same != NULL could return the same key but a different node. */ + DEBUGASSERT(t == removenode); if(t != removenode) return 2; diff --git a/vendor/curl/lib/strcase.h b/vendor/curl/lib/strcase.h index 8c50bbcba64..915c996926d 100644 --- a/vendor/curl/lib/strcase.h +++ b/vendor/curl/lib/strcase.h @@ -26,18 +26,6 @@ #include -/* - * Only "raw" case insensitive strings. This is meant to be locale independent - * and only compare strings we know are safe for this. - * - * The function is capable of comparing a-z case insensitively. - * - * Result is 1 if text matches and 0 if not. - */ - -#define strcasecompare(a,b) curl_strequal(a,b) -#define strncasecompare(a,b,c) curl_strnequal(a,b,c) - char Curl_raw_toupper(char in); char Curl_raw_tolower(char in); diff --git a/vendor/curl/lib/strequal.c b/vendor/curl/lib/strequal.c index d1ba91501bb..17dd34b7f3a 100644 --- a/vendor/curl/lib/strequal.c +++ b/vendor/curl/lib/strequal.c @@ -59,12 +59,21 @@ static int ncasecompare(const char *first, const char *second, size_t max) first++; second++; } - if(0 == max) + if(max == 0) return 1; /* they are equal this far */ return Curl_raw_toupper(*first) == Curl_raw_toupper(*second); } +/* + * Only "raw" case insensitive strings. This is meant to be locale independent + * and only compare strings we know are safe for this. + * + * The function is capable of comparing a-z case insensitively. + * + * Result is 1 if text matches and 0 if not. + */ + /* --- public function --- */ int curl_strequal(const char *first, const char *second) { diff --git a/vendor/curl/lib/strerror.c b/vendor/curl/lib/strerror.c index 9cf93dd66e9..f0f36ed1b71 100644 --- a/vendor/curl/lib/strerror.c +++ b/vendor/curl/lib/strerror.c @@ -317,36 +317,7 @@ curl_easy_strerror(CURLcode error) return "ECH attempted but failed"; /* error codes not used by current libcurl */ - case CURLE_OBSOLETE20: - case CURLE_OBSOLETE24: - case CURLE_OBSOLETE29: - case CURLE_OBSOLETE32: - case CURLE_OBSOLETE34: - case CURLE_OBSOLETE40: - case CURLE_OBSOLETE41: - case CURLE_OBSOLETE44: - case CURLE_OBSOLETE46: - case CURLE_OBSOLETE50: - case CURLE_OBSOLETE51: - case CURLE_OBSOLETE57: - case CURLE_OBSOLETE62: - case CURLE_OBSOLETE75: - case CURLE_OBSOLETE76: - - /* error codes used by curl tests */ - case CURLE_RESERVED115: - case CURLE_RESERVED116: - case CURLE_RESERVED117: - case CURLE_RESERVED118: - case CURLE_RESERVED119: - case CURLE_RESERVED120: - case CURLE_RESERVED121: - case CURLE_RESERVED122: - case CURLE_RESERVED123: - case CURLE_RESERVED124: - case CURLE_RESERVED125: - case CURLE_RESERVED126: - case CURL_LAST: + default: break; } /* @@ -838,7 +809,7 @@ const char *Curl_strerror(int err, char *buf, size_t buflen) * storage is supplied via 'strerrbuf' and 'buflen' to hold the generated * message string, or EINVAL if 'errnum' is not a valid error number. */ - if(0 != strerror_r(err, buf, buflen)) { + if(strerror_r(err, buf, buflen)) { if('\0' == buf[0]) curl_msnprintf(buf, buflen, "Unknown error %d", err); } diff --git a/vendor/curl/lib/system_win32.c b/vendor/curl/lib/system_win32.c index 52128875802..a890a0ea989 100644 --- a/vendor/curl/lib/system_win32.c +++ b/vendor/curl/lib/system_win32.c @@ -36,12 +36,17 @@ #include "curl_memory.h" #include "memdebug.h" +#ifndef HAVE_IF_NAMETOINDEX /* Handle of iphlpapp.dll */ static HMODULE s_hIpHlpApiDll = NULL; /* Pointer to the if_nametoindex function */ IF_NAMETOINDEX_FN Curl_if_nametoindex = NULL; +/* This is used to dynamically load DLLs */ +static HMODULE curl_load_library(LPCTSTR filename); +#endif + /* Curl_win32_init() performs Win32 global initialization */ CURLcode Curl_win32_init(long flags) { @@ -90,7 +95,8 @@ CURLcode Curl_win32_init(long flags) } #endif - s_hIpHlpApiDll = Curl_load_library(TEXT("iphlpapi.dll")); +#ifndef HAVE_IF_NAMETOINDEX + s_hIpHlpApiDll = curl_load_library(TEXT("iphlpapi.dll")); if(s_hIpHlpApiDll) { /* Get the address of the if_nametoindex function */ #ifdef UNDER_CE @@ -106,6 +112,7 @@ CURLcode Curl_win32_init(long flags) if(pIfNameToIndex) Curl_if_nametoindex = pIfNameToIndex; } +#endif /* curlx_verify_windows_version must be called during init at least once because it has its own initialization routine. */ @@ -123,11 +130,13 @@ CURLcode Curl_win32_init(long flags) /* Curl_win32_cleanup() is the opposite of Curl_win32_init() */ void Curl_win32_cleanup(long init_flags) { +#ifndef HAVE_IF_NAMETOINDEX if(s_hIpHlpApiDll) { FreeLibrary(s_hIpHlpApiDll); s_hIpHlpApiDll = NULL; Curl_if_nametoindex = NULL; } +#endif #ifdef USE_WINDOWS_SSPI Curl_sspi_global_cleanup(); @@ -140,11 +149,13 @@ void Curl_win32_cleanup(long init_flags) } } -#if !defined(LOAD_WITH_ALTERED_SEARCH_PATH) +#ifndef HAVE_IF_NAMETOINDEX + +#ifndef LOAD_WITH_ALTERED_SEARCH_PATH #define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008 #endif -#if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32) +#ifndef LOAD_LIBRARY_SEARCH_SYSTEM32 #define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 #endif @@ -163,7 +174,7 @@ typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD); #endif /* - * Curl_load_library() + * curl_load_library() * * This is used to dynamically load DLLs using the most secure method available * for the version of Windows that we are running on. @@ -176,7 +187,7 @@ typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD); * * Returns the handle of the module on success; otherwise NULL. */ -HMODULE Curl_load_library(LPCTSTR filename) +static HMODULE curl_load_library(LPCTSTR filename) { #if !defined(CURL_WINDOWS_UWP) && !defined(UNDER_CE) HMODULE hModule = NULL; @@ -228,7 +239,6 @@ HMODULE Curl_load_library(LPCTSTR filename) hModule = pLoadLibraryEx ? pLoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) : LoadLibrary(path); - } free(path); } @@ -240,5 +250,6 @@ HMODULE Curl_load_library(LPCTSTR filename) return NULL; #endif } +#endif /* !HAVE_IF_NAMETOINDEX */ #endif /* _WIN32 */ diff --git a/vendor/curl/lib/system_win32.h b/vendor/curl/lib/system_win32.h index b8333c647e1..6bf89d3d9d7 100644 --- a/vendor/curl/lib/system_win32.h +++ b/vendor/curl/lib/system_win32.h @@ -36,14 +36,13 @@ extern bool Curl_isVistaOrGreater; CURLcode Curl_win32_init(long flags); void Curl_win32_cleanup(long init_flags); +#ifndef HAVE_IF_NAMETOINDEX /* We use our own typedef here since some headers might lack this */ typedef unsigned int(WINAPI *IF_NAMETOINDEX_FN)(const char *); /* This is used instead of if_nametoindex if available on Windows */ extern IF_NAMETOINDEX_FN Curl_if_nametoindex; - -/* This is used to dynamically load DLLs */ -HMODULE Curl_load_library(LPCTSTR filename); +#endif #else /* _WIN32 */ #define Curl_win32_init(x) CURLE_OK #endif /* !_WIN32 */ diff --git a/vendor/curl/lib/telnet.c b/vendor/curl/lib/telnet.c index 737db36d72c..731789e4636 100644 --- a/vendor/curl/lib/telnet.c +++ b/vendor/curl/lib/telnet.c @@ -57,7 +57,6 @@ #include "system_win32.h" #include "arpa_telnet.h" #include "select.h" -#include "strcase.h" #include "curlx/warnless.h" #include "curlx/strparse.h" @@ -171,7 +170,7 @@ static void sendsuboption(struct Curl_easy *data, static CURLcode telnet_do(struct Curl_easy *data, bool *done); static CURLcode telnet_done(struct Curl_easy *data, - CURLcode, bool premature); + CURLcode, bool premature); static CURLcode send_telnet_data(struct Curl_easy *data, struct TELNET *tn, char *buffer, ssize_t nread); @@ -189,10 +188,10 @@ const struct Curl_handler Curl_handler_telnet = { ZERO_NULL, /* connect_it */ ZERO_NULL, /* connecting */ ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* proto_pollset */ + ZERO_NULL, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ ZERO_NULL, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -839,7 +838,7 @@ static CURLcode check_telnet_options(struct Curl_easy *data, switch(olen) { case 5: /* Terminal type */ - if(strncasecompare(option, "TTYPE", 5)) { + if(curl_strnequal(option, "TTYPE", 5)) { tn->subopt_ttype = arg; tn->us_preferred[CURL_TELOPT_TTYPE] = CURL_YES; break; @@ -849,7 +848,7 @@ static CURLcode check_telnet_options(struct Curl_easy *data, case 8: /* Display variable */ - if(strncasecompare(option, "XDISPLOC", 8)) { + if(curl_strnequal(option, "XDISPLOC", 8)) { tn->subopt_xdisploc = arg; tn->us_preferred[CURL_TELOPT_XDISPLOC] = CURL_YES; break; @@ -859,7 +858,7 @@ static CURLcode check_telnet_options(struct Curl_easy *data, case 7: /* Environment variable */ - if(strncasecompare(option, "NEW_ENV", 7)) { + if(curl_strnequal(option, "NEW_ENV", 7)) { beg = curl_slist_append(tn->telnet_vars, arg); if(!beg) { result = CURLE_OUT_OF_MEMORY; @@ -874,7 +873,7 @@ static CURLcode check_telnet_options(struct Curl_easy *data, case 2: /* Window Size */ - if(strncasecompare(option, "WS", 2)) { + if(curl_strnequal(option, "WS", 2)) { const char *p = arg; curl_off_t x = 0; curl_off_t y = 0; @@ -896,7 +895,7 @@ static CURLcode check_telnet_options(struct Curl_easy *data, case 6: /* To take care or not of the 8th bit in data exchange */ - if(strncasecompare(option, "BINARY", 6)) { + if(curl_strnequal(option, "BINARY", 6)) { int binary_option = atoi(arg); if(binary_option != 1) { tn->us_preferred[CURL_TELOPT_BINARY] = CURL_NO; @@ -1314,8 +1313,8 @@ static CURLcode telnet_do(struct Curl_easy *data, bool *done) int poll_cnt; curl_off_t total_dl = 0; curl_off_t total_ul = 0; + ssize_t snread; #endif - ssize_t nread; struct curltime now; bool keepon = TRUE; char buffer[4*1024]; @@ -1464,6 +1463,7 @@ static CURLcode telnet_do(struct Curl_easy *data, bool *done) } if(events.lNetworkEvents & FD_READ) { /* read data from network */ + size_t nread; result = Curl_xfer_recv(data, buffer, sizeof(buffer), &nread); /* read would have blocked. Loop again */ if(result == CURLE_AGAIN) @@ -1475,7 +1475,7 @@ static CURLcode telnet_do(struct Curl_easy *data, bool *done) } /* returned zero but actually received 0 or less here, the server closed the connection and we bail out */ - else if(nread <= 0) { + else if(!nread) { keepon = FALSE; break; } @@ -1550,6 +1550,7 @@ static CURLcode telnet_do(struct Curl_easy *data, bool *done) default: /* read! */ if(pfd[0].revents & POLLIN) { /* read data from network */ + size_t nread; result = Curl_xfer_recv(data, buffer, sizeof(buffer), &nread); /* read would have blocked. Loop again */ if(result == CURLE_AGAIN) @@ -1567,7 +1568,7 @@ static CURLcode telnet_do(struct Curl_easy *data, bool *done) } /* returned zero but actually received 0 or less here, the server closed the connection and we bail out */ - else if(nread <= 0) { + else if(!nread) { keepon = FALSE; break; } @@ -1590,34 +1591,34 @@ static CURLcode telnet_do(struct Curl_easy *data, bool *done) } } - nread = 0; + snread = 0; if(poll_cnt == 2) { if(pfd[1].revents & POLLIN) { /* read from in file */ - nread = read(pfd[1].fd, buffer, sizeof(buffer)); + snread = read(pfd[1].fd, buffer, sizeof(buffer)); } } else { /* read from user-supplied method */ - nread = (int)data->state.fread_func(buffer, 1, sizeof(buffer), + snread = (int)data->state.fread_func(buffer, 1, sizeof(buffer), data->state.in); - if(nread == CURL_READFUNC_ABORT) { + if(snread == CURL_READFUNC_ABORT) { keepon = FALSE; break; } - if(nread == CURL_READFUNC_PAUSE) + if(snread == CURL_READFUNC_PAUSE) break; } - if(nread > 0) { - result = send_telnet_data(data, tn, buffer, nread); + if(snread > 0) { + result = send_telnet_data(data, tn, buffer, snread); if(result) { keepon = FALSE; break; } - total_ul += nread; + total_ul += snread; Curl_pgrsSetUploadCounter(data, total_ul); } - else if(nread < 0) + else if(snread < 0) keepon = FALSE; break; diff --git a/vendor/curl/lib/tftp.c b/vendor/curl/lib/tftp.c index e9f4e68eccb..6a9f964a079 100644 --- a/vendor/curl/lib/tftp.c +++ b/vendor/curl/lib/tftp.c @@ -48,6 +48,7 @@ #include "urldata.h" #include +#include "cfilters.h" #include "cf-socket.h" #include "transfer.h" #include "sendf.h" @@ -159,8 +160,8 @@ static CURLcode tftp_setup_connection(struct Curl_easy *data, struct connectdata *conn); static CURLcode tftp_multi_statemach(struct Curl_easy *data, bool *done); static CURLcode tftp_doing(struct Curl_easy *data, bool *dophase_done); -static int tftp_getsock(struct Curl_easy *data, struct connectdata *conn, - curl_socket_t *socks); +static CURLcode tftp_pollset(struct Curl_easy *data, + struct easy_pollset *ps); static CURLcode tftp_translate_code(tftp_error_t error); @@ -177,10 +178,10 @@ const struct Curl_handler Curl_handler_tftp = { tftp_connect, /* connect_it */ tftp_multi_statemach, /* connecting */ tftp_doing, /* doing */ - tftp_getsock, /* proto_getsock */ - tftp_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + tftp_pollset, /* proto_pollset */ + tftp_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ ZERO_NULL, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -429,6 +430,7 @@ static CURLcode tftp_send_first(struct tftp_conn *state, const char *mode = "octet"; char *filename; struct Curl_easy *data = state->data; + const struct Curl_sockaddr_ex *remote_addr = NULL; CURLcode result = CURLE_OK; /* Set ASCII mode if -B flag was used */ @@ -525,10 +527,14 @@ static CURLcode tftp_send_first(struct tftp_conn *state, #else #define CURL_SENDTO_ARG5(x) (x) #endif + remote_addr = Curl_conn_get_remote_addr(data, FIRSTSOCKET); + if(!remote_addr) + return CURLE_FAILED_INIT; + senddata = sendto(state->sockfd, (void *)state->spacket.data, (SEND_TYPE_ARG3)sbytes, 0, - CURL_SENDTO_ARG5(&data->conn->remote_addr->curl_sa_addr), - (curl_socklen_t)data->conn->remote_addr->addrlen); + CURL_SENDTO_ARG5(&remote_addr->curl_sa_addr), + (curl_socklen_t)remote_addr->addrlen); if(senddata != (ssize_t)sbytes) { char buffer[STRERROR_LEN]; failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); @@ -955,6 +961,7 @@ static CURLcode tftp_connect(struct Curl_easy *data, bool *done) int blksize; int need_blksize; struct connectdata *conn = data->conn; + const struct Curl_sockaddr_ex *remote_addr = NULL; blksize = TFTP_BLKSIZE_DEFAULT; @@ -998,8 +1005,13 @@ static CURLcode tftp_connect(struct Curl_easy *data, bool *done) state->blksize = TFTP_BLKSIZE_DEFAULT; /* Unless updated by OACK response */ state->requested_blksize = blksize; + remote_addr = Curl_conn_get_remote_addr(data, FIRSTSOCKET); + DEBUGASSERT(remote_addr); + if(!remote_addr) + return CURLE_FAILED_INIT; + ((struct sockaddr *)&state->local_addr)->sa_family = - (CURL_SA_FAMILY_T)(conn->remote_addr->family); + (CURL_SA_FAMILY_T)(remote_addr->family); tftp_set_timeouts(state); @@ -1018,7 +1030,7 @@ static CURLcode tftp_connect(struct Curl_easy *data, bool *done) * IPv4 and IPv6... */ int rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr, - (curl_socklen_t)conn->remote_addr->addrlen); + (curl_socklen_t)remote_addr->addrlen); if(rc) { char buffer[STRERROR_LEN]; failf(data, "bind() failed; %s", @@ -1062,19 +1074,10 @@ static CURLcode tftp_done(struct Curl_easy *data, CURLcode status, return result; } -/********************************************************** - * - * tftp_getsock - * - * The getsock callback - * - **********************************************************/ -static int tftp_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks) +static CURLcode tftp_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { - (void)data; - socks[0] = conn->sock[FIRSTSOCKET]; - return GETSOCK_READSOCK(0); + return Curl_pollset_add_in(data, ps, data->conn->sock[FIRSTSOCKET]); } /********************************************************** @@ -1357,7 +1360,7 @@ static CURLcode tftp_setup_connection(struct Curl_easy *data, { char *type; - conn->transport = TRNSPRT_UDP; + conn->transport_wanted = TRNSPRT_UDP; /* TFTP URLs support an extension like ";mode=" that * we will try to get now! */ diff --git a/vendor/curl/lib/transfer.c b/vendor/curl/lib/transfer.c index ef7d7f19af4..50f621056f7 100644 --- a/vendor/curl/lib/transfer.c +++ b/vendor/curl/lib/transfer.c @@ -79,7 +79,6 @@ #include "connect.h" #include "http2.h" #include "mime.h" -#include "strcase.h" #include "hsts.h" #include "setopt.h" #include "headers.h" @@ -106,7 +105,7 @@ char *Curl_checkheaders(const struct Curl_easy *data, DEBUGASSERT(thisheader[thislen-1] != ':'); for(head = data->set.headers; head; head = head->next) { - if(strncasecompare(head->data, thisheader, thislen) && + if(curl_strnequal(head->data, thisheader, thislen) && Curl_headersep(head->data[thislen]) ) return head->data; } @@ -115,7 +114,7 @@ char *Curl_checkheaders(const struct Curl_easy *data, } #endif -static int data_pending(struct Curl_easy *data) +static int data_pending(struct Curl_easy *data, bool rcvd_eagain) { struct connectdata *conn = data->conn; @@ -124,8 +123,9 @@ static int data_pending(struct Curl_easy *data) /* in the case of libssh2, we can never be really sure that we have emptied its internal buffers so we MUST always try until we get EAGAIN back */ - return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) || - Curl_conn_data_pending(data, FIRSTSOCKET); + return (!rcvd_eagain && + conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP)) || + Curl_conn_data_pending(data, FIRSTSOCKET); } /* @@ -162,38 +162,23 @@ bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc) static CURLcode xfer_recv_shutdown(struct Curl_easy *data, bool *done) { - int sockindex; - if(!data || !data->conn) return CURLE_FAILED_INIT; - if(data->conn->sockfd == CURL_SOCKET_BAD) - return CURLE_FAILED_INIT; - sockindex = (data->conn->sockfd == data->conn->sock[SECONDARYSOCKET]); - return Curl_conn_shutdown(data, sockindex, done); + return Curl_conn_shutdown(data, data->conn->recv_idx, done); } static bool xfer_recv_shutdown_started(struct Curl_easy *data) { - int sockindex; - if(!data || !data->conn) return FALSE; - if(data->conn->sockfd == CURL_SOCKET_BAD) - return FALSE; - sockindex = (data->conn->sockfd == data->conn->sock[SECONDARYSOCKET]); - return Curl_shutdown_started(data, sockindex); + return Curl_shutdown_started(data, data->conn->recv_idx); } CURLcode Curl_xfer_send_shutdown(struct Curl_easy *data, bool *done) { - int sockindex; - if(!data || !data->conn) return CURLE_FAILED_INIT; - if(data->conn->writesockfd == CURL_SOCKET_BAD) - return CURLE_FAILED_INIT; - sockindex = (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET]); - return Curl_conn_shutdown(data, sockindex, done); + return Curl_conn_shutdown(data, data->conn->send_idx, done); } /** @@ -210,7 +195,7 @@ static ssize_t xfer_recv_resp(struct Curl_easy *data, bool eos_reliable, CURLcode *err) { - ssize_t nread; + size_t nread; DEBUGASSERT(blen > 0); /* If we are reading BODY data and the connection does NOT handle EOF @@ -251,8 +236,7 @@ static ssize_t xfer_recv_resp(struct Curl_easy *data, } DEBUGF(infof(data, "sendrecv_dl: we are done")); } - DEBUGASSERT(nread >= 0); - return nread; + return (ssize_t)nread; } /* @@ -271,6 +255,7 @@ static CURLcode sendrecv_dl(struct Curl_easy *data, int maxloops = 10; curl_off_t total_received = 0; bool is_multiplex = FALSE; + bool rcvd_eagain = FALSE; result = Curl_multi_xfer_buf_borrow(data, &xfer_buf, &xfer_blen); if(result) @@ -303,23 +288,25 @@ static CURLcode sendrecv_dl(struct Curl_easy *data, bytestoread = (size_t)data->set.max_recv_speed; } + rcvd_eagain = FALSE; nread = xfer_recv_resp(data, buf, bytestoread, is_multiplex, &result); if(nread < 0) { if(CURLE_AGAIN != result) goto out; /* real error */ + rcvd_eagain = TRUE; result = CURLE_OK; if(data->req.download_done && data->req.no_body && !data->req.resp_trailer) { DEBUGF(infof(data, "EAGAIN, download done, no trailer announced, " "not waiting for EOS")); nread = 0; - /* continue as if we read the EOS */ + /* continue as if we received the EOS */ } else break; /* get out of loop */ } - /* We only get a 0-length read on EndOfStream */ + /* We only get a 0-length receive at the end of the response */ blen = (size_t)nread; is_eos = (blen == 0); *didwhat |= KEEP_RECV; @@ -355,12 +342,12 @@ static CURLcode sendrecv_dl(struct Curl_easy *data, } while(maxloops--); - if((maxloops <= 0) || data_pending(data)) { - /* did not read until EAGAIN or there is still pending data, mark as - read-again-please */ - data->state.select_bits = CURL_CSELECT_IN; - if((k->keepon & KEEP_SENDBITS) == KEEP_SEND) - data->state.select_bits |= CURL_CSELECT_OUT; + if(!Curl_xfer_is_blocked(data) && + (!rcvd_eagain || data_pending(data, rcvd_eagain))) { + /* Did not read until EAGAIN or there is still data pending + * in buffers. Mark as read-again via simulated SELECT results. */ + Curl_multi_mark_dirty(data); + CURL_TRC_M(data, "sendrecv_dl() no EAGAIN/pending data, mark as dirty"); } if(((k->keepon & (KEEP_RECV|KEEP_SEND)) == KEEP_SEND) && @@ -396,24 +383,6 @@ static CURLcode sendrecv_ul(struct Curl_easy *data, int *didwhat) return CURLE_OK; } -static int select_bits_paused(struct Curl_easy *data, int select_bits) -{ - /* See issue #11982: we really need to be careful not to progress - * a transfer direction when that direction is paused. Not all parts - * of our state machine are handling PAUSED transfers correctly. So, we - * do not want to go there. - * NOTE: we are only interested in PAUSE, not HOLD. */ - - /* if there is data in a direction not paused, return false */ - if(((select_bits & CURL_CSELECT_IN) && - !(data->req.keepon & KEEP_RECV_PAUSE)) || - ((select_bits & CURL_CSELECT_OUT) && - !(data->req.keepon & KEEP_SEND_PAUSE))) - return FALSE; - - return (data->req.keepon & (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)); -} - /* * Curl_sendrecv() is the low-level function to be called when data is to * be read and written to/from the connection. @@ -425,14 +394,9 @@ CURLcode Curl_sendrecv(struct Curl_easy *data, struct curltime *nowp) int didwhat = 0; DEBUGASSERT(nowp); - if(data->state.select_bits) { - if(select_bits_paused(data, data->state.select_bits)) { - /* leave the bits unchanged, so they'll tell us what to do when - * this transfer gets unpaused. */ - result = CURLE_OK; - goto out; - } - data->state.select_bits = 0; + if(Curl_xfer_is_blocked(data)) { + result = CURLE_OK; + goto out; } /* We go ahead and do a read if we have a readable socket or if the stream @@ -502,7 +466,7 @@ CURLcode Curl_sendrecv(struct Curl_easy *data, struct curltime *nowp) } /* If there is nothing more to send/recv, the request is done */ - if(0 == (k->keepon&(KEEP_RECVBITS|KEEP_SENDBITS))) + if((k->keepon & (KEEP_RECVBITS|KEEP_SENDBITS)) == 0) data->req.done = TRUE; out: @@ -753,101 +717,88 @@ CURLcode Curl_retry_request(struct Curl_easy *data, char **url) return CURLE_OK; } -/* - * xfer_setup() is called to setup basic properties for the transfer. - */ static void xfer_setup( struct Curl_easy *data, /* transfer */ - int sockindex, /* socket index to read from or -1 */ - curl_off_t size, /* -1 if unknown at this point */ - bool getheader, /* TRUE if header parsing is wanted */ - int writesockindex, /* socket index to write to, it may be the same we - read from. -1 disables */ - bool shutdown, /* shutdown connection at transfer end. Only - * supported when sending OR receiving. */ - bool shutdown_err_ignore /* errors during shutdown do not fail the - * transfer */ + int send_idx, /* sockindex to send on or -1 */ + int recv_idx, /* sockindex to receive on or -1 */ + curl_off_t recv_size /* how much to receive, -1 if unknown */ ) { struct SingleRequest *k = &data->req; struct connectdata *conn = data->conn; - bool want_send = Curl_req_want_send(data); DEBUGASSERT(conn != NULL); - DEBUGASSERT((sockindex <= 1) && (sockindex >= -1)); - DEBUGASSERT((writesockindex <= 1) && (writesockindex >= -1)); - DEBUGASSERT(!shutdown || (sockindex == -1) || (writesockindex == -1)); - - if(Curl_conn_is_multiplex(conn, FIRSTSOCKET) || want_send) { - /* when multiplexing, the read/write sockets need to be the same! */ - conn->sockfd = sockindex == -1 ? - ((writesockindex == -1 ? CURL_SOCKET_BAD : conn->sock[writesockindex])) : - conn->sock[sockindex]; - conn->writesockfd = conn->sockfd; - if(want_send) - /* special and HTTP-specific */ - writesockindex = FIRSTSOCKET; - } - else { - conn->sockfd = sockindex == -1 ? - CURL_SOCKET_BAD : conn->sock[sockindex]; - conn->writesockfd = writesockindex == -1 ? - CURL_SOCKET_BAD : conn->sock[writesockindex]; - } - - k->getheader = getheader; - k->size = size; - k->shutdown = shutdown; - k->shutdown_err_ignore = shutdown_err_ignore; + /* indexes are in range */ + DEBUGASSERT((send_idx <= 1) && (send_idx >= -1)); + DEBUGASSERT((recv_idx <= 1) && (recv_idx >= -1)); + /* if request wants to send, switching off the send direction is wrong */ + DEBUGASSERT((send_idx >= 0) || !Curl_req_want_send(data)); + + conn->send_idx = send_idx; + conn->recv_idx = recv_idx; + + /* without receiving, there should be not recv_size */ + DEBUGASSERT((conn->recv_idx >= 0) || (recv_size == -1)); + k->size = recv_size; + k->header = !!conn->handler->write_resp_hd; + /* by default, we do not shutdown at the end of the transfer */ + k->shutdown = FALSE; + k->shutdown_err_ignore = FALSE; /* The code sequence below is placed in this function just because all necessary input is not always known in do_complete() as this function may be called after that */ + if(!k->header && (recv_size > 0)) + Curl_pgrsSetDownloadSize(data, recv_size); - if(!k->getheader) { - k->header = FALSE; - if(size > 0) - Curl_pgrsSetDownloadSize(data, size); - } /* we want header and/or body, if neither then do not do this! */ - if(k->getheader || !data->req.no_body) { + if(conn->handler->write_resp_hd || !data->req.no_body) { - if(sockindex != -1) + if(conn->recv_idx != -1) k->keepon |= KEEP_RECV; - if(writesockindex != -1) + if(conn->send_idx != -1) k->keepon |= KEEP_SEND; - } /* if(k->getheader || !data->req.no_body) */ + } + CURL_TRC_M(data, "xfer_setup: recv_idx=%d, send_idx=%d", + conn->recv_idx, conn->send_idx); } void Curl_xfer_setup_nop(struct Curl_easy *data) { - xfer_setup(data, -1, -1, FALSE, -1, FALSE, FALSE); + xfer_setup(data, -1, -1, -1); +} + +void Curl_xfer_setup_sendrecv(struct Curl_easy *data, + int sockindex, + curl_off_t recv_size) +{ + xfer_setup(data, sockindex, sockindex, recv_size); +} + +void Curl_xfer_setup_send(struct Curl_easy *data, + int sockindex) +{ + xfer_setup(data, sockindex, -1, -1); } -void Curl_xfer_setup1(struct Curl_easy *data, - int send_recv, - curl_off_t recv_size, - bool getheader) +void Curl_xfer_setup_recv(struct Curl_easy *data, + int sockindex, + curl_off_t recv_size) { - int recv_index = (send_recv & CURL_XFER_RECV) ? FIRSTSOCKET : -1; - int send_index = (send_recv & CURL_XFER_SEND) ? FIRSTSOCKET : -1; - DEBUGASSERT((recv_index >= 0) || (recv_size == -1)); - xfer_setup(data, recv_index, recv_size, getheader, send_index, FALSE, FALSE); + xfer_setup(data, -1, sockindex, recv_size); } -void Curl_xfer_setup2(struct Curl_easy *data, - int send_recv, - curl_off_t recv_size, - bool shutdown, - bool shutdown_err_ignore) +void Curl_xfer_set_shutdown(struct Curl_easy *data, + bool shutdown, + bool ignore_errors) { - int recv_index = (send_recv & CURL_XFER_RECV) ? SECONDARYSOCKET : -1; - int send_index = (send_recv & CURL_XFER_SEND) ? SECONDARYSOCKET : -1; - DEBUGASSERT((recv_index >= 0) || (recv_size == -1)); - xfer_setup(data, recv_index, recv_size, FALSE, send_index, - shutdown, shutdown_err_ignore); + /* Shutdown should only be set when the transfer only sends or receives. */ + DEBUGASSERT(!shutdown || + (data->conn->send_idx < 0) || (data->conn->recv_idx < 0)); + data->req.shutdown = shutdown; + data->req.shutdown_err_ignore = ignore_errors; } CURLcode Curl_xfer_write_resp(struct Curl_easy *data, @@ -907,18 +858,12 @@ CURLcode Curl_xfer_write_done(struct Curl_easy *data, bool premature) bool Curl_xfer_needs_flush(struct Curl_easy *data) { - int sockindex; - sockindex = ((data->conn->writesockfd != CURL_SOCKET_BAD) && - (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET])); - return Curl_conn_needs_flush(data, sockindex); + return Curl_conn_needs_flush(data, data->conn->send_idx); } CURLcode Curl_xfer_flush(struct Curl_easy *data) { - int sockindex; - sockindex = ((data->conn->writesockfd != CURL_SOCKET_BAD) && - (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET])); - return Curl_conn_flush(data, sockindex); + return Curl_conn_flush(data, data->conn->send_idx); } CURLcode Curl_xfer_send(struct Curl_easy *data, @@ -926,14 +871,12 @@ CURLcode Curl_xfer_send(struct Curl_easy *data, size_t *pnwritten) { CURLcode result; - int sockindex; DEBUGASSERT(data); DEBUGASSERT(data->conn); - sockindex = ((data->conn->writesockfd != CURL_SOCKET_BAD) && - (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET])); - result = Curl_conn_send(data, sockindex, buf, blen, eos, pnwritten); + result = Curl_conn_send(data, data->conn->send_idx, + buf, blen, eos, pnwritten); if(result == CURLE_AGAIN) { result = CURLE_OK; *pnwritten = 0; @@ -948,19 +891,15 @@ CURLcode Curl_xfer_send(struct Curl_easy *data, CURLcode Curl_xfer_recv(struct Curl_easy *data, char *buf, size_t blen, - ssize_t *pnrcvd) + size_t *pnrcvd) { - int sockindex; - DEBUGASSERT(data); DEBUGASSERT(data->conn); DEBUGASSERT(data->set.buffer_size > 0); - sockindex = ((data->conn->sockfd != CURL_SOCKET_BAD) && - (data->conn->sockfd == data->conn->sock[SECONDARYSOCKET])); if((size_t)data->set.buffer_size < blen) blen = (size_t)data->set.buffer_size; - return Curl_conn_recv(data, sockindex, buf, blen, pnrcvd); + return Curl_conn_recv(data, data->conn->recv_idx, buf, blen, pnrcvd); } CURLcode Curl_xfer_send_close(struct Curl_easy *data) @@ -974,9 +913,48 @@ bool Curl_xfer_is_blocked(struct Curl_easy *data) bool want_send = ((data)->req.keepon & KEEP_SEND); bool want_recv = ((data)->req.keepon & KEEP_RECV); if(!want_send) - return want_recv && Curl_cwriter_is_paused(data); + return want_recv && Curl_xfer_recv_is_paused(data); else if(!want_recv) - return want_send && Curl_creader_is_paused(data); + return want_send && Curl_xfer_send_is_paused(data); else - return Curl_creader_is_paused(data) && Curl_cwriter_is_paused(data); + return Curl_xfer_recv_is_paused(data) && Curl_xfer_send_is_paused(data); +} + +bool Curl_xfer_send_is_paused(struct Curl_easy *data) +{ + return (data->req.keepon & KEEP_SEND_PAUSE); +} + +bool Curl_xfer_recv_is_paused(struct Curl_easy *data) +{ + return (data->req.keepon & KEEP_RECV_PAUSE); +} + +CURLcode Curl_xfer_pause_send(struct Curl_easy *data, bool enable) +{ + CURLcode result = CURLE_OK; + if(enable) { + data->req.keepon |= KEEP_SEND_PAUSE; + } + else { + data->req.keepon &= ~KEEP_SEND_PAUSE; + if(Curl_creader_is_paused(data)) + result = Curl_creader_unpause(data); + } + return result; +} + +CURLcode Curl_xfer_pause_recv(struct Curl_easy *data, bool enable) +{ + CURLcode result = CURLE_OK; + if(enable) { + data->req.keepon |= KEEP_RECV_PAUSE; + } + else { + data->req.keepon &= ~KEEP_RECV_PAUSE; + if(Curl_cwriter_is_paused(data)) + result = Curl_cwriter_unpause(data); + } + Curl_conn_ev_data_pause(data, enable); + return result; } diff --git a/vendor/curl/lib/transfer.h b/vendor/curl/lib/transfer.h index 2c355e0e9d8..91a81e52e8f 100644 --- a/vendor/curl/lib/transfer.h +++ b/vendor/curl/lib/transfer.h @@ -34,8 +34,6 @@ void Curl_init_CONNECT(struct Curl_easy *data); CURLcode Curl_pretransfer(struct Curl_easy *data); CURLcode Curl_sendrecv(struct Curl_easy *data, struct curltime *nowp); -int Curl_single_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks); CURLcode Curl_retry_request(struct Curl_easy *data, char **url); bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc); @@ -66,38 +64,33 @@ bool Curl_xfer_write_is_paused(struct Curl_easy *data); CURLcode Curl_xfer_write_resp_hd(struct Curl_easy *data, const char *hd0, size_t hdlen, bool is_eos); -#define CURL_XFER_NOP (0) -#define CURL_XFER_RECV (1<<(0)) -#define CURL_XFER_SEND (1<<(1)) -#define CURL_XFER_SENDRECV (CURL_XFER_RECV|CURL_XFER_SEND) - -/** - * The transfer is neither receiving nor sending now. - */ +/* The transfer is neither receiving nor sending. */ void Curl_xfer_setup_nop(struct Curl_easy *data); -/** - * The transfer will use socket 1 to send/recv. `recv_size` is - * the amount to receive or -1 if unknown. `getheader` indicates - * response header processing is expected. - */ -void Curl_xfer_setup1(struct Curl_easy *data, - int send_recv, - curl_off_t recv_size, - bool getheader); +/* The transfer sends data on the given socket index */ +void Curl_xfer_setup_send(struct Curl_easy *data, + int sockindex); + +/* The transfer receives data on the given socket index, the + * amount to receive (or -1 if unknown). */ +void Curl_xfer_setup_recv(struct Curl_easy *data, + int sockindex, + curl_off_t recv_size); + +/* *After* Curl_xfer_setup_xxx(), tell the transfer to shutdown the + * connection at the end. Let the transfer either fail or ignore any + * errors during shutdown. */ +void Curl_xfer_set_shutdown(struct Curl_easy *data, + bool shutdown, + bool ignore_errors); /** - * The transfer will use socket 2 to send/recv. `recv_size` is - * the amount to receive or -1 if unknown. With `shutdown` being - * set, the transfer is only allowed to either send OR receive - * and the socket 2 connection will be shutdown at the end of - * the transfer. An unclean shutdown will fail the transfer - * unless `shutdown_err_ignore` is TRUE. + * The transfer will use socket 1 to send/recv. `recv_size` is + * the amount to receive or -1 if unknown. */ -void Curl_xfer_setup2(struct Curl_easy *data, - int send_recv, - curl_off_t recv_size, - bool shutdown, bool shutdown_err_ignore); +void Curl_xfer_setup_sendrecv(struct Curl_easy *data, + int sockindex, + curl_off_t recv_size); /** * Multi has set transfer to DONE. Last chance to trigger @@ -132,16 +125,23 @@ CURLcode Curl_xfer_send(struct Curl_easy *data, */ CURLcode Curl_xfer_recv(struct Curl_easy *data, char *buf, size_t blen, - ssize_t *pnrcvd); + size_t *pnrcvd); CURLcode Curl_xfer_send_close(struct Curl_easy *data); CURLcode Curl_xfer_send_shutdown(struct Curl_easy *data, bool *done); -/** - * Return TRUE iff the transfer is not done, but further progress +/* Return TRUE if the transfer is not done, but further progress * is blocked. For example when it is only receiving and its writer - * is PAUSED. - */ + * is PAUSED. */ bool Curl_xfer_is_blocked(struct Curl_easy *data); +/* Query if send/recv for transfer is paused. */ +bool Curl_xfer_send_is_paused(struct Curl_easy *data); +bool Curl_xfer_recv_is_paused(struct Curl_easy *data); + +/* Enable/Disable pausing of send/recv for the transfer. */ +CURLcode Curl_xfer_pause_send(struct Curl_easy *data, bool enable); +CURLcode Curl_xfer_pause_recv(struct Curl_easy *data, bool enable); + + #endif /* HEADER_CURL_TRANSFER_H */ diff --git a/vendor/curl/lib/uint-bset.c b/vendor/curl/lib/uint-bset.c index 2560b373634..1c60f22adff 100644 --- a/vendor/curl/lib/uint-bset.c +++ b/vendor/curl/lib/uint-bset.c @@ -45,7 +45,8 @@ void Curl_uint_bset_init(struct uint_bset *bset) CURLcode Curl_uint_bset_resize(struct uint_bset *bset, unsigned int nmax) { - unsigned int nslots = (nmax + 63) / 64; + unsigned int nslots = (nmax < (UINT_MAX-63)) ? + ((nmax + 63) / 64) : (UINT_MAX / 64); DEBUGASSERT(bset->init == CURL_UINT_BSET_MAGIC); if(nslots != bset->nslots) { @@ -60,6 +61,7 @@ CURLcode Curl_uint_bset_resize(struct uint_bset *bset, unsigned int nmax) } bset->slots = slots; bset->nslots = nslots; + bset->first_slot_used = 0; } return CURLE_OK; } @@ -72,12 +74,12 @@ void Curl_uint_bset_destroy(struct uint_bset *bset) memset(bset, 0, sizeof(*bset)); } - -unsigned int Curl_uint_bset_capacity(struct uint_bset *bset) +#ifdef UNITTESTS +UNITTEST unsigned int Curl_uint_bset_capacity(struct uint_bset *bset) { return bset->nslots * 64; } - +#endif unsigned int Curl_uint_bset_count(struct uint_bset *bset) { @@ -90,11 +92,10 @@ unsigned int Curl_uint_bset_count(struct uint_bset *bset) return n; } - bool Curl_uint_bset_empty(struct uint_bset *bset) { unsigned int i; - for(i = 0; i < bset->nslots; ++i) { + for(i = bset->first_slot_used; i < bset->nslots; ++i) { if(bset->slots[i]) return FALSE; } @@ -104,8 +105,10 @@ bool Curl_uint_bset_empty(struct uint_bset *bset) void Curl_uint_bset_clear(struct uint_bset *bset) { - if(bset->nslots) + if(bset->nslots) { memset(bset->slots, 0, bset->nslots * sizeof(curl_uint64_t)); + bset->first_slot_used = UINT_MAX; + } } @@ -115,6 +118,8 @@ bool Curl_uint_bset_add(struct uint_bset *bset, unsigned int i) if(islot >= bset->nslots) return FALSE; bset->slots[islot] |= ((curl_uint64_t)1 << (i % 64)); + if(islot < bset->first_slot_used) + bset->first_slot_used = islot; return TRUE; } @@ -139,13 +144,14 @@ bool Curl_uint_bset_contains(struct uint_bset *bset, unsigned int i) bool Curl_uint_bset_first(struct uint_bset *bset, unsigned int *pfirst) { unsigned int i; - for(i = 0; i < bset->nslots; ++i) { + for(i = bset->first_slot_used; i < bset->nslots; ++i) { if(bset->slots[i]) { *pfirst = (i * 64) + CURL_CTZ64(bset->slots[i]); + bset->first_slot_used = i; return TRUE; } } - *pfirst = UINT_MAX; /* a value we cannot store */ + bset->first_slot_used = *pfirst = UINT_MAX; return FALSE; } @@ -183,11 +189,11 @@ unsigned int Curl_popcount64(curl_uint64_t x) /* Compute the "Hamming Distance" between 'x' and 0, * which is the number of set bits in 'x'. * See: https://en.wikipedia.org/wiki/Hamming_weight */ - const curl_uint64_t m1 = CURL_OFF_TU_C(0x5555555555555555); /* 0101+ */ - const curl_uint64_t m2 = CURL_OFF_TU_C(0x3333333333333333); /* 00110011+ */ - const curl_uint64_t m4 = CURL_OFF_TU_C(0x0f0f0f0f0f0f0f0f); /* 00001111+ */ + const curl_uint64_t m1 = 0x5555555555555555LL; /* 0101+ */ + const curl_uint64_t m2 = 0x3333333333333333LL; /* 00110011+ */ + const curl_uint64_t m4 = 0x0f0f0f0f0f0f0f0fLL; /* 00001111+ */ /* 1 + 256^1 + 256^2 + 256^3 + ... + 256^7 */ - const curl_uint64_t h01 = CURL_OFF_TU_C(0x0101010101010101); + const curl_uint64_t h01 = 0x0101010101010101LL; x -= (x >> 1) & m1; /* replace every 2 bits with bits present */ x = (x & m2) + ((x >> 2) & m2); /* replace every nibble with bits present */ x = (x + (x >> 4)) & m4; /* replace every byte with bits present */ @@ -203,11 +209,11 @@ unsigned int Curl_ctz64(curl_uint64_t x) { /* count trailing zeros in a curl_uint64_t. * divide and conquer to find the number of lower 0 bits */ - const curl_uint64_t ml32 = CURL_OFF_TU_C(0xFFFFFFFF); /* lower 32 bits */ - const curl_uint64_t ml16 = CURL_OFF_TU_C(0x0000FFFF); /* lower 16 bits */ - const curl_uint64_t ml8 = CURL_OFF_TU_C(0x000000FF); /* lower 8 bits */ - const curl_uint64_t ml4 = CURL_OFF_TU_C(0x0000000F); /* lower 4 bits */ - const curl_uint64_t ml2 = CURL_OFF_TU_C(0x00000003); /* lower 2 bits */ + const curl_uint64_t ml32 = 0xFFFFFFFF; /* lower 32 bits */ + const curl_uint64_t ml16 = 0x0000FFFF; /* lower 16 bits */ + const curl_uint64_t ml8 = 0x000000FF; /* lower 8 bits */ + const curl_uint64_t ml4 = 0x0000000F; /* lower 4 bits */ + const curl_uint64_t ml2 = 0x00000003; /* lower 2 bits */ unsigned int n; if(!x) diff --git a/vendor/curl/lib/uint-bset.h b/vendor/curl/lib/uint-bset.h index d998dccdfe5..cc405cc656e 100644 --- a/vendor/curl/lib/uint-bset.h +++ b/vendor/curl/lib/uint-bset.h @@ -42,6 +42,7 @@ struct uint_bset { curl_uint64_t *slots; unsigned int nslots; + unsigned int first_slot_used; #ifdef DEBUGBUILD int init; #endif diff --git a/vendor/curl/lib/uint-hash.c b/vendor/curl/lib/uint-hash.c index afeb684d0ca..6c665078876 100644 --- a/vendor/curl/lib/uint-hash.c +++ b/vendor/curl/lib/uint-hash.c @@ -107,8 +107,8 @@ static void uint_hash_entry_unlink(struct uint_hash *h, } static void uint_hash_elem_link(struct uint_hash *h, - struct uint_hash_entry **he_anchor, - struct uint_hash_entry *he) + struct uint_hash_entry **he_anchor, + struct uint_hash_entry *he) { he->next = *he_anchor; *he_anchor = he; @@ -206,10 +206,12 @@ static void uint_hash_clear(struct uint_hash *h) } } -void Curl_uint_hash_clear(struct uint_hash *h) +#ifdef UNITTESTS +UNITTEST void Curl_uint_hash_clear(struct uint_hash *h) { uint_hash_clear(h); } +#endif void Curl_uint_hash_destroy(struct uint_hash *h) { diff --git a/vendor/curl/lib/uint-spbset.c b/vendor/curl/lib/uint-spbset.c index 578b9bd07c1..d12cdcb4aa1 100644 --- a/vendor/curl/lib/uint-spbset.c +++ b/vendor/curl/lib/uint-spbset.c @@ -35,6 +35,9 @@ #define CURL_UINT_SPBSET_MAGIC 0x70737362 #endif +/* Clear the bitset, making it empty. */ +UNITTEST void Curl_uint_spbset_clear(struct uint_spbset *bset); + void Curl_uint_spbset_init(struct uint_spbset *bset) { memset(bset, 0, sizeof(*bset)); @@ -77,7 +80,7 @@ bool Curl_uint_spbset_empty(struct uint_spbset *bset) return TRUE; } -void Curl_uint_spbset_clear(struct uint_spbset *bset) +UNITTEST void Curl_uint_spbset_clear(struct uint_spbset *bset) { struct uint_spbset_chunk *next, *chunk; diff --git a/vendor/curl/lib/uint-spbset.h b/vendor/curl/lib/uint-spbset.h index 571d56753cd..bd2347902c3 100644 --- a/vendor/curl/lib/uint-spbset.h +++ b/vendor/curl/lib/uint-spbset.h @@ -64,9 +64,6 @@ unsigned int Curl_uint_spbset_count(struct uint_spbset *bset); /* TRUE of bitset is empty */ bool Curl_uint_spbset_empty(struct uint_spbset *bset); -/* Clear the bitset, making it empty. */ -void Curl_uint_spbset_clear(struct uint_spbset *bset); - /* Add the number `i` to the bitset. * Numbers can be added more than once, without making a difference. * Returns FALSE if allocations failed. */ diff --git a/vendor/curl/lib/uint-table.c b/vendor/curl/lib/uint-table.c index d8de1b128ab..21bcb6e1cf3 100644 --- a/vendor/curl/lib/uint-table.c +++ b/vendor/curl/lib/uint-table.c @@ -34,6 +34,9 @@ #define CURL_UINT_TBL_MAGIC 0x62757473 #endif +/* Clear the table, making it empty. */ +UNITTEST void Curl_uint_tbl_clear(struct uint_tbl *tbl); + void Curl_uint_tbl_init(struct uint_tbl *tbl, Curl_uint_tbl_entry_dtor *entry_dtor) { @@ -68,7 +71,7 @@ CURLcode Curl_uint_tbl_resize(struct uint_tbl *tbl, unsigned int nrows) { /* we use `tbl->nrows + 1` during iteration, want that to work */ DEBUGASSERT(tbl->init == CURL_UINT_TBL_MAGIC); - if(!nrows || (nrows == UINT_MAX)) + if(!nrows) return CURLE_BAD_FUNCTION_ARGUMENT; if(nrows != tbl->nrows) { void **rows = calloc(nrows, sizeof(void *)); @@ -95,8 +98,7 @@ void Curl_uint_tbl_destroy(struct uint_tbl *tbl) memset(tbl, 0, sizeof(*tbl)); } - -void Curl_uint_tbl_clear(struct uint_tbl *tbl) +UNITTEST void Curl_uint_tbl_clear(struct uint_tbl *tbl) { DEBUGASSERT(tbl->init == CURL_UINT_TBL_MAGIC); uint_tbl_clear_rows(tbl, 0, tbl->nrows); @@ -130,7 +132,7 @@ bool Curl_uint_tbl_add(struct uint_tbl *tbl, void *entry, unsigned int *pkey) DEBUGASSERT(tbl->init == CURL_UINT_TBL_MAGIC); if(!entry || !pkey) return FALSE; - *pkey = UINT_MAX; /* always invalid */ + *pkey = UINT_MAX; if(tbl->nentries == tbl->nrows) /* full */ return FALSE; diff --git a/vendor/curl/lib/uint-table.h b/vendor/curl/lib/uint-table.h index 2c05b1de1ab..c74ec7ad634 100644 --- a/vendor/curl/lib/uint-table.h +++ b/vendor/curl/lib/uint-table.h @@ -60,9 +60,6 @@ unsigned int Curl_uint_tbl_capacity(struct uint_tbl *tbl); /* Get the number of entries in the table. */ unsigned int Curl_uint_tbl_count(struct uint_tbl *tbl); -/* Clear the table, making it empty. */ -void Curl_uint_tbl_clear(struct uint_tbl *tbl); - /* Get the entry for key or NULL if not present */ void *Curl_uint_tbl_get(struct uint_tbl *tbl, unsigned int key); diff --git a/vendor/curl/lib/url.c b/vendor/curl/lib/url.c index 10e37ec67f4..86d744a5549 100644 --- a/vendor/curl/lib/url.c +++ b/vendor/curl/lib/url.c @@ -59,6 +59,13 @@ #error "We cannot compile without socket() support!" #endif +#if defined(HAVE_IF_NAMETOINDEX) && defined(_WIN32) +#if defined(__MINGW32__) && (__MINGW64_VERSION_MAJOR <= 5) +#include /* workaround for old mingw-w64 missing to include it */ +#endif +#include +#endif + #include #include "doh.h" @@ -107,7 +114,6 @@ #include "imap.h" #include "url.h" #include "connect.h" -#include "inet_ntop.h" #include "http_ntlm.h" #include "curl_rtmp.h" #include "gopher.h" @@ -231,22 +237,24 @@ CURLcode Curl_close(struct Curl_easy **datap) data = *datap; *datap = NULL; - /* Detach connection if any is left. This should not be normal, but can be - the case for example with CONNECT_ONLY + recv/send (test 556) */ - Curl_detach_connection(data); - if(!data->state.internal) { - if(data->multi) - /* This handle is still part of a multi handle, take care of this first - and detach this handle from there. */ - curl_multi_remove_handle(data->multi, data); - - if(data->multi_easy) { + if(!data->state.internal && data->multi) { + /* This handle is still part of a multi handle, take care of this first + and detach this handle from there. + This detaches the connection. */ + curl_multi_remove_handle(data->multi, data); + } + else { + /* Detach connection if any is left. This should not be normal, but can be + the case for example with CONNECT_ONLY + recv/send (test 556) */ + Curl_detach_connection(data); + if(!data->state.internal && data->multi_easy) { /* when curl_easy_perform() is used, it creates its own multi handle to use and this is the one */ curl_multi_cleanup(data->multi_easy); data->multi_easy = NULL; } } + DEBUGASSERT(!data->conn || data->state.internal); Curl_expire_clear(data); /* shut off any timers left */ @@ -380,7 +388,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) set->ftp_filemethod = FTPFILE_MULTICWD; set->ftp_skip_ip = TRUE; /* skip PASV IP by default */ #endif - set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ + set->dns_cache_timeout_ms = 60000; /* Timeout every 60 seconds by default */ /* Timeout every 24 hours by default */ set->general_ssl.ca_cache_timeout = 24 * 60 * 60; @@ -422,13 +430,11 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) /* Set the default CA cert bundle/path detected/specified at build time. * - * If Schannel or Secure Transport is the selected SSL backend then these - * locations are ignored. We allow setting CA location for Schannel and - * Secure Transport when explicitly specified by the user via - * CURLOPT_CAINFO / --cacert. + * If Schannel is the selected SSL backend then these locations are ignored. + * We allow setting CA location for Schannel when explicitly specified by + * the user via CURLOPT_CAINFO / --cacert. */ - if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL && - Curl_ssl_backend() != CURLSSLBACKEND_SECURETRANSPORT) { + if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) { #ifdef CURL_CA_BUNDLE result = Curl_setstropt(&set->str[STRING_SSL_CAFILE], CURL_CA_BUNDLE); if(result) @@ -452,6 +458,14 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) #endif } + /* set default minimum TLS version */ +#ifdef USE_SSL + Curl_setopt_SSLVERSION(data, CURLOPT_SSLVERSION, CURL_SSLVERSION_DEFAULT); +#ifndef CURL_DISABLE_PROXY + Curl_setopt_SSLVERSION(data, CURLOPT_PROXY_SSLVERSION, + CURL_SSLVERSION_DEFAULT); +#endif +#endif #ifndef CURL_DISABLE_FTP set->wildcard_enabled = FALSE; set->chunk_bgn = ZERO_NULL; @@ -472,8 +486,8 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) set->happy_eyeballs_timeout = CURL_HET_DEFAULT; set->upkeep_interval_ms = CURL_UPKEEP_INTERVAL_DEFAULT; set->maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */ - set->maxage_conn = 118; - set->maxlifetime_conn = 0; + set->conn_max_idle_ms = 118 * 1000; + set->conn_max_age_ms = 0; set->http09_allowed = FALSE; set->httpwant = CURL_HTTP_VERSION_NONE ; @@ -640,7 +654,7 @@ proxy_info_matches(const struct proxy_info *data, { if((data->proxytype == needle->proxytype) && (data->port == needle->port) && - strcasecompare(data->host.name, needle->host.name)) + curl_strequal(data->host.name, needle->host.name)) return TRUE; return FALSE; @@ -670,36 +684,36 @@ socks_proxy_info_matches(const struct proxy_info *data, #define socks_proxy_info_matches(x,y) FALSE #endif -/* A connection has to have been idle for a shorter time than 'maxage_conn' +/* A connection has to have been idle for less than 'conn_max_idle_ms' (the success rate is just too low after this), or created less than - 'maxlifetime_conn' ago, to be subject for reuse. */ - + 'conn_max_age_ms' ago, to be subject for reuse. */ static bool conn_maxage(struct Curl_easy *data, struct connectdata *conn, struct curltime now) { - timediff_t idletime, lifetime; - - idletime = curlx_timediff(now, conn->lastused); - idletime /= 1000; /* integer seconds is fine */ + timediff_t age_ms; - if(idletime > data->set.maxage_conn) { - infof(data, "Too old connection (%" FMT_TIMEDIFF_T - " seconds idle), disconnect it", idletime); - return TRUE; + if(data->set.conn_max_idle_ms) { + age_ms = curlx_timediff(now, conn->lastused); + if(age_ms > data->set.conn_max_idle_ms) { + infof(data, "Too old connection (%" FMT_TIMEDIFF_T + " ms idle, max idle is %" FMT_TIMEDIFF_T " ms), disconnect it", + age_ms, data->set.conn_max_idle_ms); + return TRUE; + } } - lifetime = curlx_timediff(now, conn->created); - lifetime /= 1000; /* integer seconds is fine */ - - if(data->set.maxlifetime_conn && lifetime > data->set.maxlifetime_conn) { - infof(data, - "Too old connection (%" FMT_TIMEDIFF_T - " seconds since creation), disconnect it", lifetime); - return TRUE; + if(data->set.conn_max_age_ms) { + age_ms = curlx_timediff(now, conn->created); + if(age_ms > data->set.conn_max_age_ms) { + infof(data, + "Too old connection (created %" FMT_TIMEDIFF_T + " ms ago, max lifetime is %" FMT_TIMEDIFF_T " ms), disconnect it", + age_ms, data->set.conn_max_age_ms); + return TRUE; + } } - return FALSE; } @@ -829,7 +843,7 @@ static bool url_match_connect_config(struct connectdata *conn, struct url_conn_match *m) { /* connect-only or to-be-closed connections will not be reused */ - if(conn->connect_only || conn->bits.close) + if(conn->connect_only || conn->bits.close || conn->bits.no_reuse) return FALSE; /* ip_version must match */ @@ -1125,7 +1139,7 @@ static bool url_match_destination(struct connectdata *conn, || !m->needle->bits.httpproxy || m->needle->bits.tunnel_proxy #endif ) { - if(!strcasecompare(m->needle->handler->scheme, conn->handler->scheme)) { + if(!curl_strequal(m->needle->handler->scheme, conn->handler->scheme)) { /* `needle` and `conn` do not have the same scheme... */ if(get_protocol_family(conn->handler) != m->needle->handler->protocol) { /* and `conn`s protocol family is not the protocol `needle` wants. @@ -1142,14 +1156,14 @@ static bool url_match_destination(struct connectdata *conn, } /* If needle has "conn_to_*" set, conn must match this */ - if((m->needle->bits.conn_to_host && !strcasecompare( + if((m->needle->bits.conn_to_host && !curl_strequal( m->needle->conn_to_host.name, conn->conn_to_host.name)) || (m->needle->bits.conn_to_port && m->needle->conn_to_port != conn->conn_to_port)) return FALSE; /* hostname and port must match */ - if(!strcasecompare(m->needle->host.name, conn->host.name) || + if(!curl_strequal(m->needle->host.name, conn->host.name) || m->needle->remote_port != conn->remote_port) return FALSE; } @@ -1370,38 +1384,6 @@ ConnectionExists(struct Curl_easy *data, return result; } -/* - * verboseconnect() displays verbose information after a connect - */ -#ifndef CURL_DISABLE_VERBOSE_STRINGS -void Curl_verboseconnect(struct Curl_easy *data, - struct connectdata *conn, int sockindex) -{ - if(data->set.verbose && sockindex == SECONDARYSOCKET) - infof(data, "Connected 2nd connection to %s port %u", - conn->secondary.remote_ip, conn->secondary.remote_port); - else - infof(data, "Connected to %s (%s) port %u", - CURL_CONN_HOST_DISPNAME(conn), conn->primary.remote_ip, - conn->primary.remote_port); -#ifndef CURL_DISABLE_HTTP - if(conn->handler->protocol & PROTO_FAMILY_HTTP) { - switch(conn->alpn) { - case CURL_HTTP_VERSION_3: - infof(data, "using HTTP/3"); - break; - case CURL_HTTP_VERSION_2: - infof(data, "using HTTP/2"); - break; - default: - infof(data, "using HTTP/1.x"); - break; - } - } -#endif -} -#endif - /* * Allocate and initialize a new connectdata object. */ @@ -1415,10 +1397,9 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ - conn->sockfd = CURL_SOCKET_BAD; - conn->writesockfd = CURL_SOCKET_BAD; + conn->recv_idx = 0; /* default for receiving transfer data */ + conn->send_idx = 0; /* default for sending transfer data */ conn->connection_id = -1; /* no ID */ - conn->primary.remote_port = -1; /* unknown at this point */ conn->remote_port = -1; /* unknown at this point */ /* Default protocol-independent behavior does not support persistent @@ -1461,7 +1442,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) #endif conn->ip_version = data->set.ipver; conn->connect_only = data->set.connect_only; - conn->transport = TRNSPRT_TCP; /* most of them are TCP streams */ + conn->transport_wanted = TRNSPRT_TCP; /* most of them are TCP streams */ /* Initialize the attached xfers bitset */ Curl_uint_spbset_init(&conn->xfers_attached); @@ -1711,7 +1692,7 @@ const struct Curl_handler *Curl_getn_scheme_handler(const char *scheme, } h = protocols[c % 67]; - if(h && strncasecompare(scheme, h->scheme, len) && !h->scheme[len]) + if(h && curl_strnequal(scheme, h->scheme, len) && !h->scheme[len]) return h; } return NULL; @@ -1795,10 +1776,10 @@ static void zonefrom_url(CURLU *uh, struct Curl_easy *data, #if defined(HAVE_IF_NAMETOINDEX) || defined(_WIN32) /* Zone identifier is not numeric */ unsigned int scopeidx = 0; -#ifdef _WIN32 - scopeidx = Curl_if_nametoindex(zoneid); -#else +#ifdef HAVE_IF_NAMETOINDEX scopeidx = if_nametoindex(zoneid); +#else + scopeidx = Curl_if_nametoindex(zoneid); #endif if(!scopeidx) { #ifndef CURL_DISABLE_VERBOSE_STRINGS @@ -1885,7 +1866,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, uc = curl_url_get(uh, CURLUPART_HOST, &data->state.up.hostname, 0); if(uc) { - if(!strcasecompare("file", data->state.up.scheme)) + if(!curl_strequal("file", data->state.up.scheme)) return CURLE_OUT_OF_MEMORY; } else if(strlen(data->state.up.hostname) > MAX_URL_LEN) { @@ -1922,7 +1903,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, #ifndef CURL_DISABLE_HSTS /* HSTS upgrade */ - if(data->hsts && strcasecompare("http", data->state.up.scheme)) { + if(data->hsts && curl_strequal("http", data->state.up.scheme)) { /* This MUST use the IDN decoded name */ if(Curl_hsts(data->hsts, conn->host.name, strlen(conn->host.name), TRUE)) { char *url; @@ -2016,7 +1997,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, uc = curl_url_get(uh, CURLUPART_PORT, &data->state.up.port, CURLU_DEFAULT_PORT); if(uc) { - if(!strcasecompare("file", data->state.up.scheme)) + if(!curl_strequal("file", data->state.up.scheme)) return CURLE_OUT_OF_MEMORY; } else { @@ -2030,7 +2011,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, valid = FALSE; } if(valid) - conn->primary.remote_port = conn->remote_port = (unsigned short)port; + conn->remote_port = (unsigned short)port; } (void)curl_url_get(uh, CURLUPART_QUERY, &data->state.up.query, 0); @@ -2089,33 +2070,21 @@ static CURLcode setup_range(struct Curl_easy *data) static CURLcode setup_connection_internals(struct Curl_easy *data, struct connectdata *conn) { - const struct Curl_handler *p; const char *hostname; int port; CURLcode result; - /* Perform setup complement if some. */ - p = conn->handler; - - if(p->setup_connection) { - result = (*p->setup_connection)(data, conn); - + if(conn->handler->setup_connection) { + result = conn->handler->setup_connection(data, conn); if(result) return result; - - p = conn->handler; /* May have changed. */ } - if(conn->primary.remote_port < 0) - /* we check for -1 here since if proxy was detected already, this was - likely already set to the proxy port */ - conn->primary.remote_port = p->defport; - /* Now create the destination name */ #ifndef CURL_DISABLE_PROXY if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { hostname = conn->http_proxy.host.name; - port = conn->primary.remote_port; + port = conn->http_proxy.port; } else #endif @@ -2195,7 +2164,7 @@ static char *detect_proxy(struct Curl_easy *data, * This can cause 'internal' http/ftp requests to be * arbitrarily redirected by any external attacker. */ - if(!proxy && !strcasecompare("http_proxy", proxy_env)) { + if(!proxy && !curl_strequal("http_proxy", proxy_env)) { /* There was no lowercase variable, try the uppercase version: */ Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env)); proxy = curl_getenv(proxy_env); @@ -2204,10 +2173,10 @@ static char *detect_proxy(struct Curl_easy *data, if(!proxy) { #ifndef CURL_DISABLE_WEBSOCKETS /* websocket proxy fallbacks */ - if(strcasecompare("ws_proxy", proxy_env)) { + if(curl_strequal("ws_proxy", proxy_env)) { proxy = curl_getenv("http_proxy"); } - else if(strcasecompare("wss_proxy", proxy_env)) { + else if(curl_strequal("wss_proxy", proxy_env)) { proxy = curl_getenv("https_proxy"); if(!proxy) proxy = curl_getenv("HTTPS_PROXY"); @@ -2238,7 +2207,7 @@ static char *detect_proxy(struct Curl_easy *data, */ static CURLcode parse_proxy(struct Curl_easy *data, struct connectdata *conn, char *proxy, - curl_proxytype proxytype) + long proxytype) { char *portptr = NULL; int port = -1; @@ -2274,22 +2243,22 @@ static CURLcode parse_proxy(struct Curl_easy *data, goto error; } - if(strcasecompare("https", scheme)) { + if(curl_strequal("https", scheme)) { if(proxytype != CURLPROXY_HTTPS2) proxytype = CURLPROXY_HTTPS; else proxytype = CURLPROXY_HTTPS2; } - else if(strcasecompare("socks5h", scheme)) + else if(curl_strequal("socks5h", scheme)) proxytype = CURLPROXY_SOCKS5_HOSTNAME; - else if(strcasecompare("socks5", scheme)) + else if(curl_strequal("socks5", scheme)) proxytype = CURLPROXY_SOCKS5; - else if(strcasecompare("socks4a", scheme)) + else if(curl_strequal("socks4a", scheme)) proxytype = CURLPROXY_SOCKS4A; - else if(strcasecompare("socks4", scheme) || - strcasecompare("socks", scheme)) + else if(curl_strequal("socks4", scheme) || + curl_strequal("socks", scheme)) proxytype = CURLPROXY_SOCKS4; - else if(strcasecompare("http", scheme)) + else if(curl_strequal("http", scheme)) ; /* leave it as HTTP or HTTP/1.0 */ else { /* Any other xxx:// reject! */ @@ -2376,12 +2345,8 @@ static CURLcode parse_proxy(struct Curl_easy *data, port = CURL_DEFAULT_PROXY_PORT; } } - if(port >= 0) { + if(port >= 0) proxyinfo->port = port; - if(conn->primary.remote_port < 0 || sockstype || - !conn->socks_proxy.host.rawalloc) - conn->primary.remote_port = port; - } /* now, clone the proxy hostname */ uc = curl_url_get(uhp, CURLUPART_HOST, &host, CURLU_URLDECODE); @@ -2390,7 +2355,7 @@ static CURLcode parse_proxy(struct Curl_easy *data, goto error; } #ifdef USE_UNIX_SOCKETS - if(sockstype && strcasecompare(UNIX_SOCKET_PREFIX, host)) { + if(sockstype && curl_strequal(UNIX_SOCKET_PREFIX, host)) { uc = curl_url_get(uhp, CURLUPART_PATH, &path, CURLU_URLDECODE); if(uc) { result = CURLE_OUT_OF_MEMORY; @@ -2556,7 +2521,7 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data, * connection that may exist registered to the same proxy host. ***********************************************************************/ if(proxy || socksproxy) { - curl_proxytype ptype = (curl_proxytype)conn->http_proxy.proxytype; + long ptype = conn->http_proxy.proxytype; if(proxy) { result = parse_proxy(data, conn, proxy, ptype); Curl_safefree(proxy); /* parse_proxy copies the proxy string */ @@ -2757,16 +2722,20 @@ static CURLcode parse_remote_port(struct Curl_easy *data, return CURLE_OK; } +#ifndef CURL_DISABLE_NETRC static bool str_has_ctrl(const char *input) { - const unsigned char *str = (const unsigned char *)input; - while(*str) { - if(*str < 0x20) - return TRUE; - str++; + if(input) { + const unsigned char *str = (const unsigned char *)input; + while(*str) { + if(*str < 0x20) + return TRUE; + str++; + } } return FALSE; } +#endif /* * Override the login details from the URL with that in the CURLOPT_USERPWD @@ -2945,7 +2914,7 @@ static CURLcode parse_connect_to_host_port(struct Curl_easy *data, CURLcode result = CURLE_OK; #ifdef CURL_DISABLE_VERBOSE_STRINGS - (void) data; + (void)data; #endif *hostname_result = NULL; @@ -3062,8 +3031,8 @@ static CURLcode parse_connect_to_string(struct Curl_easy *data, if(!hostname_to_match) return CURLE_OUT_OF_MEMORY; hostname_to_match_len = strlen(hostname_to_match); - host_match = strncasecompare(ptr, hostname_to_match, - hostname_to_match_len); + host_match = curl_strnequal(ptr, hostname_to_match, + hostname_to_match_len); free(hostname_to_match); ptr += hostname_to_match_len; @@ -3184,8 +3153,8 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data, &as /* to */, allowed_alpns); } - #endif - #ifdef USE_HTTP2 +#endif +#ifdef USE_HTTP2 if(!hit && (neg->wanted & CURL_HTTP_V2x) && !neg->h2_prior_knowledge) { srcalpnid = ALPN_h2; @@ -3194,7 +3163,7 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data, &as /* to */, allowed_alpns); } - #endif +#endif if(!hit && (neg->wanted & CURL_HTTP_V1x) && !neg->only_10) { srcalpnid = ALPN_h1; @@ -3228,7 +3197,7 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data, neg->wanted = neg->allowed = CURL_HTTP_V2x; break; case ALPN_h3: - conn->transport = TRNSPRT_QUIC; + conn->transport_wanted = TRNSPRT_QUIC; neg->wanted = neg->allowed = CURL_HTTP_V3x; break; default: /* should not be possible */ @@ -3286,6 +3255,7 @@ static CURLcode resolve_server(struct Curl_easy *data, struct Curl_dns_entry **pdns) { struct hostname *ehost; + int eport; timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); const char *peertype = "host"; CURLcode result; @@ -3305,7 +3275,7 @@ static CURLcode resolve_server(struct Curl_easy *data, if(unix_path) { /* This only works if previous transport is TRNSPRT_TCP. Check it? */ - conn->transport = TRNSPRT_UNIX; + conn->transport_wanted = TRNSPRT_UNIX; return resolve_unix(data, conn, unix_path, pdns); } } @@ -3315,6 +3285,8 @@ static CURLcode resolve_server(struct Curl_easy *data, if(CONN_IS_PROXIED(conn)) { ehost = conn->bits.socksproxy ? &conn->socks_proxy.host : &conn->http_proxy.host; + eport = conn->bits.socksproxy ? conn->socks_proxy.port : + conn->http_proxy.port; peertype = "proxy"; } else @@ -3323,8 +3295,7 @@ static CURLcode resolve_server(struct Curl_easy *data, ehost = conn->bits.conn_to_host ? &conn->conn_to_host : &conn->host; /* If not connecting via a proxy, extract the port from the URL, if it is * there, thus overriding any defaults that might have been set above. */ - conn->primary.remote_port = conn->bits.conn_to_port ? conn->conn_to_port : - conn->remote_port; + eport = conn->bits.conn_to_port ? conn->conn_to_port : conn->remote_port; } /* Resolve target host right on */ @@ -3333,7 +3304,7 @@ static CURLcode resolve_server(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; result = Curl_resolv_timeout(data, conn->hostname_resolve, - conn->primary.remote_port, conn->ip_version, + eport, conn->ip_version, pdns, timeout_ms); DEBUGASSERT(!result || !*pdns); if(result == CURLE_AGAIN) { @@ -3596,7 +3567,7 @@ static CURLcode create_conn(struct Curl_easy *data, * Do this after the hostnames have been IDN-converted. *************************************************************/ if(conn->bits.conn_to_host && - strcasecompare(conn->conn_to_host.name, conn->host.name)) { + curl_strequal(conn->conn_to_host.name, conn->host.name)) { conn->bits.conn_to_host = FALSE; } @@ -3710,7 +3681,7 @@ static CURLcode create_conn(struct Curl_easy *data, *in_connect = conn; #ifndef CURL_DISABLE_PROXY - infof(data, "Re-using existing %s: connection%s with %s %s", + infof(data, "Reusing existing %s: connection%s with %s %s", conn->given->scheme, tls_upgraded ? " (upgraded to SSL)" : "", conn->bits.proxy ? "proxy" : "host", @@ -3718,7 +3689,7 @@ static CURLcode create_conn(struct Curl_easy *data, conn->http_proxy.host.name ? conn->http_proxy.host.dispname : conn->host.dispname); #else - infof(data, "Re-using existing %s: connection%s with host %s", + infof(data, "Reusing existing %s: connection%s with host %s", conn->given->scheme, tls_upgraded ? " (upgraded to SSL)" : "", conn->host.dispname); @@ -4071,7 +4042,7 @@ void Curl_data_priority_clear_state(struct Curl_easy *data) memset(&data->state.priority, 0, sizeof(data->state.priority)); } -#endif /* defined(USE_HTTP2) || defined(USE_HTTP3) */ +#endif /* USE_HTTP2 || USE_HTTP3 */ CURLcode Curl_conn_meta_set(struct connectdata *conn, const char *key, @@ -4094,3 +4065,17 @@ void *Curl_conn_meta_get(struct connectdata *conn, const char *key) { return Curl_hash_pick(&conn->meta_hash, CURL_UNCONST(key), strlen(key) + 1); } + +CURLcode Curl_1st_err(CURLcode r1, CURLcode r2) +{ + return r1 ? r1 : r2; +} + +CURLcode Curl_1st_fatal(CURLcode r1, CURLcode r2) +{ + if(r1 && (r1 != CURLE_AGAIN)) + return r1; + if(r2 && (r2 != CURLE_AGAIN)) + return r2; + return r1; +} diff --git a/vendor/curl/lib/url.h b/vendor/curl/lib/url.h index 7aba98dbb93..11a69d41578 100644 --- a/vendor/curl/lib/url.h +++ b/vendor/curl/lib/url.h @@ -79,13 +79,6 @@ const struct Curl_handler *Curl_getn_scheme_handler(const char *scheme, #define CURL_DEFAULT_HTTPS_PROXY_PORT 443 /* default https proxy port unless specified */ -#ifdef CURL_DISABLE_VERBOSE_STRINGS -#define Curl_verboseconnect(x,y,z) Curl_nop_stmt -#else -void Curl_verboseconnect(struct Curl_easy *data, struct connectdata *conn, - int sockindex); -#endif - /** * Return TRUE iff the given connection is considered dead. * @param nowp NULL or pointer to time being checked against. @@ -101,11 +94,24 @@ CURLcode Curl_conn_upkeep(struct Curl_easy *data, struct connectdata *conn, struct curltime *now); +/** + * Always eval all arguments, return the first result != CURLE_OK. + * A non-short-circuit evaluation. + */ +CURLcode Curl_1st_err(CURLcode r1, CURLcode r2); + +/** + * Always eval all arguments, return the first + * result != (CURLE_OK|CURLE_AGAIN) or `r1`. + * A non-short-circuit evaluation. + */ +CURLcode Curl_1st_fatal(CURLcode r1, CURLcode r2); + #if defined(USE_HTTP2) || defined(USE_HTTP3) void Curl_data_priority_clear_state(struct Curl_easy *data); #else #define Curl_data_priority_clear_state(x) -#endif /* !(defined(USE_HTTP2) || defined(USE_HTTP3)) */ +#endif /* USE_HTTP2 || USE_HTTP3 */ #ifdef USE_NGHTTP2 CURLcode Curl_data_priority_add_child(struct Curl_easy *parent, diff --git a/vendor/curl/lib/urlapi.c b/vendor/curl/lib/urlapi.c index 6a7ab1a575e..c89852794e0 100644 --- a/vendor/curl/lib/urlapi.c +++ b/vendor/curl/lib/urlapi.c @@ -31,7 +31,7 @@ #include "escape.h" #include "curl_ctype.h" #include "curlx/inet_pton.h" -#include "inet_ntop.h" +#include "curlx/inet_ntop.h" #include "strdup.h" #include "idn.h" #include "curlx/strparse.h" @@ -164,7 +164,7 @@ static CURLUcode urlencode_str(struct dynbuf *o, const char *url, } else if((*iptr < ' ') || (*iptr >= 0x7f)) { unsigned char out[3]={'%'}; - Curl_hexbyte(&out[1], *iptr, TRUE); + Curl_hexbyte(&out[1], *iptr); result = curlx_dyn_addn(o, out, 3); } else { @@ -511,9 +511,9 @@ static CURLUcode ipv6_parse(struct Curl_URL *u, char *hostname, { char dest[16]; /* fits a binary IPv6 address */ hostname[hlen] = 0; /* end the address there */ - if(1 != curlx_inet_pton(AF_INET6, hostname, dest)) + if(curlx_inet_pton(AF_INET6, hostname, dest) != 1) return CURLUE_BAD_IPV6; - if(Curl_inet_ntop(AF_INET6, dest, hostname, hlen)) { + if(curlx_inet_ntop(AF_INET6, dest, hostname, hlen)) { hlen = strlen(hostname); /* might be shorter now */ hostname[hlen + 1] = 0; } @@ -1320,18 +1320,221 @@ CURLU *curl_url_dup(const CURLU *in) return NULL; } +#ifndef USE_IDN +#define host_decode(x,y) CURLUE_LACKS_IDN +#define host_encode(x,y) CURLUE_LACKS_IDN +#else +static CURLUcode host_decode(const char *host, char **allochost) +{ + CURLcode result = Curl_idn_decode(host, allochost); + if(result) + return (result == CURLE_OUT_OF_MEMORY) ? + CURLUE_OUT_OF_MEMORY : CURLUE_BAD_HOSTNAME; + return CURLUE_OK; +} + +static CURLUcode host_encode(const char *host, char **allochost) +{ + CURLcode result = Curl_idn_encode(host, allochost); + if(result) + return (result == CURLE_OUT_OF_MEMORY) ? + CURLUE_OUT_OF_MEMORY : CURLUE_BAD_HOSTNAME; + return CURLUE_OK; +} +#endif + +static CURLUcode urlget_format(const CURLU *u, CURLUPart what, + const char *ptr, char **part, + bool plusdecode, unsigned int flags) +{ + size_t partlen = strlen(ptr); + bool urldecode = (flags & CURLU_URLDECODE) ? 1 : 0; + bool urlencode = (flags & CURLU_URLENCODE) ? 1 : 0; + bool punycode = (flags & CURLU_PUNYCODE) && (what == CURLUPART_HOST); + bool depunyfy = (flags & CURLU_PUNY2IDN) && (what == CURLUPART_HOST); + *part = Curl_memdup0(ptr, partlen); + if(!*part) + return CURLUE_OUT_OF_MEMORY; + if(plusdecode) { + /* convert + to space */ + char *plus = *part; + size_t i = 0; + for(i = 0; i < partlen; ++plus, i++) { + if(*plus == '+') + *plus = ' '; + } + } + if(urldecode) { + char *decoded; + size_t dlen; + /* this unconditional rejection of control bytes is documented + API behavior */ + CURLcode res = Curl_urldecode(*part, 0, &decoded, &dlen, REJECT_CTRL); + free(*part); + if(res) { + *part = NULL; + return CURLUE_URLDECODE; + } + *part = decoded; + partlen = dlen; + } + if(urlencode) { + struct dynbuf enc; + CURLUcode uc; + curlx_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); + uc = urlencode_str(&enc, *part, partlen, TRUE, what == CURLUPART_QUERY); + if(uc) + return uc; + free(*part); + *part = curlx_dyn_ptr(&enc); + } + else if(punycode) { + if(!Curl_is_ASCII_name(u->host)) { + char *allochost = NULL; + CURLUcode ret = host_decode(*part, &allochost); + if(ret) + return ret; + free(*part); + *part = allochost; + } + } + else if(depunyfy) { + if(Curl_is_ASCII_name(u->host)) { + char *allochost = NULL; + CURLUcode ret = host_encode(*part, &allochost); + if(ret) + return ret; + free(*part); + *part = allochost; + } + } + + return CURLUE_OK; +} + +static CURLUcode urlget_url(const CURLU *u, char **part, unsigned int flags) +{ + char *url; + const char *scheme; + char *options = u->options; + char *port = u->port; + char *allochost = NULL; + bool show_fragment = + u->fragment || (u->fragment_present && flags & CURLU_GET_EMPTY); + bool show_query = (u->query && u->query[0]) || + (u->query_present && flags & CURLU_GET_EMPTY); + bool punycode = (flags & CURLU_PUNYCODE) ? 1 : 0; + bool depunyfy = (flags & CURLU_PUNY2IDN) ? 1 : 0; + bool urlencode = (flags & CURLU_URLENCODE) ? 1 : 0; + char portbuf[7]; + if(u->scheme && curl_strequal("file", u->scheme)) { + url = aprintf("file://%s%s%s%s%s", + u->path, + show_query ? "?": "", + u->query ? u->query : "", + show_fragment ? "#": "", + u->fragment ? u->fragment : ""); + } + else if(!u->host) + return CURLUE_NO_HOST; + else { + const struct Curl_handler *h = NULL; + char schemebuf[MAX_SCHEME_LEN + 5]; + if(u->scheme) + scheme = u->scheme; + else if(flags & CURLU_DEFAULT_SCHEME) + scheme = DEFAULT_SCHEME; + else + return CURLUE_NO_SCHEME; + + h = Curl_get_scheme_handler(scheme); + if(!port && (flags & CURLU_DEFAULT_PORT)) { + /* there is no stored port number, but asked to deliver + a default one for the scheme */ + if(h) { + msnprintf(portbuf, sizeof(portbuf), "%u", h->defport); + port = portbuf; + } + } + else if(port) { + /* there is a stored port number, but asked to inhibit if it matches + the default one for the scheme */ + if(h && (h->defport == u->portnum) && + (flags & CURLU_NO_DEFAULT_PORT)) + port = NULL; + } + + if(h && !(h->flags & PROTOPT_URLOPTIONS)) + options = NULL; + + if(u->host[0] == '[') { + if(u->zoneid) { + /* make it '[ host %25 zoneid ]' */ + struct dynbuf enc; + size_t hostlen = strlen(u->host); + curlx_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); + if(curlx_dyn_addf(&enc, "%.*s%%25%s]", (int)hostlen - 1, u->host, + u->zoneid)) + return CURLUE_OUT_OF_MEMORY; + allochost = curlx_dyn_ptr(&enc); + } + } + else if(urlencode) { + allochost = curl_easy_escape(NULL, u->host, 0); + if(!allochost) + return CURLUE_OUT_OF_MEMORY; + } + else if(punycode) { + if(!Curl_is_ASCII_name(u->host)) { + CURLUcode ret = host_decode(u->host, &allochost); + if(ret) + return ret; + } + } + else if(depunyfy) { + if(Curl_is_ASCII_name(u->host)) { + CURLUcode ret = host_encode(u->host, &allochost); + if(ret) + return ret; + } + } + + if(!(flags & CURLU_NO_GUESS_SCHEME) || !u->guessed_scheme) + msnprintf(schemebuf, sizeof(schemebuf), "%s://", scheme); + else + schemebuf[0] = 0; + + url = aprintf("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + schemebuf, + u->user ? u->user : "", + u->password ? ":": "", + u->password ? u->password : "", + options ? ";" : "", + options ? options : "", + (u->user || u->password || options) ? "@": "", + allochost ? allochost : u->host, + port ? ":": "", + port ? port : "", + u->path ? u->path : "/", + show_query ? "?": "", + u->query ? u->query : "", + show_fragment ? "#": "", + u->fragment ? u->fragment : ""); + free(allochost); + } + if(!url) + return CURLUE_OUT_OF_MEMORY; + *part = url; + return CURLUE_OK; +} + CURLUcode curl_url_get(const CURLU *u, CURLUPart what, char **part, unsigned int flags) { const char *ptr; CURLUcode ifmissing = CURLUE_UNKNOWN_PART; char portbuf[7]; - bool urldecode = (flags & CURLU_URLDECODE) ? 1 : 0; - bool urlencode = (flags & CURLU_URLENCODE) ? 1 : 0; - bool punycode = FALSE; - bool depunyfy = FALSE; bool plusdecode = FALSE; - (void)flags; if(!u) return CURLUE_BAD_HANDLE; if(!part) @@ -1342,7 +1545,7 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what, case CURLUPART_SCHEME: ptr = u->scheme; ifmissing = CURLUE_NO_SCHEME; - urldecode = FALSE; /* never for schemes */ + flags &= ~CURLU_URLDECODE; /* never for schemes */ if((flags & CURLU_NO_GUESS_SCHEME) && u->guessed_scheme) return CURLUE_NO_SCHEME; break; @@ -1361,8 +1564,6 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what, case CURLUPART_HOST: ptr = u->host; ifmissing = CURLUE_NO_HOST; - punycode = (flags & CURLU_PUNYCODE) ? 1 : 0; - depunyfy = (flags & CURLU_PUNY2IDN) ? 1 : 0; break; case CURLUPART_ZONEID: ptr = u->zoneid; @@ -1371,7 +1572,7 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what, case CURLUPART_PORT: ptr = u->port; ifmissing = CURLUE_NO_PORT; - urldecode = FALSE; /* never for port */ + flags &= ~CURLU_URLDECODE; /* never for port */ if(!ptr && (flags & CURLU_DEFAULT_PORT) && u->scheme) { /* there is no stored port number, but asked to deliver a default one for the scheme */ @@ -1398,7 +1599,7 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what, case CURLUPART_QUERY: ptr = u->query; ifmissing = CURLUE_NO_QUERY; - plusdecode = urldecode; + plusdecode = flags & CURLU_URLDECODE; if(ptr && !ptr[0] && !(flags & CURLU_GET_EMPTY)) /* there was a blank query and the user do not ask for it */ ptr = NULL; @@ -1410,219 +1611,31 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what, /* there was a blank fragment and the user asks for it */ ptr = ""; break; - case CURLUPART_URL: { - char *url; - const char *scheme; - char *options = u->options; - char *port = u->port; - char *allochost = NULL; - bool show_fragment = - u->fragment || (u->fragment_present && flags & CURLU_GET_EMPTY); - bool show_query = - (u->query && u->query[0]) || - (u->query_present && flags & CURLU_GET_EMPTY); - punycode = (flags & CURLU_PUNYCODE) ? 1 : 0; - depunyfy = (flags & CURLU_PUNY2IDN) ? 1 : 0; - if(u->scheme && strcasecompare("file", u->scheme)) { - url = aprintf("file://%s%s%s%s%s", - u->path, - show_query ? "?": "", - u->query ? u->query : "", - show_fragment ? "#": "", - u->fragment ? u->fragment : ""); - } - else if(!u->host) - return CURLUE_NO_HOST; - else { - const struct Curl_handler *h = NULL; - char schemebuf[MAX_SCHEME_LEN + 5]; - if(u->scheme) - scheme = u->scheme; - else if(flags & CURLU_DEFAULT_SCHEME) - scheme = DEFAULT_SCHEME; - else - return CURLUE_NO_SCHEME; - - h = Curl_get_scheme_handler(scheme); - if(!port && (flags & CURLU_DEFAULT_PORT)) { - /* there is no stored port number, but asked to deliver - a default one for the scheme */ - if(h) { - msnprintf(portbuf, sizeof(portbuf), "%u", h->defport); - port = portbuf; - } - } - else if(port) { - /* there is a stored port number, but asked to inhibit if it matches - the default one for the scheme */ - if(h && (h->defport == u->portnum) && - (flags & CURLU_NO_DEFAULT_PORT)) - port = NULL; - } - - if(h && !(h->flags & PROTOPT_URLOPTIONS)) - options = NULL; - - if(u->host[0] == '[') { - if(u->zoneid) { - /* make it '[ host %25 zoneid ]' */ - struct dynbuf enc; - size_t hostlen = strlen(u->host); - curlx_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); - if(curlx_dyn_addf(&enc, "%.*s%%25%s]", (int)hostlen - 1, u->host, - u->zoneid)) - return CURLUE_OUT_OF_MEMORY; - allochost = curlx_dyn_ptr(&enc); - } - } - else if(urlencode) { - allochost = curl_easy_escape(NULL, u->host, 0); - if(!allochost) - return CURLUE_OUT_OF_MEMORY; - } - else if(punycode) { - if(!Curl_is_ASCII_name(u->host)) { -#ifndef USE_IDN - return CURLUE_LACKS_IDN; -#else - CURLcode result = Curl_idn_decode(u->host, &allochost); - if(result) - return (result == CURLE_OUT_OF_MEMORY) ? - CURLUE_OUT_OF_MEMORY : CURLUE_BAD_HOSTNAME; -#endif - } - } - else if(depunyfy) { - if(Curl_is_ASCII_name(u->host)) { -#ifndef USE_IDN - return CURLUE_LACKS_IDN; -#else - CURLcode result = Curl_idn_encode(u->host, &allochost); - if(result) - /* this is the most likely error */ - return (result == CURLE_OUT_OF_MEMORY) ? - CURLUE_OUT_OF_MEMORY : CURLUE_BAD_HOSTNAME; -#endif - } - } - - if(!(flags & CURLU_NO_GUESS_SCHEME) || !u->guessed_scheme) - msnprintf(schemebuf, sizeof(schemebuf), "%s://", scheme); - else - schemebuf[0] = 0; - - url = aprintf("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", - schemebuf, - u->user ? u->user : "", - u->password ? ":": "", - u->password ? u->password : "", - options ? ";" : "", - options ? options : "", - (u->user || u->password || options) ? "@": "", - allochost ? allochost : u->host, - port ? ":": "", - port ? port : "", - u->path ? u->path : "/", - show_query ? "?": "", - u->query ? u->query : "", - show_fragment ? "#": "", - u->fragment ? u->fragment : ""); - free(allochost); - } - if(!url) - return CURLUE_OUT_OF_MEMORY; - *part = url; - return CURLUE_OK; - } + case CURLUPART_URL: + return urlget_url(u, part, flags); default: ptr = NULL; break; } - if(ptr) { - size_t partlen = strlen(ptr); - size_t i = 0; - *part = Curl_memdup0(ptr, partlen); - if(!*part) - return CURLUE_OUT_OF_MEMORY; - if(plusdecode) { - /* convert + to space */ - char *plus = *part; - for(i = 0; i < partlen; ++plus, i++) { - if(*plus == '+') - *plus = ' '; - } - } - if(urldecode) { - char *decoded; - size_t dlen; - /* this unconditional rejection of control bytes is documented - API behavior */ - CURLcode res = Curl_urldecode(*part, 0, &decoded, &dlen, REJECT_CTRL); - free(*part); - if(res) { - *part = NULL; - return CURLUE_URLDECODE; - } - *part = decoded; - partlen = dlen; - } - if(urlencode) { - struct dynbuf enc; - CURLUcode uc; - curlx_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); - uc = urlencode_str(&enc, *part, partlen, TRUE, what == CURLUPART_QUERY); - if(uc) - return uc; - free(*part); - *part = curlx_dyn_ptr(&enc); - } - else if(punycode) { - if(!Curl_is_ASCII_name(u->host)) { -#ifndef USE_IDN - return CURLUE_LACKS_IDN; -#else - char *allochost; - CURLcode result = Curl_idn_decode(*part, &allochost); - if(result) - return (result == CURLE_OUT_OF_MEMORY) ? - CURLUE_OUT_OF_MEMORY : CURLUE_BAD_HOSTNAME; - free(*part); - *part = allochost; -#endif - } - } - else if(depunyfy) { - if(Curl_is_ASCII_name(u->host)) { -#ifndef USE_IDN - return CURLUE_LACKS_IDN; -#else - char *allochost; - CURLcode result = Curl_idn_encode(*part, &allochost); - if(result) - return (result == CURLE_OUT_OF_MEMORY) ? - CURLUE_OUT_OF_MEMORY : CURLUE_BAD_HOSTNAME; - free(*part); - *part = allochost; -#endif - } - } + if(ptr) + return urlget_format(u, what, ptr, part, plusdecode, flags); - return CURLUE_OK; - } - else - return ifmissing; + return ifmissing; } static CURLUcode set_url_scheme(CURLU *u, const char *scheme, - unsigned int flags) + unsigned int flags) { - size_t plen = strlen(scheme); + size_t plen = strlen(scheme); + const struct Curl_handler *h = NULL; + if((plen > MAX_SCHEME_LEN) || (plen < 1)) + /* too long or too short */ + return CURLUE_BAD_SCHEME; + /* verify that it is a fine scheme */ + h = Curl_get_scheme_handler(scheme); + if(!h) { const char *s = scheme; - if((plen > MAX_SCHEME_LEN) || (plen < 1)) - /* too long or too short */ - return CURLUE_BAD_SCHEME; - /* verify that it is a fine scheme */ - if(!(flags & CURLU_NON_SUPPORT_SCHEME) && !Curl_get_scheme_handler(scheme)) + if(!(flags & CURLU_NON_SUPPORT_SCHEME)) return CURLUE_UNSUPPORTED_SCHEME; if(ISALPHA(*s)) { /* ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */ @@ -1635,8 +1648,9 @@ static CURLUcode set_url_scheme(CURLU *u, const char *scheme, } else return CURLUE_BAD_SCHEME; - u->guessed_scheme = FALSE; - return CURLUE_OK; + } + u->guessed_scheme = FALSE; + return CURLUE_OK; } static CURLUcode set_url_port(CURLU *u, const char *provided_port) @@ -1659,7 +1673,7 @@ static CURLUcode set_url_port(CURLU *u, const char *provided_port) } static CURLUcode set_url(CURLU *u, const char *url, size_t part_size, - unsigned int flags) + unsigned int flags) { /* * Allow a new URL to replace the existing (if any) contents. @@ -1696,13 +1710,73 @@ static CURLUcode set_url(CURLU *u, const char *url, size_t part_size, return uc; } +static CURLUcode urlset_clear(CURLU *u, CURLUPart what) +{ + switch(what) { + case CURLUPART_URL: + free_urlhandle(u); + memset(u, 0, sizeof(struct Curl_URL)); + break; + case CURLUPART_SCHEME: + Curl_safefree(u->scheme); + u->guessed_scheme = FALSE; + break; + case CURLUPART_USER: + Curl_safefree(u->user); + break; + case CURLUPART_PASSWORD: + Curl_safefree(u->password); + break; + case CURLUPART_OPTIONS: + Curl_safefree(u->options); + break; + case CURLUPART_HOST: + Curl_safefree(u->host); + break; + case CURLUPART_ZONEID: + Curl_safefree(u->zoneid); + break; + case CURLUPART_PORT: + u->portnum = 0; + Curl_safefree(u->port); + break; + case CURLUPART_PATH: + Curl_safefree(u->path); + break; + case CURLUPART_QUERY: + Curl_safefree(u->query); + u->query_present = FALSE; + break; + case CURLUPART_FRAGMENT: + Curl_safefree(u->fragment); + u->fragment_present = FALSE; + break; + default: + return CURLUE_UNKNOWN_PART; + } + return CURLUE_OK; +} + +static bool allowed_in_path(unsigned char x) +{ + switch(x) { + case '!': case '$': case '&': case '\'': + case '(': case ')': case '{': case '}': + case '[': case ']': case '*': case '+': + case ',': case ';': case '=': case ':': + case '@': case '/': + return TRUE; + } + return FALSE; +} + CURLUcode curl_url_set(CURLU *u, CURLUPart what, const char *part, unsigned int flags) { char **storep = NULL; bool urlencode = (flags & CURLU_URLENCODE) ? 1 : 0; bool plusencode = FALSE; - bool urlskipslash = FALSE; + bool pathmode = FALSE; bool leadingslash = FALSE; bool appendquery = FALSE; bool equalsencode = FALSE; @@ -1710,57 +1784,9 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, if(!u) return CURLUE_BAD_HANDLE; - if(!part) { + if(!part) /* setting a part to NULL clears it */ - switch(what) { - case CURLUPART_URL: - break; - case CURLUPART_SCHEME: - storep = &u->scheme; - u->guessed_scheme = FALSE; - break; - case CURLUPART_USER: - storep = &u->user; - break; - case CURLUPART_PASSWORD: - storep = &u->password; - break; - case CURLUPART_OPTIONS: - storep = &u->options; - break; - case CURLUPART_HOST: - storep = &u->host; - break; - case CURLUPART_ZONEID: - storep = &u->zoneid; - break; - case CURLUPART_PORT: - u->portnum = 0; - storep = &u->port; - break; - case CURLUPART_PATH: - storep = &u->path; - break; - case CURLUPART_QUERY: - storep = &u->query; - u->query_present = FALSE; - break; - case CURLUPART_FRAGMENT: - storep = &u->fragment; - u->fragment_present = FALSE; - break; - default: - return CURLUE_UNKNOWN_PART; - } - if(storep && *storep) { - Curl_safefree(*storep); - } - else if(!storep) { - free_urlhandle(u); - memset(u, 0, sizeof(struct Curl_URL)); - } - return CURLUE_OK; - } + return urlset_clear(u, what); nalloc = strlen(part); if(nalloc > CURL_MAX_INPUT_LENGTH) @@ -1795,7 +1821,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, case CURLUPART_PORT: return set_url_port(u, part); case CURLUPART_PATH: - urlskipslash = TRUE; + pathmode = TRUE; leadingslash = TRUE; /* enforce */ storep = &u->path; break; @@ -1810,9 +1836,8 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, storep = &u->fragment; u->fragment_present = TRUE; break; - case CURLUPART_URL: { + case CURLUPART_URL: return set_url(u, part, nalloc, flags); - } default: return CURLUE_UNKNOWN_PART; } @@ -1838,7 +1863,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, return CURLUE_OUT_OF_MEMORY; } else if(ISUNRESERVED(*i) || - ((*i == '/') && urlskipslash) || + (pathmode && allowed_in_path(*i)) || ((*i == '=') && equalsencode)) { if((*i == '=') && equalsencode) /* only skip the first equals sign */ @@ -1849,7 +1874,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, } else { unsigned char out[3]={'%'}; - Curl_hexbyte(&out[1], *i, TRUE); + Curl_hexbyte(&out[1], *i); result = curlx_dyn_addn(&enc, out, 3); if(result) return cc2cu(result); diff --git a/vendor/curl/lib/urldata.h b/vendor/curl/lib/urldata.h index 45052e84b18..a35512cf7a8 100644 --- a/vendor/curl/lib/urldata.h +++ b/vendor/curl/lib/urldata.h @@ -70,11 +70,11 @@ struct curl_trc_featt; * platforms that have a >= 64-bit type and then we use such a type for the * protocol fields in the protocol handler. */ -#define CURLPROTO_WS (1<<30) +#define CURLPROTO_WS (1L<<30) #define CURLPROTO_WSS ((curl_prot_t)1<<31) #else -#define CURLPROTO_WS 0 -#define CURLPROTO_WSS 0 +#define CURLPROTO_WS 0L +#define CURLPROTO_WSS 0L #endif /* the default protocols accepting a redirect to */ @@ -158,20 +158,20 @@ typedef unsigned int curl_prot_t; #include "request.h" #include "netrc.h" -/* return the count of bytes sent, or -1 on error */ -typedef ssize_t (Curl_send)(struct Curl_easy *data, /* transfer */ - int sockindex, /* socketindex */ - const void *buf, /* data to write */ - size_t len, /* max amount to write */ - bool eos, /* last chunk */ - CURLcode *err); /* error to return */ - -/* return the count of bytes read, or -1 on error */ -typedef ssize_t (Curl_recv)(struct Curl_easy *data, /* transfer */ - int sockindex, /* socketindex */ - char *buf, /* store data here */ - size_t len, /* max amount to read */ - CURLcode *err); /* error to return */ +/* On error return, the value of `pnwritten` has no meaning */ +typedef CURLcode (Curl_send)(struct Curl_easy *data, /* transfer */ + int sockindex, /* socketindex */ + const void *buf, /* data to write */ + size_t len, /* amount to send */ + bool eos, /* last chunk */ + size_t *pnwritten); /* how much sent */ + +/* On error return, the value of `pnread` has no meaning */ +typedef CURLcode (Curl_recv)(struct Curl_easy *data, /* transfer */ + int sockindex, /* socketindex */ + char *buf, /* store data here */ + size_t len, /* max amount to read */ + size_t *pnread); /* how much received */ #include "mime.h" #include "imap.h" @@ -295,7 +295,6 @@ struct ssl_config_data { char *key_type; /* format for private key (default: PEM) */ char *key_passwd; /* plain text private key password */ BIT(certinfo); /* gather lots of certificate info */ - BIT(falsestart); BIT(earlydata); /* use tls1.3 early data */ BIT(enable_beast); /* allow this flaw for interoperability's sake */ BIT(no_revoke); /* disable SSL certificate revocation checks */ @@ -318,7 +317,7 @@ struct ssl_general_config { #ifndef CURL_DISABLE_DIGEST_AUTH /* Struct used for Digest challenge-response authentication */ struct digestdata { -#if defined(USE_WINDOWS_SSPI) +#ifdef USE_WINDOWS_SSPI BYTE *input_token; size_t input_token_len; CtxtHandle *http_context; @@ -357,93 +356,6 @@ typedef enum { GSS_AUTHSUCC } curlnegotiate; -/* Struct used for GSSAPI (Kerberos V5) authentication */ -#if defined(USE_KERBEROS5) -struct kerberos5data { -#if defined(USE_WINDOWS_SSPI) - CredHandle *credentials; - CtxtHandle *context; - TCHAR *spn; - SEC_WINNT_AUTH_IDENTITY identity; - SEC_WINNT_AUTH_IDENTITY *p_identity; - size_t token_max; - BYTE *output_token; -#else - gss_ctx_id_t context; - gss_name_t spn; -#endif -}; -#endif - -/* Struct used for SCRAM-SHA-1 authentication */ -#ifdef USE_GSASL -#include -struct gsasldata { - Gsasl *ctx; - Gsasl_session *client; -}; -#endif - -/* Struct used for NTLM challenge-response authentication */ -#if defined(USE_NTLM) -struct ntlmdata { -#ifdef USE_WINDOWS_SSPI -/* The sslContext is used for the Schannel bindings. The - * api is available on the Windows 7 SDK and later. - */ -#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS - CtxtHandle *sslContext; -#endif - CredHandle *credentials; - CtxtHandle *context; - SEC_WINNT_AUTH_IDENTITY identity; - SEC_WINNT_AUTH_IDENTITY *p_identity; - size_t token_max; - BYTE *output_token; - BYTE *input_token; - size_t input_token_len; - TCHAR *spn; -#else - unsigned int flags; - unsigned char nonce[8]; - unsigned int target_info_len; - void *target_info; /* TargetInfo received in the NTLM type-2 message */ -#endif -}; -#endif - -/* Struct used for Negotiate (SPNEGO) authentication */ -#ifdef USE_SPNEGO -struct negotiatedata { -#ifdef HAVE_GSSAPI - OM_uint32 status; - gss_ctx_id_t context; - gss_name_t spn; - gss_buffer_desc output_token; - struct dynbuf channel_binding_data; -#else -#ifdef USE_WINDOWS_SSPI -#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS - CtxtHandle *sslContext; -#endif - DWORD status; - CredHandle *credentials; - CtxtHandle *context; - SEC_WINNT_AUTH_IDENTITY identity; - SEC_WINNT_AUTH_IDENTITY *p_identity; - TCHAR *spn; - size_t token_max; - BYTE *output_token; - size_t output_token_length; -#endif -#endif - BIT(noauthpersist); - BIT(havenoauthpersist); - BIT(havenegdata); - BIT(havemultiplerequests); -}; -#endif - #ifdef CURL_DISABLE_PROXY #define CONN_IS_PROXIED(x) 0 #else @@ -511,6 +423,7 @@ struct ConnectBits { BIT(parallel_connect); /* set TRUE when a parallel connect attempt has started (happy eyeballs) */ BIT(aborted); /* connection was aborted, e.g. in unclean state */ + BIT(no_reuse); /* connection should not be reused */ BIT(shutdown_handler); /* connection shutdown: handler shut down */ BIT(shutdown_filters); /* connection shutdown: filters shut down */ BIT(in_cpool); /* connection is kept in a connection pool */ @@ -558,15 +471,6 @@ struct hostname { #define FIRSTSOCKET 0 #define SECONDARYSOCKET 1 -/* Polling requested by an easy handle. - * `action` is CURL_POLL_IN, CURL_POLL_OUT or CURL_POLL_INOUT. - */ -struct easy_pollset { - curl_socket_t sockets[MAX_SOCKSPEREASYHANDLE]; - unsigned int num; - unsigned char actions[MAX_SOCKSPEREASYHANDLE]; -}; - /* * Specific protocol handler. */ @@ -603,24 +507,24 @@ struct Curl_handler { /* Called from the multi interface during the PROTOCONNECT phase, and it should then return a proper fd set */ - int (*proto_getsock)(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks); + CURLcode (*proto_pollset)(struct Curl_easy *data, + struct easy_pollset *ps); /* Called from the multi interface during the DOING phase, and it should then return a proper fd set */ - int (*doing_getsock)(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks); + CURLcode (*doing_pollset)(struct Curl_easy *data, + struct easy_pollset *ps); /* Called from the multi interface during the DO_MORE phase, and it should then return a proper fd set */ - int (*domore_getsock)(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks); + CURLcode (*domore_pollset)(struct Curl_easy *data, + struct easy_pollset *ps); /* Called from the multi interface during the DO_DONE, PERFORM and WAITPERFORM phases, and it should then return a proper fd set. Not setting this will make libcurl use the generic default one. */ - int (*perform_getsock)(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks); + CURLcode (*perform_pollset)(struct Curl_easy *data, + struct easy_pollset *ps); /* This function *MAY* be set to a protocol-dependent function that is run * by the curl_disconnect(), as a step in the disconnection. If the handler @@ -713,8 +617,7 @@ struct ip_quadruple { struct proxy_info { struct hostname host; int port; - unsigned char proxytype; /* curl_proxytype: what kind of proxy that is in - use */ + unsigned char proxytype; /* what kind of proxy that is in use */ char *user; /* proxy username string, allocated */ char *passwd; /* proxy password string, allocated */ }; @@ -753,10 +656,6 @@ struct connectdata { * the connection is cleaned up (see Curl_hash_add2()).*/ struct Curl_hash meta_hash; - /* 'remote_addr' is the particular IP we connected to. it is owned, set - * and NULLed by the connected socket filter (if there is one). */ - const struct Curl_sockaddr_ex *remote_addr; - struct hostname host; char *hostname_resolve; /* hostname to resolve to address, allocated */ char *secondaryhostname; /* secondary socket hostname (ftp) */ @@ -766,14 +665,6 @@ struct connectdata { struct proxy_info socks_proxy; struct proxy_info http_proxy; #endif - /* 'primary' and 'secondary' get filled with IP quadruple - (local/remote numerical ip address and port) whenever a connect is - *attempted*. - When more than one address is tried for a connection these will hold data - for the last attempt. When the connection is actually established - these are updated with data which comes directly from the socket. */ - struct ip_quadruple primary; - struct ip_quadruple secondary; char *user; /* username string, allocated */ char *passwd; /* password string, allocated */ char *options; /* options string, allocated */ @@ -781,14 +672,21 @@ struct connectdata { char *oauth_bearer; /* OAUTH2 bearer, allocated */ struct curltime created; /* creation time */ struct curltime lastused; /* when returned to the connection poolas idle */ - curl_socket_t sock[2]; /* two sockets, the second is used for the data - transfer when doing FTP */ + + /* A connection can have one or two sockets and connection filters. + * The protocol using the 2nd one is FTP for CONTROL+DATA sockets */ + curl_socket_t sock[2]; + struct Curl_cfilter *cfilter[2]; /* connection filters */ Curl_recv *recv[2]; Curl_send *send[2]; - struct Curl_cfilter *cfilter[2]; /* connection filters */ + int recv_idx; /* on which socket index to receive, default 0 */ + int send_idx; /* on which socket index to send, default 0 */ + +#define CONN_SOCK_IDX_VALID(i) (((i) >= 0) && ((i) < 2)) + struct { struct curltime start[2]; /* when filter shutdown started */ - unsigned int timeout_ms; /* 0 means no timeout */ + timediff_t timeout_ms; /* 0 means no timeout */ } shutdown; struct ssl_primary_config ssl_config; @@ -807,10 +705,6 @@ struct connectdata { /**** curl_get() phase fields */ - curl_socket_t sockfd; /* socket to read from or CURL_SOCKET_BAD */ - curl_socket_t writesockfd; /* socket to write to, it may be the same we read - from. CURL_SOCKET_BAD disables */ - #ifdef HAVE_GSSAPI BIT(sec_complete); /* if Kerberos is enabled for this connection */ unsigned char command_prot; /* enum protection_level */ @@ -823,10 +717,6 @@ struct connectdata { struct sockaddr_in local_addr; #endif -#if defined(USE_KERBEROS5) /* Consider moving some of the above GSS-API */ - struct kerberos5data krb5; /* variables into the structure definition, */ -#endif /* however, some of them are ftp specific. */ - struct uint_spbset xfers_attached; /* mids of attached transfers */ /* A connection cache from a SHARE might be used in several multi handles. * We MUST not reuse connections that are running in another multi, @@ -838,29 +728,17 @@ struct connectdata { /*************** Request - specific items ************/ #if defined(USE_WINDOWS_SSPI) && defined(SECPKG_ATTR_ENDPOINT_BINDINGS) - CtxtHandle *sslContext; + CtxtHandle *sslContext; /* mingw-w64 v9+. MS SDK 7.0A+. */ #endif -#ifdef USE_GSASL - struct gsasldata gsasl; -#endif - -#if defined(USE_NTLM) +#ifdef USE_NTLM curlntlm http_ntlm_state; curlntlm proxy_ntlm_state; - - struct ntlmdata ntlm; /* NTLM differs from other authentication schemes - because it authenticates connections, not - single requests! */ - struct ntlmdata proxyntlm; /* NTLM data for proxy */ #endif #ifdef USE_SPNEGO curlnegotiate http_negotiate_state; curlnegotiate proxy_negotiate_state; - - struct negotiatedata negotiate; /* state data for host Negotiate auth */ - struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */ #endif #ifdef USE_UNIX_SOCKETS @@ -888,14 +766,12 @@ struct connectdata { unsigned short localport; unsigned short secondary_port; /* secondary socket remote port to connect to (ftp) */ - unsigned char alpn; /* APLN TLS negotiated protocol, a CURL_HTTP_VERSION* - value */ -#ifndef CURL_DISABLE_PROXY - unsigned char proxy_alpn; /* APLN of proxy tunnel, CURL_HTTP_VERSION* */ -#endif - unsigned char transport; /* one of the TRNSPRT_* defines */ + unsigned char transport_wanted; /* one of the TRNSPRT_* defines. Not + necessarily the transport the connection ends using due to Alt-Svc + and happy eyeballing. Use `Curl_conn_get_transport() for actual value + once the connection is set up. */ unsigned char ip_version; /* copied from the Curl_easy at creation time */ - /* HTTP version last responded with by the server. + /* HTTP version last responded with by the server or negotiated via ALPN. * 0 at start, then one of 09, 10, 11, etc. */ unsigned char httpversion_seen; unsigned char connect_only; @@ -1071,7 +947,6 @@ typedef enum { EXPIRE_HAPPY_EYEBALLS_DNS, /* See asyn-ares.c */ EXPIRE_HAPPY_EYEBALLS, EXPIRE_MULTI_PENDING, - EXPIRE_RUN_NOW, EXPIRE_SPEEDCHECK, EXPIRE_TIMEOUT, EXPIRE_TOOFAST, @@ -1158,7 +1033,7 @@ struct UrlState { struct Curl_async async; /* asynchronous name resolver data */ #endif -#if defined(USE_OPENSSL) +#ifdef USE_OPENSSL /* void instead of ENGINE to avoid bleeding OpenSSL into this header */ void *engine; /* void instead of OSSL_PROVIDER */ @@ -1263,9 +1138,6 @@ struct UrlState { #endif unsigned char httpreq; /* Curl_HttpReq; what kind of HTTP request (if any) is this */ - unsigned char select_bits; /* != 0 -> bitmask of socket events for this - transfer overriding anything the socket may - report */ unsigned int creds_from:2; /* where is the server credentials originating from, see the CREDS_* defines above */ @@ -1363,7 +1235,7 @@ enum dupstring { STRING_FTP_ALTERNATIVE_TO_USER, /* command to send if USER/PASS fails */ STRING_FTPPORT, /* port to send with the FTP PORT command */ #endif -#if defined(HAVE_GSSAPI) +#ifdef HAVE_GSSAPI STRING_KRB_LEVEL, /* krb security level */ #endif #ifndef CURL_DISABLE_NETRC @@ -1479,8 +1351,6 @@ struct UserDefined { void *writeheader; /* write the header to this if non-NULL */ unsigned long httpauth; /* kind of HTTP authentication to use (bitmask) */ unsigned long proxyauth; /* kind of proxy authentication to use (bitmask) */ - long maxredirs; /* maximum no. of http(s) redirects to follow, set to -1 - for infinity */ void *postfields; /* if POST, set the fields' values here */ curl_seek_callback seek_func; /* function that seeks the input */ curl_off_t postfieldsize; /* if POST, this might have a size to use instead @@ -1515,13 +1385,10 @@ struct UserDefined { #endif void *progress_client; /* pointer to pass to the progress callback */ void *ioctl_client; /* pointer to pass to the ioctl callback */ - long maxage_conn; /* in seconds, max idle time to allow a connection that + timediff_t conn_max_idle_ms; /* max idle time to allow a connection that is to be reused */ - long maxlifetime_conn; /* in seconds, max time since creation to allow a + timediff_t conn_max_age_ms; /* max time since creation to allow a connection that is to be reused */ -#ifndef CURL_DISABLE_TFTP - long tftp_blksize; /* in bytes, 0 means use default */ -#endif curl_off_t filesize; /* size of file to upload, -1 means unknown */ long low_speed_limit; /* bytes/second */ long low_speed_time; /* number of seconds */ @@ -1549,11 +1416,11 @@ struct UserDefined { unsigned short proxyport; /* If non-zero, use this port number by default. If the proxy string features a ":[port]" that one will override this. */ - unsigned char proxytype; /* what kind of proxy: curl_proxytype */ + unsigned char proxytype; /* what kind of proxy */ unsigned char socks5auth;/* kind of SOCKS5 authentication to use (bitmask) */ #endif struct ssl_general_config general_ssl; /* general user defined SSL stuff */ - int dns_cache_timeout; /* DNS cache timeout (seconds) */ + timediff_t dns_cache_timeout_ms; /* DNS cache timeout (milliseconds) */ unsigned int buffer_size; /* size of receive buffer to use */ unsigned int upload_buffer_size; /* size of upload buffer to use, keep it >= CURL_MAX_WRITE_SIZE */ @@ -1563,7 +1430,7 @@ struct UserDefined { #endif curl_off_t max_filesize; /* Maximum file size to download */ #ifndef CURL_DISABLE_FTP - unsigned int accepttimeout; /* in milliseconds, 0 means no timeout */ + timediff_t accepttimeout; /* in milliseconds, 0 means no timeout */ unsigned char ftp_filemethod; /* how to get to a file: curl_ftpfile */ unsigned char ftpsslauth; /* what AUTH XXX to try: curl_ftpauth */ unsigned char ftp_ccc; /* FTP CCC options: curl_ftpccc */ @@ -1607,16 +1474,15 @@ struct UserDefined { void *wildcardptr; #endif - unsigned int timeout; /* ms, 0 means no timeout */ - unsigned int connecttimeout; /* ms, 0 means default timeout */ - unsigned int happy_eyeballs_timeout; /* ms, 0 is a valid value */ - unsigned int server_response_timeout; /* ms, 0 means no timeout */ - unsigned int shutdowntimeout; /* ms, 0 means default timeout */ + timediff_t timeout; /* ms, 0 means no timeout */ + timediff_t connecttimeout; /* ms, 0 means default timeout */ + timediff_t happy_eyeballs_timeout; /* ms, 0 is a valid value */ + timediff_t server_response_timeout; /* ms, 0 means no timeout */ + timediff_t shutdowntimeout; /* ms, 0 means default timeout */ int tcp_keepidle; /* seconds in idle before sending keepalive probe */ int tcp_keepintvl; /* seconds between TCP keepalive probes */ int tcp_keepcnt; /* maximum number of keepalive probes */ - long expect_100_timeout; /* in milliseconds */ #if defined(USE_HTTP2) || defined(USE_HTTP3) struct Curl_data_priority priority; #endif @@ -1636,6 +1502,9 @@ struct UserDefined { #ifdef USE_ECH int tls_ech; /* TLS ECH configuration */ #endif + short maxredirs; /* maximum no. of http(s) redirects to follow, + set to -1 for infinity */ + unsigned short expect_100_timeout; /* in milliseconds */ unsigned short use_port; /* which port to use (when not using default) */ #ifndef CURL_DISABLE_BINDLOCAL unsigned short localport; /* local port number to bind to */ @@ -1643,6 +1512,9 @@ struct UserDefined { in case the 'localport' one cannot be bind()ed */ #endif +#ifndef CURL_DISABLE_TFTP + unsigned short tftp_blksize; /* in bytes, 0 means use default */ +#endif #ifndef CURL_DISABLE_NETRC unsigned char use_netrc; /* enum CURL_NETRC_OPTION values */ #endif @@ -1728,7 +1600,7 @@ struct UserDefined { location: */ BIT(opt_no_body); /* as set with CURLOPT_NOBODY */ BIT(verbose); /* output verbosity */ -#if defined(HAVE_GSSAPI) +#ifdef HAVE_GSSAPI BIT(krb); /* Kerberos connection requested */ #endif BIT(reuse_forbid); /* forbidden to be reused, close after use */ diff --git a/vendor/curl/lib/vauth/cleartext.c b/vendor/curl/lib/vauth/cleartext.c index 719abd19606..8fc5d41b9a3 100644 --- a/vendor/curl/lib/vauth/cleartext.c +++ b/vendor/curl/lib/vauth/cleartext.c @@ -127,7 +127,7 @@ void Curl_auth_create_login_message(const char *valuep, struct bufref *out) * Returns void. */ void Curl_auth_create_external_message(const char *user, - struct bufref *out) + struct bufref *out) { /* This is the same formatting as the login message */ Curl_auth_create_login_message(user, out); diff --git a/vendor/curl/lib/vauth/digest.c b/vendor/curl/lib/vauth/digest.c index ec4e82256c4..898629a958f 100644 --- a/vendor/curl/lib/vauth/digest.c +++ b/vendor/curl/lib/vauth/digest.c @@ -42,7 +42,6 @@ #include "../vtls/vtls.h" #include "../curlx/warnless.h" #include "../curlx/strparse.h" -#include "../strcase.h" #include "../curl_printf.h" #include "../rand.h" @@ -153,7 +152,7 @@ static void auth_digest_md5_to_ascii(unsigned char *source, /* 16 bytes */ /* Convert sha256 or SHA-512/256 chunk to RFC7616 -suitable ASCII string */ static void auth_digest_sha256_to_ascii(unsigned char *source, /* 32 bytes */ - unsigned char *dest) /* 65 bytes */ + unsigned char *dest) /* 65 bytes */ { int i; for(i = 0; i < 32; i++) @@ -510,31 +509,31 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg, /* Extract a value=content pair */ if(Curl_auth_digest_get_pair(chlg, value, content, &chlg)) { - if(strcasecompare(value, "nonce")) { + if(curl_strequal(value, "nonce")) { free(digest->nonce); digest->nonce = strdup(content); if(!digest->nonce) return CURLE_OUT_OF_MEMORY; } - else if(strcasecompare(value, "stale")) { - if(strcasecompare(content, "true")) { + else if(curl_strequal(value, "stale")) { + if(curl_strequal(content, "true")) { digest->stale = TRUE; digest->nc = 1; /* we make a new nonce now */ } } - else if(strcasecompare(value, "realm")) { + else if(curl_strequal(value, "realm")) { free(digest->realm); digest->realm = strdup(content); if(!digest->realm) return CURLE_OUT_OF_MEMORY; } - else if(strcasecompare(value, "opaque")) { + else if(curl_strequal(value, "opaque")) { free(digest->opaque); digest->opaque = strdup(content); if(!digest->opaque) return CURLE_OUT_OF_MEMORY; } - else if(strcasecompare(value, "qop")) { + else if(curl_strequal(value, "qop")) { const char *token = content; struct Curl_str out; bool foundAuth = FALSE; @@ -568,28 +567,28 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg, return CURLE_OUT_OF_MEMORY; } } - else if(strcasecompare(value, "algorithm")) { + else if(curl_strequal(value, "algorithm")) { free(digest->algorithm); digest->algorithm = strdup(content); if(!digest->algorithm) return CURLE_OUT_OF_MEMORY; - if(strcasecompare(content, "MD5-sess")) + if(curl_strequal(content, "MD5-sess")) digest->algo = ALGO_MD5SESS; - else if(strcasecompare(content, "MD5")) + else if(curl_strequal(content, "MD5")) digest->algo = ALGO_MD5; - else if(strcasecompare(content, "SHA-256")) + else if(curl_strequal(content, "SHA-256")) digest->algo = ALGO_SHA256; - else if(strcasecompare(content, "SHA-256-SESS")) + else if(curl_strequal(content, "SHA-256-SESS")) digest->algo = ALGO_SHA256SESS; - else if(strcasecompare(content, "SHA-512-256")) { + else if(curl_strequal(content, "SHA-512-256")) { #ifdef CURL_HAVE_SHA512_256 digest->algo = ALGO_SHA512_256; #else /* ! CURL_HAVE_SHA512_256 */ return CURLE_NOT_BUILT_IN; #endif /* ! CURL_HAVE_SHA512_256 */ } - else if(strcasecompare(content, "SHA-512-256-SESS")) { + else if(curl_strequal(content, "SHA-512-256-SESS")) { #ifdef CURL_HAVE_SHA512_256 digest->algo = ALGO_SHA512_256SESS; #else /* ! CURL_HAVE_SHA512_256 */ @@ -599,8 +598,8 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg, else return CURLE_BAD_CONTENT_ENCODING; } - else if(strcasecompare(value, "userhash")) { - if(strcasecompare(content, "true")) { + else if(curl_strequal(value, "userhash")) { + if(curl_strequal(content, "true")) { digest->userhash = TRUE; } } @@ -771,7 +770,7 @@ static CURLcode auth_create_digest_http_message( if(!hashthis) return CURLE_OUT_OF_MEMORY; - if(digest->qop && strcasecompare(digest->qop, "auth-int")) { + if(digest->qop && curl_strequal(digest->qop, "auth-int")) { /* We do not support auth-int for PUT or POST */ char hashed[65]; char *hashthis2; diff --git a/vendor/curl/lib/vauth/digest_sspi.c b/vendor/curl/lib/vauth/digest_sspi.c index 2761c599650..c74b8f86539 100644 --- a/vendor/curl/lib/vauth/digest_sspi.c +++ b/vendor/curl/lib/vauth/digest_sspi.c @@ -203,7 +203,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, status == SEC_I_COMPLETE_AND_CONTINUE) Curl_pSecFn->CompleteAuthToken(&credentials, &resp_desc); else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) +#ifndef CURL_DISABLE_VERBOSE_STRINGS char buffer[STRERROR_LEN]; #endif @@ -215,7 +215,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, if(status == SEC_E_INSUFFICIENT_MEMORY) return CURLE_OUT_OF_MEMORY; -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) +#ifndef CURL_DISABLE_VERBOSE_STRINGS infof(data, "schannel: InitializeSecurityContext failed: %s", Curl_sspi_strerror(status, buffer, sizeof(buffer))); #endif @@ -270,7 +270,7 @@ CURLcode Curl_override_sspi_http_realm(const char *chlg, /* Extract a value=content pair */ if(Curl_auth_digest_get_pair(chlg, value, content, &chlg)) { - if(strcasecompare(value, "realm")) { + if(curl_strequal(value, "realm")) { /* Setup identity's domain and length */ domain.tchar_ptr = curlx_convert_UTF8_to_tchar(content); @@ -345,8 +345,8 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg, if(!Curl_auth_digest_get_pair(p, value, content, &p)) break; - if(strcasecompare(value, "stale") && - strcasecompare(content, "true")) { + if(curl_strequal(value, "stale") && + curl_strequal(content, "true")) { stale = TRUE; break; } @@ -411,7 +411,7 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, SecBufferDesc chlg_desc; SECURITY_STATUS status; - (void) data; + (void)data; /* Query the security package for DigestSSP */ status = @@ -602,7 +602,7 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, status == SEC_I_COMPLETE_AND_CONTINUE) Curl_pSecFn->CompleteAuthToken(&credentials, &resp_desc); else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) +#ifndef CURL_DISABLE_VERBOSE_STRINGS char buffer[STRERROR_LEN]; #endif @@ -616,7 +616,7 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, if(status == SEC_E_INSUFFICIENT_MEMORY) return CURLE_OUT_OF_MEMORY; -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) +#ifndef CURL_DISABLE_VERBOSE_STRINGS infof(data, "schannel: InitializeSecurityContext failed: %s", Curl_sspi_strerror(status, buffer, sizeof(buffer))); #endif diff --git a/vendor/curl/lib/vauth/krb5_gssapi.c b/vendor/curl/lib/vauth/krb5_gssapi.c index b5590406175..fd46619d846 100644 --- a/vendor/curl/lib/vauth/krb5_gssapi.c +++ b/vendor/curl/lib/vauth/krb5_gssapi.c @@ -96,14 +96,15 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, OM_uint32 major_status; OM_uint32 minor_status; OM_uint32 unused_status; - gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER; gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; - (void) userp; - (void) passwdp; + (void)userp; + (void)passwdp; if(!krb5->spn) { + gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER; + /* Generate our SPN */ char *spn = Curl_auth_build_spn(service, NULL, host); if(!spn) @@ -315,7 +316,8 @@ void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5) /* Free our security context */ if(krb5->context != GSS_C_NO_CONTEXT) { - gss_delete_sec_context(&minor_status, &krb5->context, GSS_C_NO_BUFFER); + Curl_gss_delete_sec_context(&minor_status, &krb5->context, + GSS_C_NO_BUFFER); krb5->context = GSS_C_NO_CONTEXT; } diff --git a/vendor/curl/lib/vauth/krb5_sspi.c b/vendor/curl/lib/vauth/krb5_sspi.c index a29358569d9..ea26f82750a 100644 --- a/vendor/curl/lib/vauth/krb5_sspi.c +++ b/vendor/curl/lib/vauth/krb5_sspi.c @@ -270,8 +270,8 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, SecPkgContext_Sizes sizes; SECURITY_STATUS status; -#if defined(CURL_DISABLE_VERBOSE_STRINGS) - (void) data; +#ifdef CURL_DISABLE_VERBOSE_STRINGS + (void)data; #endif /* Ensure we have a valid challenge message */ diff --git a/vendor/curl/lib/vauth/ntlm.c b/vendor/curl/lib/vauth/ntlm.c index 5cda790dda3..6164cd388be 100644 --- a/vendor/curl/lib/vauth/ntlm.c +++ b/vendor/curl/lib/vauth/ntlm.c @@ -235,7 +235,7 @@ static void ntlm_print_hex(FILE *handle, const char *buf, size_t len) { const char *p = buf; - (void) handle; + (void)handle; fprintf(stderr, "0x"); while(len-- > 0) @@ -268,8 +268,8 @@ static CURLcode ntlm_decode_type2_target(struct Curl_easy *data, const unsigned char *type2 = Curl_bufref_ptr(type2ref); size_t type2len = Curl_bufref_len(type2ref); -#if defined(CURL_DISABLE_VERBOSE_STRINGS) - (void) data; +#ifdef CURL_DISABLE_VERBOSE_STRINGS + (void)data; #endif if(type2len >= 48) { @@ -368,7 +368,7 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, const unsigned char *type2 = Curl_bufref_ptr(type2ref); size_t type2len = Curl_bufref_len(type2ref); -#if defined(CURL_DISABLE_VERBOSE_STRINGS) +#ifdef CURL_DISABLE_VERBOSE_STRINGS (void)data; #endif diff --git a/vendor/curl/lib/vauth/ntlm_sspi.c b/vendor/curl/lib/vauth/ntlm_sspi.c index 86b4bccfdf4..d45e2db38e1 100644 --- a/vendor/curl/lib/vauth/ntlm_sspi.c +++ b/vendor/curl/lib/vauth/ntlm_sspi.c @@ -205,8 +205,8 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, const struct bufref *type2, struct ntlmdata *ntlm) { -#if defined(CURL_DISABLE_VERBOSE_STRINGS) - (void) data; +#ifdef CURL_DISABLE_VERBOSE_STRINGS + (void)data; #endif /* Ensure we have a valid type-2 message */ @@ -257,11 +257,11 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, unsigned long attrs; TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ -#if defined(CURL_DISABLE_VERBOSE_STRINGS) - (void) data; +#ifdef CURL_DISABLE_VERBOSE_STRINGS + (void)data; #endif - (void) passwdp; - (void) userp; + (void)passwdp; + (void)userp; /* Setup the type-2 "input" security buffer */ type_2_desc.ulVersion = SECBUFFER_VERSION; diff --git a/vendor/curl/lib/vauth/oauth2.c b/vendor/curl/lib/vauth/oauth2.c index 76e77c6a2f4..a84dc60dafd 100644 --- a/vendor/curl/lib/vauth/oauth2.c +++ b/vendor/curl/lib/vauth/oauth2.c @@ -94,8 +94,8 @@ CURLcode Curl_auth_create_oauth_bearer_message(const char *user, * Returns CURLE_OK on success. */ CURLcode Curl_auth_create_xoauth_bearer_message(const char *user, - const char *bearer, - struct bufref *out) + const char *bearer, + struct bufref *out) { /* Generate the message */ char *xoauth = aprintf("user=%s\1auth=Bearer %s\1\1", user, bearer); diff --git a/vendor/curl/lib/vauth/spnego_gssapi.c b/vendor/curl/lib/vauth/spnego_gssapi.c index b17ee46d175..4ed02a398ca 100644 --- a/vendor/curl/lib/vauth/spnego_gssapi.c +++ b/vendor/curl/lib/vauth/spnego_gssapi.c @@ -93,14 +93,13 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, OM_uint32 major_status; OM_uint32 minor_status; OM_uint32 unused_status; - gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER; gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; gss_channel_bindings_t chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; struct gss_channel_bindings_struct chan; - (void) user; - (void) password; + (void)user; + (void)password; if(nego->context && nego->status == GSS_S_COMPLETE) { /* We finished successfully our part of authentication, but server @@ -111,6 +110,8 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, } if(!nego->spn) { + gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER; + /* Generate our SPN */ char *spn = Curl_auth_build_spn(service, NULL, host); if(!spn) @@ -267,7 +268,8 @@ void Curl_auth_cleanup_spnego(struct negotiatedata *nego) /* Free our security context */ if(nego->context != GSS_C_NO_CONTEXT) { - gss_delete_sec_context(&minor_status, &nego->context, GSS_C_NO_BUFFER); + Curl_gss_delete_sec_context(&minor_status, &nego->context, + GSS_C_NO_BUFFER); nego->context = GSS_C_NO_CONTEXT; } @@ -276,7 +278,6 @@ void Curl_auth_cleanup_spnego(struct negotiatedata *nego) gss_release_buffer(&minor_status, &nego->output_token); nego->output_token.value = NULL; nego->output_token.length = 0; - } /* Free the SPN */ diff --git a/vendor/curl/lib/vauth/spnego_sspi.c b/vendor/curl/lib/vauth/spnego_sspi.c index c19a1ff4236..9c481252612 100644 --- a/vendor/curl/lib/vauth/spnego_sspi.c +++ b/vendor/curl/lib/vauth/spnego_sspi.c @@ -107,8 +107,8 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, unsigned long attrs; TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ -#if defined(CURL_DISABLE_VERBOSE_STRINGS) - (void) data; +#ifdef CURL_DISABLE_VERBOSE_STRINGS + (void)data; #endif if(nego->context && nego->status == SEC_E_OK) { diff --git a/vendor/curl/lib/vauth/vauth.c b/vendor/curl/lib/vauth/vauth.c index e2872b2522a..1b44aa6de1a 100644 --- a/vendor/curl/lib/vauth/vauth.c +++ b/vendor/curl/lib/vauth/vauth.c @@ -27,10 +27,11 @@ #include #include "vauth.h" +#include "../strdup.h" #include "../urldata.h" -#include "../strcase.h" #include "../curlx/multibyte.h" #include "../curl_printf.h" +#include "../url.h" /* The last #include files should be: */ #include "../curl_memory.h" @@ -53,7 +54,7 @@ * * Returns a pointer to the newly allocated SPN. */ -#if !defined(USE_WINDOWS_SSPI) +#ifndef USE_WINDOWS_SSPI char *Curl_auth_build_spn(const char *service, const char *host, const char *realm) { @@ -78,7 +79,7 @@ TCHAR *Curl_auth_build_spn(const char *service, const char *host, TCHAR *tchar_spn = NULL; TCHAR *dupe_tchar_spn = NULL; - (void) realm; + (void)realm; /* Note: We could use DsMakeSPN() or DsClientMakeSpnForTargetServer() rather than doing this ourselves but the first is only available in Windows XP @@ -156,7 +157,121 @@ bool Curl_auth_allowed_to_host(struct Curl_easy *data) return !data->state.this_is_a_follow || data->set.allow_auth_to_other_hosts || (data->state.first_host && - strcasecompare(data->state.first_host, conn->host.name) && + curl_strequal(data->state.first_host, conn->host.name) && (data->state.first_remote_port == conn->remote_port) && (data->state.first_remote_protocol == conn->handler->protocol)); } + +#ifdef USE_NTLM + +static void ntlm_conn_dtor(void *key, size_t klen, void *entry) +{ + struct ntlmdata *ntlm = entry; + (void)key; + (void)klen; + DEBUGASSERT(ntlm); + Curl_auth_cleanup_ntlm(ntlm); + free(ntlm); +} + +struct ntlmdata *Curl_auth_ntlm_get(struct connectdata *conn, bool proxy) +{ + const char *key = proxy ? CURL_META_NTLM_PROXY_CONN : + CURL_META_NTLM_CONN; + struct ntlmdata *ntlm = Curl_conn_meta_get(conn, key); + if(!ntlm) { + ntlm = calloc(1, sizeof(*ntlm)); + if(!ntlm || + Curl_conn_meta_set(conn, key, ntlm, ntlm_conn_dtor)) + return NULL; + } + return ntlm; +} + +void Curl_auth_ntlm_remove(struct connectdata *conn, bool proxy) +{ + Curl_conn_meta_remove(conn, proxy ? + CURL_META_NTLM_PROXY_CONN : CURL_META_NTLM_CONN); +} + +#endif /* USE_NTLM */ + +#ifdef USE_KERBEROS5 + +static void krb5_conn_dtor(void *key, size_t klen, void *entry) +{ + struct kerberos5data *krb5 = entry; + (void)key; + (void)klen; + DEBUGASSERT(krb5); + Curl_auth_cleanup_gssapi(krb5); + free(krb5); +} + +struct kerberos5data *Curl_auth_krb5_get(struct connectdata *conn) +{ + struct kerberos5data *krb5 = Curl_conn_meta_get(conn, CURL_META_KRB5_CONN); + if(!krb5) { + krb5 = calloc(1, sizeof(*krb5)); + if(!krb5 || + Curl_conn_meta_set(conn, CURL_META_KRB5_CONN, krb5, krb5_conn_dtor)) + return NULL; + } + return krb5; +} + +#endif /* USE_KERBEROS5 */ + +#ifdef USE_GSASL + +static void gsasl_conn_dtor(void *key, size_t klen, void *entry) +{ + struct gsasldata *gsasl = entry; + (void)key; + (void)klen; + DEBUGASSERT(gsasl); + Curl_auth_gsasl_cleanup(gsasl); + free(gsasl); +} + +struct gsasldata *Curl_auth_gsasl_get(struct connectdata *conn) +{ + struct gsasldata *gsasl = Curl_conn_meta_get(conn, CURL_META_GSASL_CONN); + if(!gsasl) { + gsasl = calloc(1, sizeof(*gsasl)); + if(!gsasl || + Curl_conn_meta_set(conn, CURL_META_GSASL_CONN, gsasl, gsasl_conn_dtor)) + return NULL; + } + return gsasl; +} + +#endif /* USE_GSASL */ + +#ifdef USE_SPNEGO + +static void nego_conn_dtor(void *key, size_t klen, void *entry) +{ + struct negotiatedata *nego = entry; + (void)key; + (void)klen; + DEBUGASSERT(nego); + Curl_auth_cleanup_spnego(nego); + free(nego); +} + +struct negotiatedata *Curl_auth_nego_get(struct connectdata *conn, bool proxy) +{ + const char *key = proxy ? CURL_META_NEGO_PROXY_CONN : + CURL_META_NEGO_CONN; + struct negotiatedata *nego = Curl_conn_meta_get(conn, key); + if(!nego) { + nego = calloc(1, sizeof(*nego)); + if(!nego || + Curl_conn_meta_set(conn, key, nego, nego_conn_dtor)) + return NULL; + } + return nego; +} + +#endif /* USE_SPNEGO */ diff --git a/vendor/curl/lib/vauth/vauth.h b/vendor/curl/lib/vauth/vauth.h index 58b13f582c7..d9e73a0ed12 100644 --- a/vendor/curl/lib/vauth/vauth.h +++ b/vendor/curl/lib/vauth/vauth.h @@ -27,30 +27,29 @@ #include #include "../bufref.h" +#include "../curlx/dynbuf.h" struct Curl_easy; +struct connectdata; -#if !defined(CURL_DISABLE_DIGEST_AUTH) +#ifndef CURL_DISABLE_DIGEST_AUTH struct digestdata; #endif -#if defined(USE_NTLM) +#ifdef USE_NTLM struct ntlmdata; #endif -#if defined(USE_KERBEROS5) -struct kerberos5data; -#endif - #if (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)) && defined(USE_SPNEGO) struct negotiatedata; #endif -#if defined(USE_GSASL) +#ifdef USE_GSASL struct gsasldata; #endif -#if defined(USE_WINDOWS_SSPI) +#ifdef USE_WINDOWS_SSPI +#include "../curl_sspi.h" #define GSS_ERROR(status) ((status) & 0x80000000) #endif @@ -61,7 +60,7 @@ struct gsasldata; bool Curl_auth_allowed_to_host(struct Curl_easy *data); /* This is used to build an SPN string */ -#if !defined(USE_WINDOWS_SSPI) +#ifndef USE_WINDOWS_SSPI char *Curl_auth_build_spn(const char *service, const char *host, const char *realm); #else @@ -117,9 +116,23 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, /* This is used to clean up the digest specific data */ void Curl_auth_digest_cleanup(struct digestdata *digest); +#else +#define Curl_auth_is_digest_supported() FALSE #endif /* !CURL_DISABLE_DIGEST_AUTH */ #ifdef USE_GSASL + +/* meta key for storing GSASL meta at connection */ +#define CURL_META_GSASL_CONN "meta:auth:gsasl:conn" + +#include +struct gsasldata { + Gsasl *ctx; + Gsasl_session *client; +}; + +struct gsasldata *Curl_auth_gsasl_get(struct connectdata *conn); + /* This is used to evaluate if MECH is supported by gsasl */ bool Curl_auth_gsasl_is_supported(struct Curl_easy *data, const char *mech, @@ -140,10 +153,47 @@ CURLcode Curl_auth_gsasl_token(struct Curl_easy *data, void Curl_auth_gsasl_cleanup(struct gsasldata *digest); #endif -#if defined(USE_NTLM) +#ifdef USE_NTLM + +/* meta key for storing NTML meta at connection */ +#define CURL_META_NTLM_CONN "meta:auth:ntml:conn" +/* meta key for storing NTML-PROXY meta at connection */ +#define CURL_META_NTLM_PROXY_CONN "meta:auth:ntml-proxy:conn" + +struct ntlmdata { +#ifdef USE_WINDOWS_SSPI +/* The sslContext is used for the Schannel bindings. The + * api is available on the Windows 7 SDK and later. + */ +#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS + CtxtHandle *sslContext; +#endif + CredHandle *credentials; + CtxtHandle *context; + SEC_WINNT_AUTH_IDENTITY identity; + SEC_WINNT_AUTH_IDENTITY *p_identity; + size_t token_max; + BYTE *output_token; + BYTE *input_token; + size_t input_token_len; + TCHAR *spn; +#else + unsigned int flags; + unsigned char nonce[8]; + unsigned int target_info_len; + void *target_info; /* TargetInfo received in the NTLM type-2 message */ +#endif +}; + /* This is used to evaluate if NTLM is supported */ bool Curl_auth_is_ntlm_supported(void); +struct ntlmdata *Curl_auth_ntlm_get(struct connectdata *conn, bool proxy); +void Curl_auth_ntlm_remove(struct connectdata *conn, bool proxy); + +/* This is used to clean up the NTLM specific data */ +void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm); + /* This is used to generate a base64 encoded NTLM type-1 message */ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, const char *userp, @@ -165,8 +215,6 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, struct ntlmdata *ntlm, struct bufref *out); -/* This is used to clean up the NTLM specific data */ -void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm); #else #define Curl_auth_is_ntlm_supported() FALSE #endif /* USE_NTLM */ @@ -183,7 +231,41 @@ CURLcode Curl_auth_create_xoauth_bearer_message(const char *user, const char *bearer, struct bufref *out); -#if defined(USE_KERBEROS5) +#ifdef USE_KERBEROS5 + +#ifdef HAVE_GSSAPI +# ifdef HAVE_GSSGNU +# include +# elif defined HAVE_GSSAPI_GSSAPI_H +# include +# else +# include +# endif +# ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H +# include +# endif +#endif + +/* meta key for storing KRB5 meta at connection */ +#define CURL_META_KRB5_CONN "meta:auth:krb5:conn" + +struct kerberos5data { +#ifdef USE_WINDOWS_SSPI + CredHandle *credentials; + CtxtHandle *context; + TCHAR *spn; + SEC_WINNT_AUTH_IDENTITY identity; + SEC_WINNT_AUTH_IDENTITY *p_identity; + size_t token_max; + BYTE *output_token; +#else + gss_ctx_id_t context; + gss_name_t spn; +#endif +}; + +struct kerberos5data *Curl_auth_krb5_get(struct connectdata *conn); + /* This is used to evaluate if GSSAPI (Kerberos V5) is supported */ bool Curl_auth_is_gssapi_supported(void); @@ -213,10 +295,48 @@ void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5); #define Curl_auth_is_gssapi_supported() FALSE #endif /* USE_KERBEROS5 */ -#if defined(USE_SPNEGO) -/* This is used to evaluate if SPNEGO (Negotiate) is supported */ +#ifdef USE_SPNEGO + bool Curl_auth_is_spnego_supported(void); +/* meta key for storing NEGO meta at connection */ +#define CURL_META_NEGO_CONN "meta:auth:nego:conn" +/* meta key for storing NEGO PROXY meta at connection */ +#define CURL_META_NEGO_PROXY_CONN "meta:auth:nego-proxy:conn" + +/* Struct used for Negotiate (SPNEGO) authentication */ +struct negotiatedata { +#ifdef HAVE_GSSAPI + OM_uint32 status; + gss_ctx_id_t context; + gss_name_t spn; + gss_buffer_desc output_token; + struct dynbuf channel_binding_data; +#else +#ifdef USE_WINDOWS_SSPI +#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS + CtxtHandle *sslContext; +#endif + DWORD status; + CredHandle *credentials; + CtxtHandle *context; + SEC_WINNT_AUTH_IDENTITY identity; + SEC_WINNT_AUTH_IDENTITY *p_identity; + TCHAR *spn; + size_t token_max; + BYTE *output_token; + size_t output_token_length; +#endif +#endif + BIT(noauthpersist); + BIT(havenoauthpersist); + BIT(havenegdata); + BIT(havemultiplerequests); +}; + +struct negotiatedata * +Curl_auth_nego_get(struct connectdata *conn, bool proxy); + /* This is used to decode a base64 encoded SPNEGO (Negotiate) challenge message */ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, diff --git a/vendor/curl/lib/version.c b/vendor/curl/lib/version.c index bf4c76d016c..aeb133ec73d 100644 --- a/vendor/curl/lib/version.c +++ b/vendor/curl/lib/version.c @@ -197,10 +197,10 @@ char *curl_version(void) #ifdef USE_SSH char ssh_version[30]; #endif -#ifdef USE_NGHTTP2 +#if !defined(CURL_DISABLE_HTTP) && defined(USE_NGHTTP2) char h2_version[30]; #endif -#ifdef USE_HTTP3 +#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP3) char h3_version[30]; #endif #ifdef USE_LIBRTMP @@ -258,11 +258,11 @@ char *curl_version(void) Curl_ssh_version(ssh_version, sizeof(ssh_version)); src[i++] = ssh_version; #endif -#ifdef USE_NGHTTP2 +#if !defined(CURL_DISABLE_HTTP) && defined(USE_NGHTTP2) Curl_http2_ver(h2_version, sizeof(h2_version)); src[i++] = h2_version; #endif -#ifdef USE_HTTP3 +#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP3) Curl_quic_ver(h3_version, sizeof(h3_version)); src[i++] = h3_version; #endif @@ -428,7 +428,7 @@ static int idn_present(curl_version_info_data *info) !defined(CURL_DISABLE_HTTP) static int https_proxy_present(curl_version_info_data *info) { - (void) info; + (void)info; return Curl_ssl_supports(NULL, SSLSUPP_HTTPS_PROXY); } #endif @@ -436,7 +436,7 @@ static int https_proxy_present(curl_version_info_data *info) #if defined(USE_SSL) && defined(USE_ECH) static int ech_present(curl_version_info_data *info) { - (void) info; + (void)info; return Curl_ssl_supports(NULL, SSLSUPP_ECH); } #endif @@ -488,17 +488,17 @@ static const struct feat features_table[] = { #ifndef CURL_DISABLE_HSTS FEATURE("HSTS", NULL, CURL_VERSION_HSTS), #endif -#if defined(USE_NGHTTP2) +#if !defined(CURL_DISABLE_HTTP) && defined(USE_NGHTTP2) FEATURE("HTTP2", NULL, CURL_VERSION_HTTP2), #endif -#if defined(USE_HTTP3) +#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP3) FEATURE("HTTP3", NULL, CURL_VERSION_HTTP3), #endif #if defined(USE_SSL) && !defined(CURL_DISABLE_PROXY) && \ !defined(CURL_DISABLE_HTTP) FEATURE("HTTPS-proxy", https_proxy_present, CURL_VERSION_HTTPS_PROXY), #endif -#if defined(USE_HTTPSRR) +#ifdef USE_HTTPSRR FEATURE("HTTPSRR", NULL, 0), #endif #if defined(USE_LIBIDN2) || defined(USE_WIN32_IDN) || defined(USE_APPLE_IDN) @@ -523,7 +523,7 @@ static const struct feat features_table[] = { #ifdef USE_NTLM FEATURE("NTLM", NULL, CURL_VERSION_NTLM), #endif -#if defined(USE_LIBPSL) +#ifdef USE_LIBPSL FEATURE("PSL", NULL, CURL_VERSION_PSL), #endif #ifdef USE_SPNEGO @@ -532,7 +532,7 @@ static const struct feat features_table[] = { #ifdef USE_SSL FEATURE("SSL", NULL, CURL_VERSION_SSL), #endif -#if defined(USE_SSLS_EXPORT) +#ifdef USE_SSLS_EXPORT FEATURE("SSLS-EXPORT", NULL, 0), #endif #ifdef USE_WINDOWS_SSPI @@ -607,7 +607,7 @@ curl_version_info_data *curl_version_info(CURLversion stamp) const struct feat *p; int features = 0; -#if defined(USE_SSH) +#ifdef USE_SSH static char ssh_buf[80]; /* 'ssh_buffer' clashes with libssh/libssh.h */ #endif #ifdef USE_SSL @@ -648,7 +648,7 @@ curl_version_info_data *curl_version_info(CURLversion stamp) version_info.libidn = idn2_check_version(IDN2_VERSION); #endif -#if defined(USE_SSH) +#ifdef USE_SSH Curl_ssh_version(ssh_buf, sizeof(ssh_buf)); version_info.libssh_version = ssh_buf; #endif @@ -673,7 +673,7 @@ curl_version_info_data *curl_version_info(CURLversion stamp) } #endif -#ifdef USE_HTTP3 +#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP3) { static char quicbuffer[80]; Curl_quic_ver(quicbuffer, sizeof(quicbuffer)); diff --git a/vendor/curl/lib/vquic/curl_ngtcp2.c b/vendor/curl/lib/vquic/curl_ngtcp2.c index f529f7e4fa8..64670251375 100644 --- a/vendor/curl/lib/vquic/curl_ngtcp2.c +++ b/vendor/curl/lib/vquic/curl_ngtcp2.c @@ -24,7 +24,7 @@ #include "../curl_setup.h" -#if defined(USE_NGTCP2) && defined(USE_NGHTTP3) +#if !defined(CURL_DISABLE_HTTP) && defined(USE_NGTCP2) && defined(USE_NGHTTP3) #include #include @@ -47,12 +47,12 @@ #endif #include "../urldata.h" +#include "../url.h" #include "../uint-hash.h" #include "../sendf.h" #include "../strdup.h" #include "../rand.h" #include "../multiif.h" -#include "../strcase.h" #include "../cfilters.h" #include "../cf-socket.h" #include "../connect.h" @@ -155,7 +155,7 @@ struct cf_ngtcp2_ctx { BIT(initialized); BIT(tls_handshake_complete); /* TLS handshake is done */ BIT(use_earlydata); /* Using 0RTT data */ - BIT(earlydata_accepted); /* 0RTT was acceptd by server */ + BIT(earlydata_accepted); /* 0RTT was accepted by server */ BIT(shutdown_started); /* queued shutdown packets */ }; @@ -342,23 +342,6 @@ static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data) } } -static void h3_drain_stream(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - unsigned char bits; - - (void)cf; - bits = CURL_CSELECT_IN; - if(stream && stream->upload_left && !stream->send_closed) - bits |= CURL_CSELECT_OUT; - if(data->state.select_bits != bits) { - data->state.select_bits = bits; - Curl_expire(data, 0, EXPIRE_RUN_NOW); - } -} - /* ngtcp2 default congestion controller does not perform pacing. Limit the maximum packet burst to MAX_PKT_BURST packets. */ #define MAX_PKT_BURST 10 @@ -391,8 +374,8 @@ static void pktx_init(struct pkt_io_ctx *pktx, } static int cb_h3_acked_req_body(nghttp3_conn *conn, int64_t stream_id, - uint64_t datalen, void *user_data, - void *stream_user_data); + uint64_t datalen, void *user_data, + void *stream_user_data); static ngtcp2_conn *get_conn(ngtcp2_crypto_conn_ref *conn_ref) { @@ -485,6 +468,7 @@ static int cf_ngtcp2_handshake_completed(ngtcp2_conn *tconn, void *user_data) ctx->handshake_at = curlx_now(); ctx->tls_handshake_complete = TRUE; cf->conn->bits.multiplex = TRUE; /* at least potentially multiplexed */ + Curl_vquic_report_handshake(&ctx->tls, cf, data); ctx->tls_vrfy_result = Curl_vquic_tls_verify_peer(&ctx->tls, cf, data, &ctx->peer); @@ -744,7 +728,7 @@ static int cb_extend_max_stream_data(ngtcp2_conn *tconn, int64_t stream_id, CURL_TRC_CF(s_data, cf, "[%" FMT_PRId64 "] unblock quic flow", (curl_int64_t)stream_id); stream->quic_flow_blocked = FALSE; - h3_drain_stream(cf, s_data); + Curl_multi_mark_dirty(s_data); } return 0; } @@ -849,6 +833,9 @@ static ngtcp2_callbacks ng_callbacks = { cb_recv_rx_key, NULL, /* recv_tx_key */ NULL, /* early_data_rejected */ +#ifdef NGTCP2_CALLBACKS_V2 + NULL, /* begin_path_validation */ +#endif }; #if defined(_MSC_VER) && defined(_DLL) @@ -911,15 +898,16 @@ static CURLcode check_and_set_expiry(struct Curl_cfilter *cf, return CURLE_OK; } -static void cf_ngtcp2_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) +static CURLcode cf_ngtcp2_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { struct cf_ngtcp2_ctx *ctx = cf->ctx; bool want_recv, want_send; + CURLcode result = CURLE_OK; if(!ctx->qconn) - return; + return CURLE_OK; Curl_pollset_check(data, ps, ctx->q.sockfd, &want_recv, &want_send); if(!want_send && !Curl_bufq_is_empty(&ctx->q.sendbuf)) @@ -939,9 +927,10 @@ static void cf_ngtcp2_adjust_pollset(struct Curl_cfilter *cf, want_send = (!s_exhaust && want_send) || !Curl_bufq_is_empty(&ctx->q.sendbuf); - Curl_pollset_set(data, ps, ctx->q.sockfd, want_recv, want_send); + result = Curl_pollset_set(data, ps, ctx->q.sockfd, want_recv, want_send); CF_DATA_RESTORE(cf, save); } + return result; } static int cb_h3_stream_close(nghttp3_conn *conn, int64_t sid, @@ -971,7 +960,7 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t sid, else { CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] CLOSED", stream->id); } - h3_drain_stream(cf, data); + Curl_multi_mark_dirty(data); return 0; } @@ -1072,7 +1061,7 @@ static int cb_h3_end_headers(nghttp3_conn *conn, int64_t sid, if(stream->status_code / 100 != 1) { stream->resp_hds_complete = TRUE; } - h3_drain_stream(cf, data); + Curl_multi_mark_dirty(data); return 0; } @@ -1198,7 +1187,12 @@ static nghttp3_callbacks ngh3_callbacks = { NULL, /* end_stream */ cb_h3_reset_stream, NULL, /* shutdown */ - NULL /* recv_settings */ + NULL, /* recv_settings */ +#ifdef NGHTTP3_CALLBACKS_V2 + NULL, /* recv_origin */ + NULL, /* end_origin */ + NULL, /* rand */ +#endif }; static CURLcode init_ngh3_conn(struct Curl_cfilter *cf, @@ -1293,14 +1287,14 @@ static ssize_t recv_closed_stream(struct Curl_cfilter *cf, } /* incoming data frames on the h3 stream */ -static ssize_t cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t blen, CURLcode *err) +static CURLcode cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data, + char *buf, size_t blen, size_t *pnread) { struct cf_ngtcp2_ctx *ctx = cf->ctx; struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - ssize_t nread = -1; struct cf_call_data save; struct pkt_io_ctx pktx; + CURLcode result = CURLE_OK; (void)ctx; (void)buf; @@ -1310,7 +1304,7 @@ static ssize_t cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data, DEBUGASSERT(ctx); DEBUGASSERT(ctx->qconn); DEBUGASSERT(ctx->h3conn); - *err = CURLE_OK; + *pnread = 0; /* handshake verification failed in callback, do not recv anything */ if(ctx->tls_vrfy_result) @@ -1319,46 +1313,37 @@ static ssize_t cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data, pktx_init(&pktx, cf, data); if(!stream || ctx->shutdown_started) { - *err = CURLE_RECV_ERROR; + result = CURLE_RECV_ERROR; goto out; } if(cf_progress_ingress(cf, data, &pktx)) { - *err = CURLE_RECV_ERROR; - nread = -1; + result = CURLE_RECV_ERROR; goto out; } if(stream->xfer_result) { CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] xfer write failed", stream->id); cf_ngtcp2_stream_close(cf, data, stream); - *err = stream->xfer_result; - nread = -1; + result = stream->xfer_result; goto out; } else if(stream->closed) { - nread = recv_closed_stream(cf, data, stream, err); + ssize_t nread = recv_closed_stream(cf, data, stream, &result); + if(nread > 0) + *pnread = (size_t)nread; goto out; } - *err = CURLE_AGAIN; - nread = -1; + result = CURLE_AGAIN; out: - if(cf_progress_egress(cf, data, &pktx)) { - *err = CURLE_SEND_ERROR; - nread = -1; - } - else { - CURLcode result2 = check_and_set_expiry(cf, data, &pktx); - if(result2) { - *err = result2; - nread = -1; - } - } - CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_recv(blen=%zu) -> %zd, %d", - stream ? stream->id : -1, blen, nread, *err); + result = Curl_1st_err(result, cf_progress_egress(cf, data, &pktx)); + result = Curl_1st_err(result, check_and_set_expiry(cf, data, &pktx)); + + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_recv(blen=%zu) -> %dm, %zu", + stream ? stream->id : -1, blen, result, *pnread); CF_DATA_RESTORE(cf, save); - return nread; + return result; } static int cb_h3_acked_req_body(nghttp3_conn *conn, int64_t stream_id, @@ -1464,10 +1449,10 @@ cb_h3_read_req_body(nghttp3_conn *conn, int64_t stream_id, field list. */ #define AUTHORITY_DST_IDX 3 -static ssize_t h3_stream_open(struct Curl_cfilter *cf, - struct Curl_easy *data, - const void *buf, size_t len, - CURLcode *err) +static CURLcode h3_stream_open(struct Curl_cfilter *cf, + struct Curl_easy *data, + const void *buf, size_t len, + size_t *pnwritten) { struct cf_ngtcp2_ctx *ctx = cf->ctx; struct h3_stream_ctx *stream = NULL; @@ -1480,41 +1465,43 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf, ssize_t nwritten = -1; nghttp3_data_reader reader; nghttp3_data_reader *preader = NULL; + CURLcode result; + *pnwritten = 0; Curl_dynhds_init(&h2_headers, 0, DYN_HTTP_REQUEST); - *err = h3_data_setup(cf, data); - if(*err) + result = h3_data_setup(cf, data); + if(result) goto out; stream = H3_STREAM_CTX(ctx, data); DEBUGASSERT(stream); if(!stream) { - *err = CURLE_FAILED_INIT; + result = CURLE_FAILED_INIT; goto out; } - nwritten = Curl_h1_req_parse_read(&stream->h1, buf, len, NULL, 0, err); + nwritten = Curl_h1_req_parse_read(&stream->h1, buf, len, NULL, 0, &result); if(nwritten < 0) goto out; + *pnwritten = (size_t)nwritten; + if(!stream->h1.done) { /* need more data */ goto out; } DEBUGASSERT(stream->h1.req); - *err = Curl_http_req_to_h2(&h2_headers, stream->h1.req, data); - if(*err) { - nwritten = -1; + result = Curl_http_req_to_h2(&h2_headers, stream->h1.req, data); + if(result) goto out; - } + /* no longer needed */ Curl_h1_req_parse_free(&stream->h1); nheader = Curl_dynhds_count(&h2_headers); nva = malloc(sizeof(nghttp3_nv) * nheader); if(!nva) { - *err = CURLE_OUT_OF_MEMORY; - nwritten = -1; + result = CURLE_OUT_OF_MEMORY; goto out; } @@ -1530,8 +1517,7 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf, rc = ngtcp2_conn_open_bidi_stream(ctx->qconn, &sid, data); if(rc) { failf(data, "can get bidi streams"); - *err = CURLE_SEND_ERROR; - nwritten = -1; + result = CURLE_SEND_ERROR; goto out; } stream->id = (curl_int64_t)sid; @@ -1574,8 +1560,7 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf, "%d (%s)", stream->id, rc, nghttp3_strerror(rc)); break; } - *err = CURLE_SEND_ERROR; - nwritten = -1; + result = CURLE_SEND_ERROR; goto out; } @@ -1592,26 +1577,25 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf, out: free(nva); Curl_dynhds_free(&h2_headers); - return nwritten; + return result; } -static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, bool eos, - CURLcode *err) +static CURLcode cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data, + const void *buf, size_t len, bool eos, + size_t *pnwritten) { struct cf_ngtcp2_ctx *ctx = cf->ctx; struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - ssize_t sent = -1; struct cf_call_data save; struct pkt_io_ctx pktx; - CURLcode result; + CURLcode result = CURLE_OK; CF_DATA_SAVE(save, cf, data); DEBUGASSERT(cf->connected); DEBUGASSERT(ctx->qconn); DEBUGASSERT(ctx->h3conn); pktx_init(&pktx, cf, data); - *err = CURLE_OK; + *pnwritten = 0; /* handshake verification failed in callback, do not send anything */ if(ctx->tls_vrfy_result) @@ -1619,19 +1603,18 @@ static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data, (void)eos; /* use for stream EOF and block handling */ result = cf_progress_ingress(cf, data, &pktx); - if(result) { - *err = result; - } + if(result) + goto out; if(!stream || stream->id < 0) { if(ctx->shutdown_started) { CURL_TRC_CF(data, cf, "cannot open stream on closed connection"); - *err = CURLE_SEND_ERROR; + result = CURLE_SEND_ERROR; goto out; } - sent = h3_stream_open(cf, data, buf, len, err); - if(sent < 0) { - CURL_TRC_CF(data, cf, "failed to open stream -> %d", *err); + result = h3_stream_open(cf, data, buf, len, pnwritten); + if(result) { + CURL_TRC_CF(data, cf, "failed to open stream -> %d", result); goto out; } stream = H3_STREAM_CTX(ctx, data); @@ -1639,7 +1622,7 @@ static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data, else if(stream->xfer_result) { CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] xfer write failed", stream->id); cf_ngtcp2_stream_close(cf, data, stream); - *err = stream->xfer_result; + result = stream->xfer_result; goto out; } else if(stream->closed) { @@ -1651,52 +1634,43 @@ static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data, * error situation. */ CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] discarding data" "on closed stream with response", stream->id); - *err = CURLE_OK; - sent = (ssize_t)len; + result = CURLE_OK; + *pnwritten = len; goto out; } CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] send_body(len=%zu) " "-> stream closed", stream->id, len); - *err = CURLE_HTTP3; - sent = -1; + result = CURLE_HTTP3; goto out; } else if(ctx->shutdown_started) { CURL_TRC_CF(data, cf, "cannot send on closed connection"); - *err = CURLE_SEND_ERROR; + result = CURLE_SEND_ERROR; goto out; } else { - sent = Curl_bufq_write(&stream->sendbuf, buf, len, err); + result = Curl_bufq_write(&stream->sendbuf, buf, len, pnwritten); CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_send, add to " - "sendbuf(len=%zu) -> %zd, %d", - stream->id, len, sent, *err); - if(sent < 0) { + "sendbuf(len=%zu) -> %d, %zu", + stream->id, len, result, *pnwritten); + if(result) goto out; - } - (void)nghttp3_conn_resume_stream(ctx->h3conn, stream->id); } - if(sent > 0 && !ctx->tls_handshake_complete && ctx->use_earlydata) - ctx->earlydata_skip += sent; + if(*pnwritten > 0 && !ctx->tls_handshake_complete && ctx->use_earlydata) + ctx->earlydata_skip += *pnwritten; + DEBUGASSERT(!result); result = cf_progress_egress(cf, data, &pktx); - if(result) { - *err = result; - sent = -1; - } out: - result = check_and_set_expiry(cf, data, &pktx); - if(result) { - *err = result; - sent = -1; - } - CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_send(len=%zu) -> %zd, %d", - stream ? stream->id : -1, len, sent, *err); + result = Curl_1st_err(result, check_and_set_expiry(cf, data, &pktx)); + + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_send(len=%zu) -> %d, %zu", + stream ? stream->id : -1, len, result, *pnwritten); CF_DATA_RESTORE(cf, save); - return sent; + return result; } static CURLcode recv_pkt(const unsigned char *pkt, size_t pktlen, @@ -1756,9 +1730,9 @@ static CURLcode cf_progress_ingress(struct Curl_cfilter *cf, * Read a network packet to send from ngtcp2 into `buf`. * Return number of bytes written or -1 with *err set. */ -static ssize_t read_pkt_to_send(void *userp, - unsigned char *buf, size_t buflen, - CURLcode *err) +static CURLcode read_pkt_to_send(void *userp, + unsigned char *buf, size_t buflen, + size_t *pnread) { struct pkt_io_ctx *x = userp; struct cf_ngtcp2_ctx *ctx = x->cf->ctx; @@ -1768,7 +1742,9 @@ static ssize_t read_pkt_to_send(void *userp, uint32_t flags; int64_t stream_id; int fin; - ssize_t nwritten = 0, n; + ssize_t n; + + *pnread = 0; veccnt = 0; stream_id = -1; fin = 0; @@ -1780,7 +1756,6 @@ static ssize_t read_pkt_to_send(void *userp, * When ngtcp2 is happy (because it has no other frame that would fit * or it has nothing more to send), it returns the total length * of the assembled packet. This may be 0 if there was nothing to send. */ - *err = CURLE_OK; for(;;) { if(ctx->h3conn && ngtcp2_conn_get_max_data_left(ctx->qconn)) { @@ -1790,8 +1765,7 @@ static ssize_t read_pkt_to_send(void *userp, failf(x->data, "nghttp3_conn_writev_stream returned error: %s", nghttp3_strerror((int)veccnt)); cf_ngtcp2_h3_err_set(x->cf, x->data, (int)veccnt); - *err = CURLE_SEND_ERROR; - return -1; + return CURLE_SEND_ERROR; } } @@ -1803,9 +1777,7 @@ static ssize_t read_pkt_to_send(void *userp, (const ngtcp2_vec *)vec, veccnt, x->ts); if(n == 0) { /* nothing to send */ - *err = CURLE_AGAIN; - nwritten = -1; - goto out; + return CURLE_AGAIN; } else if(n < 0) { switch(n) { @@ -1837,9 +1809,7 @@ static ssize_t read_pkt_to_send(void *userp, failf(x->data, "ngtcp2_conn_writev_stream returned error: %s", ngtcp2_strerror((int)n)); cf_ngtcp2_err_set(x->cf, x->data, (int)n); - *err = CURLE_SEND_ERROR; - nwritten = -1; - goto out; + return CURLE_SEND_ERROR; } } @@ -1855,12 +1825,10 @@ static ssize_t read_pkt_to_send(void *userp, if(n > 0) { /* packet assembled, leave */ - nwritten = n; - goto out; + *pnread = (size_t)n; + return CURLE_OK; } } -out: - return nwritten; } static CURLcode cf_progress_egress(struct Curl_cfilter *cf, @@ -1868,7 +1836,7 @@ static CURLcode cf_progress_egress(struct Curl_cfilter *cf, struct pkt_io_ctx *pktx) { struct cf_ngtcp2_ctx *ctx = cf->ctx; - ssize_t nread; + size_t nread; size_t max_payload_size, path_max_payload_size, max_pktcnt; size_t pktcnt = 0; size_t gsolen = 0; /* this disables gso until we have a clue */ @@ -1893,7 +1861,7 @@ static CURLcode cf_progress_egress(struct Curl_cfilter *cf, return curlcode; } - /* In UDP, there is a maximum theoretical packet paload length and + /* In UDP, there is a maximum theoretical packet payload length and * a minimum payload length that is "guaranteed" to work. * To detect if this minimum payload can be increased, ngtcp2 sends * now and then a packet payload larger than the minimum. It that @@ -1913,9 +1881,9 @@ static CURLcode cf_progress_egress(struct Curl_cfilter *cf, for(;;) { /* add the next packet to send, if any, to our buffer */ - nread = Curl_bufq_sipn(&ctx->q.sendbuf, max_payload_size, - read_pkt_to_send, pktx, &curlcode); - if(nread < 0) { + curlcode = Curl_bufq_sipn(&ctx->q.sendbuf, max_payload_size, + read_pkt_to_send, pktx, &nread); + if(curlcode) { if(curlcode != CURLE_AGAIN) return curlcode; /* Nothing more to add, flush and leave */ @@ -1934,10 +1902,10 @@ static CURLcode cf_progress_egress(struct Curl_cfilter *cf, if(pktcnt == 0) { /* first packet in buffer. This is either of a known, "good" * payload size or it is a PMTUD. We will see. */ - gsolen = (size_t)nread; + gsolen = nread; } - else if((size_t)nread > gsolen || - (gsolen > path_max_payload_size && (size_t)nread != gsolen)) { + else if(nread > gsolen || + (gsolen > path_max_payload_size && nread != gsolen)) { /* The just added packet is a PMTUD *or* the one(s) before the * just added were PMTUD and the last one is smaller. * Flush the buffer before the last add. */ @@ -1954,7 +1922,7 @@ static CURLcode cf_progress_egress(struct Curl_cfilter *cf, continue; } - if(++pktcnt >= max_pktcnt || (size_t)nread < gsolen) { + if(++pktcnt >= max_pktcnt || nread < gsolen) { /* Reached MAX_PKT_BURST *or* * the capacity of our buffer *or* * last add was shorter than the previous ones, flush */ @@ -1975,34 +1943,21 @@ static CURLcode cf_progress_egress(struct Curl_cfilter *cf, return CURLE_OK; } -/* - * Called from transfer.c:data_pending to know if we should keep looping - * to receive more data from the connection. - */ -static bool cf_ngtcp2_data_pending(struct Curl_cfilter *cf, - const struct Curl_easy *data) -{ - (void)cf; - (void)data; - return FALSE; -} - static CURLcode h3_data_pause(struct Curl_cfilter *cf, struct Curl_easy *data, bool pause) { /* There seems to exist no API in ngtcp2 to shrink/enlarge the streams * windows. As we do in HTTP/2. */ - if(!pause) { - h3_drain_stream(cf, data); - Curl_expire(data, 0, EXPIRE_RUN_NOW); - } + (void)cf; + if(!pause) + Curl_multi_mark_dirty(data); return CURLE_OK; } -static CURLcode cf_ngtcp2_data_event(struct Curl_cfilter *cf, - struct Curl_easy *data, - int event, int arg1, void *arg2) +static CURLcode cf_ngtcp2_cntrl(struct Curl_cfilter *cf, + struct Curl_easy *data, + int event, int arg1, void *arg2) { struct cf_ngtcp2_ctx *ctx = cf->ctx; CURLcode result = CURLE_OK; @@ -2040,6 +1995,10 @@ static CURLcode cf_ngtcp2_data_event(struct Curl_cfilter *cf, } break; } + case CF_CTRL_CONN_INFO_UPDATE: + if(!cf->sockindex && cf->connected) + cf->conn->httpversion_seen = 30; + break; default: break; } @@ -2129,8 +2088,9 @@ static CURLcode cf_ngtcp2_shutdown(struct Curl_cfilter *cf, /* Ignore amount written. sendbuf was empty and has always room for * NGTCP2_MAX_UDP_PAYLOAD_SIZE. It can only completely fail, in which * case `result` is set non zero. */ - (void)Curl_bufq_write(&ctx->q.sendbuf, (const unsigned char *)buffer, - (size_t)nwritten, &result); + size_t n; + result = Curl_bufq_write(&ctx->q.sendbuf, (const unsigned char *)buffer, + (size_t)nwritten, &n); if(result) { CURL_TRC_CF(data, cf, "error %d adding shutdown packets to sendbuf, " "aborting shutdown", result); @@ -2589,7 +2549,6 @@ static CURLcode cf_ngtcp2_connect(struct Curl_cfilter *cf, if(result) goto out; if(cf->connected) { - cf->conn->alpn = CURL_HTTP_VERSION_3; *done = TRUE; goto out; } @@ -2611,7 +2570,6 @@ static CURLcode cf_ngtcp2_connect(struct Curl_cfilter *cf, if(!result) { CURL_TRC_CF(data, cf, "peer verified"); cf->connected = TRUE; - cf->conn->alpn = CURL_HTTP_VERSION_3; *done = TRUE; connkeep(cf->conn, "HTTP/3 default"); } @@ -2702,6 +2660,20 @@ static CURLcode cf_ngtcp2_query(struct Curl_cfilter *cf, case CF_QUERY_HTTP_VERSION: *pres1 = 30; return CURLE_OK; + case CF_QUERY_SSL_INFO: + case CF_QUERY_SSL_CTX_INFO: { + struct curl_tlssessioninfo *info = pres2; + if(Curl_vquic_tls_get_ssl_info(&ctx->tls, + (query == CF_QUERY_SSL_CTX_INFO), info)) + return CURLE_OK; + break; + } + case CF_QUERY_ALPN_NEGOTIATED: { + const char **palpn = pres2; + DEBUGASSERT(palpn); + *palpn = cf->connected ? "h3" : NULL; + return CURLE_OK; + } default: break; } @@ -2761,12 +2733,11 @@ struct Curl_cftype Curl_cft_http3 = { cf_ngtcp2_connect, cf_ngtcp2_close, cf_ngtcp2_shutdown, - Curl_cf_def_get_host, cf_ngtcp2_adjust_pollset, - cf_ngtcp2_data_pending, + Curl_cf_def_data_pending, cf_ngtcp2_send, cf_ngtcp2_recv, - cf_ngtcp2_data_event, + cf_ngtcp2_cntrl, cf_ngtcp2_conn_is_alive, Curl_cf_def_conn_keep_alive, cf_ngtcp2_query, diff --git a/vendor/curl/lib/vquic/curl_ngtcp2.h b/vendor/curl/lib/vquic/curl_ngtcp2.h index 884662523f6..86753a3a6ba 100644 --- a/vendor/curl/lib/vquic/curl_ngtcp2.h +++ b/vendor/curl/lib/vquic/curl_ngtcp2.h @@ -26,7 +26,7 @@ #include "../curl_setup.h" -#if defined(USE_NGTCP2) && defined(USE_NGHTTP3) +#if !defined(CURL_DISABLE_HTTP) && defined(USE_NGTCP2) && defined(USE_NGHTTP3) #ifdef HAVE_NETINET_UDP_H #include @@ -52,9 +52,9 @@ struct Curl_cfilter; void Curl_ngtcp2_ver(char *p, size_t len); CURLcode Curl_cf_ngtcp2_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn, - const struct Curl_addrinfo *ai); + struct Curl_easy *data, + struct connectdata *conn, + const struct Curl_addrinfo *ai); bool Curl_conn_is_ngtcp2(const struct Curl_easy *data, const struct connectdata *conn, diff --git a/vendor/curl/lib/vquic/curl_osslq.c b/vendor/curl/lib/vquic/curl_osslq.c index d5af10b06b2..fa2c0a2899e 100644 --- a/vendor/curl/lib/vquic/curl_osslq.c +++ b/vendor/curl/lib/vquic/curl_osslq.c @@ -24,7 +24,8 @@ #include "../curl_setup.h" -#if defined(USE_OPENSSL_QUIC) && defined(USE_NGHTTP3) +#if !defined(CURL_DISABLE_HTTP) && defined(USE_OPENSSL_QUIC) && \ + defined(USE_NGHTTP3) #include #include @@ -37,7 +38,6 @@ #include "../strdup.h" #include "../rand.h" #include "../multiif.h" -#include "../strcase.h" #include "../cfilters.h" #include "../cf-socket.h" #include "../connect.h" @@ -55,6 +55,7 @@ #include "../vtls/vtls.h" #include "../vtls/openssl.h" #include "curl_osslq.h" +#include "../url.h" #include "../curlx/warnless.h" /* The last 3 #include files should be in this order */ @@ -118,15 +119,15 @@ static const char *osslq_SSL_ERROR_to_str(int err) return "SSL_ERROR_WANT_CONNECT"; case SSL_ERROR_WANT_ACCEPT: return "SSL_ERROR_WANT_ACCEPT"; -#if defined(SSL_ERROR_WANT_ASYNC) +#ifdef SSL_ERROR_WANT_ASYNC case SSL_ERROR_WANT_ASYNC: return "SSL_ERROR_WANT_ASYNC"; #endif -#if defined(SSL_ERROR_WANT_ASYNC_JOB) +#ifdef SSL_ERROR_WANT_ASYNC_JOB case SSL_ERROR_WANT_ASYNC_JOB: return "SSL_ERROR_WANT_ASYNC_JOB"; #endif -#if defined(SSL_ERROR_WANT_EARLY) +#ifdef SSL_ERROR_WANT_EARLY case SSL_ERROR_WANT_EARLY: return "SSL_ERROR_WANT_EARLY"; #endif @@ -159,11 +160,11 @@ static char *osslq_strerror(unsigned long error, char *buf, size_t size) static CURLcode make_bio_addr(BIO_ADDR **pbio_addr, const struct Curl_sockaddr_ex *addr) { - BIO_ADDR *ba; + BIO_ADDR *bio_addr; CURLcode result = CURLE_FAILED_INIT; - ba = BIO_ADDR_new(); - if(!ba) { + bio_addr = BIO_ADDR_new(); + if(!bio_addr) { result = CURLE_OUT_OF_MEMORY; goto out; } @@ -172,7 +173,7 @@ static CURLcode make_bio_addr(BIO_ADDR **pbio_addr, case AF_INET: { struct sockaddr_in * const sin = (struct sockaddr_in * const)CURL_UNCONST(&addr->curl_sa_addr); - if(!BIO_ADDR_rawmake(ba, AF_INET, &sin->sin_addr, + if(!BIO_ADDR_rawmake(bio_addr, AF_INET, &sin->sin_addr, sizeof(sin->sin_addr), sin->sin_port)) { goto out; } @@ -183,7 +184,7 @@ static CURLcode make_bio_addr(BIO_ADDR **pbio_addr, case AF_INET6: { struct sockaddr_in6 * const sin = (struct sockaddr_in6 * const)CURL_UNCONST(&addr->curl_sa_addr); - if(!BIO_ADDR_rawmake(ba, AF_INET6, &sin->sin6_addr, + if(!BIO_ADDR_rawmake(bio_addr, AF_INET6, &sin->sin6_addr, sizeof(sin->sin6_addr), sin->sin6_port)) { } result = CURLE_OK; @@ -197,11 +198,11 @@ static CURLcode make_bio_addr(BIO_ADDR **pbio_addr, } out: - if(result && ba) { - BIO_ADDR_free(ba); - ba = NULL; + if(result && bio_addr) { + BIO_ADDR_free(bio_addr); + bio_addr = NULL; } - *pbio_addr = ba; + *pbio_addr = bio_addr; return result; } @@ -513,7 +514,7 @@ static CURLcode cf_osslq_ssl_err(struct Curl_cfilter *cf, else err_descr = "SSL certificate verification failed"; } -#if defined(SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED) +#ifdef SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED /* SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED is only available on OpenSSL version above v1.1.1, not LibreSSL, BoringSSL, or AWS-LC */ else if((lib == ERR_LIB_SSL) && @@ -560,7 +561,7 @@ static CURLcode cf_osslq_ssl_err(struct Curl_cfilter *cf, } static CURLcode cf_osslq_verify_peer(struct Curl_cfilter *cf, - struct Curl_easy *data) + struct Curl_easy *data) { struct cf_osslq_ctx *ctx = cf->ctx; @@ -711,31 +712,14 @@ static struct cf_osslq_stream *cf_osslq_get_qstream(struct Curl_cfilter *cf, return NULL; } -static void h3_drain_stream(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_osslq_ctx *ctx = cf->ctx; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - unsigned char bits; - - (void)cf; - bits = CURL_CSELECT_IN; - if(stream && stream->upload_left && !stream->send_closed) - bits |= CURL_CSELECT_OUT; - if(data->state.select_bits != bits) { - data->state.select_bits = bits; - Curl_expire(data, 0, EXPIRE_RUN_NOW); - } -} - static CURLcode h3_data_pause(struct Curl_cfilter *cf, struct Curl_easy *data, bool pause) { + (void)cf; if(!pause) { /* unpaused. make it run again right away */ - h3_drain_stream(cf, data); - Curl_expire(data, 0, EXPIRE_RUN_NOW); + Curl_multi_mark_dirty(data); } return CURLE_OK; } @@ -766,7 +750,7 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id, else { CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] CLOSED", stream->s.id); } - h3_drain_stream(cf, data); + Curl_multi_mark_dirty(data); return 0; } @@ -783,21 +767,20 @@ static CURLcode write_resp_raw(struct Curl_cfilter *cf, struct cf_osslq_ctx *ctx = cf->ctx; struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); CURLcode result = CURLE_OK; - ssize_t nwritten; + size_t nwritten; (void)cf; if(!stream) { return CURLE_RECV_ERROR; } - nwritten = Curl_bufq_write(&stream->recvbuf, mem, memlen, &result); - if(nwritten < 0) { + result = Curl_bufq_write(&stream->recvbuf, mem, memlen, &nwritten); + if(result) return result; - } if(!flow) stream->recv_buf_nonflow += (size_t)nwritten; - if((size_t)nwritten < memlen) { + if(nwritten < memlen) { /* This MUST not happen. Our recbuf is dimensioned to hold the * full max_stream_window and then some for this very reason. */ DEBUGASSERT(0); @@ -831,7 +814,7 @@ static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream3_id, stream->download_recvd += (curl_off_t)buflen; CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] DATA len=%zu, total=%" FMT_OFF_T, stream->s.id, buflen, stream->download_recvd); - h3_drain_stream(cf, data); + Curl_multi_mark_dirty(data); return 0; } @@ -943,7 +926,7 @@ static int cb_h3_end_headers(nghttp3_conn *conn, int64_t sid, if(stream->status_code / 100 != 1) { stream->resp_hds_complete = TRUE; } - h3_drain_stream(cf, data); + Curl_multi_mark_dirty(data); return 0; } @@ -1104,7 +1087,12 @@ static nghttp3_callbacks ngh3_callbacks = { NULL, /* end_stream */ cb_h3_reset_stream, NULL, /* shutdown */ - NULL /* recv_settings */ + NULL, /* recv_settings */ +#ifdef NGHTTP3_CALLBACKS_V2 + NULL, /* recv_origin */ + NULL, /* end_origin */ + NULL, /* rand */ +#endif }; static CURLcode cf_osslq_h3conn_init(struct cf_osslq_ctx *ctx, SSL *conn, @@ -1259,27 +1247,24 @@ struct h3_quic_recv_ctx { struct cf_osslq_stream *s; }; -static ssize_t h3_quic_recv(void *reader_ctx, - unsigned char *buf, size_t len, - CURLcode *err) +static CURLcode h3_quic_recv(void *reader_ctx, + unsigned char *buf, size_t len, + size_t *pnread) { struct h3_quic_recv_ctx *x = reader_ctx; - size_t nread; int rv; - *err = CURLE_OK; - rv = SSL_read_ex(x->s->ssl, buf, len, &nread); + rv = SSL_read_ex(x->s->ssl, buf, len, pnread); if(rv <= 0) { int detail = SSL_get_error(x->s->ssl, rv); if(detail == SSL_ERROR_WANT_READ || detail == SSL_ERROR_WANT_WRITE) { - *err = CURLE_AGAIN; - return -1; + return CURLE_AGAIN; } else if(detail == SSL_ERROR_ZERO_RETURN) { CURL_TRC_CF(x->data, x->cf, "[%" FMT_PRId64 "] h3_quic_recv -> EOS", x->s->id); x->s->recvd_eos = TRUE; - return 0; + return CURLE_OK; } else if(SSL_get_stream_read_state(x->s->ssl) == SSL_STREAM_STATE_RESET_REMOTE) { @@ -1292,14 +1277,13 @@ static ssize_t h3_quic_recv(void *reader_ctx, x->s->reset = TRUE; } x->s->recvd_eos = TRUE; - return 0; + return CURLE_OK; } else { - *err = cf_osslq_ssl_err(x->cf, x->data, detail, CURLE_RECV_ERROR); - return -1; + return cf_osslq_ssl_err(x->cf, x->data, detail, CURLE_RECV_ERROR); } } - return (ssize_t)nread; + return CURLE_OK; } static CURLcode cf_osslq_stream_recv(struct cf_osslq_stream *s, @@ -1309,6 +1293,7 @@ static CURLcode cf_osslq_stream_recv(struct cf_osslq_stream *s, struct cf_osslq_ctx *ctx = cf->ctx; CURLcode result = CURLE_OK; ssize_t nread; + size_t n; struct h3_quic_recv_ctx x; bool eagain = FALSE; size_t total_recv_len = 0; @@ -1324,8 +1309,8 @@ static CURLcode cf_osslq_stream_recv(struct cf_osslq_stream *s, (total_recv_len < H3_STREAM_CHUNK_SIZE)) { if(Curl_bufq_is_empty(&s->recvbuf) && !s->recvd_eos) { while(!eagain && !s->recvd_eos && !Curl_bufq_is_full(&s->recvbuf)) { - nread = Curl_bufq_sipn(&s->recvbuf, 0, h3_quic_recv, &x, &result); - if(nread < 0) { + result = Curl_bufq_sipn(&s->recvbuf, 0, h3_quic_recv, &x, &n); + if(result) { if(result != CURLE_AGAIN) goto out; result = CURLE_OK; @@ -1566,7 +1551,7 @@ static CURLcode cf_osslq_check_and_unblock(struct Curl_cfilter *cf, if(stream) { nghttp3_conn_unblock_stream(ctx->h3.conn, stream->s.id); stream->s.send_blocked = FALSE; - h3_drain_stream(cf, ctx->curl_items[idx_count]); + Curl_multi_mark_dirty(ctx->curl_items[idx_count]); CURL_TRC_CF(ctx->curl_items[idx_count], cf, "unblocked"); } result_count--; @@ -1817,7 +1802,6 @@ static CURLcode cf_osslq_connect(struct Curl_cfilter *cf, if(!result) { CURL_TRC_CF(data, cf, "peer verified"); cf->connected = TRUE; - cf->conn->alpn = CURL_HTTP_VERSION_3; *done = TRUE; connkeep(cf->conn, "HTTP/3 default"); } @@ -2009,44 +1993,39 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf, return nwritten; } -static ssize_t cf_osslq_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, bool eos, - CURLcode *err) +static CURLcode cf_osslq_send(struct Curl_cfilter *cf, struct Curl_easy *data, + const void *buf, size_t len, bool eos, + size_t *pnwritten) { struct cf_osslq_ctx *ctx = cf->ctx; struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); struct cf_call_data save; ssize_t nwritten; - CURLcode result; + CURLcode result = CURLE_OK; (void)eos; /* use to end stream */ CF_DATA_SAVE(save, cf, data); DEBUGASSERT(cf->connected); DEBUGASSERT(ctx->tls.ossl.ssl); DEBUGASSERT(ctx->h3.conn); - *err = CURLE_OK; + *pnwritten = 0; result = cf_progress_ingress(cf, data); - if(result) { - *err = result; - nwritten = -1; + if(result) goto out; - } result = cf_progress_egress(cf, data); - if(result) { - *err = result; - nwritten = -1; + if(result) goto out; - } if(!stream || stream->s.id < 0) { - nwritten = h3_stream_open(cf, data, buf, len, err); + nwritten = h3_stream_open(cf, data, buf, len, &result); if(nwritten < 0) { - CURL_TRC_CF(data, cf, "failed to open stream -> %d", *err); + CURL_TRC_CF(data, cf, "failed to open stream -> %d", result); goto out; } stream = H3_STREAM_CTX(ctx, data); + *pnwritten = (size_t)nwritten; } else if(stream->closed) { if(stream->resp_hds_complete) { @@ -2057,56 +2036,48 @@ static ssize_t cf_osslq_send(struct Curl_cfilter *cf, struct Curl_easy *data, * error situation. */ CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] discarding data" "on closed stream with response", stream->s.id); - *err = CURLE_OK; - nwritten = (ssize_t)len; + result = CURLE_OK; + *pnwritten = len; goto out; } CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] send_body(len=%zu) " "-> stream closed", stream->s.id, len); - *err = CURLE_HTTP3; - nwritten = -1; + result = CURLE_HTTP3; goto out; } else { - nwritten = Curl_bufq_write(&stream->sendbuf, buf, len, err); + result = Curl_bufq_write(&stream->sendbuf, buf, len, pnwritten); CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_send, add to " - "sendbuf(len=%zu) -> %zd, %d", - stream->s.id, len, nwritten, *err); - if(nwritten < 0) { + "sendbuf(len=%zu) -> %d, %zu", + stream->s.id, len, result, *pnwritten); + if(result) goto out; - } - (void)nghttp3_conn_resume_stream(ctx->h3.conn, stream->s.id); } - result = cf_progress_egress(cf, data); - if(result) { - *err = result; - nwritten = -1; - } + result = Curl_1st_err(result, cf_progress_egress(cf, data)); out: - result = check_and_set_expiry(cf, data); - CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_send(len=%zu) -> %zd, %d", - stream ? stream->s.id : -1, len, nwritten, *err); + result = Curl_1st_err(result, check_and_set_expiry(cf, data)); + + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_send(len=%zu) -> %d, %zu", + stream ? stream->s.id : -1, len, result, *pnwritten); CF_DATA_RESTORE(cf, save); - return nwritten; + return result; } -static ssize_t recv_closed_stream(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h3_stream_ctx *stream, - CURLcode *err) +static CURLcode recv_closed_stream(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct h3_stream_ctx *stream, + size_t *pnread) { - ssize_t nread = -1; - (void)cf; + *pnread = 0; if(stream->reset) { failf(data, "HTTP/3 stream %" FMT_PRId64 " reset by server", stream->s.id); - *err = data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP3; - goto out; + return data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP3; } else if(!stream->resp_hds_complete) { failf(data, @@ -2114,24 +2085,18 @@ static ssize_t recv_closed_stream(struct Curl_cfilter *cf, " was closed cleanly, but before getting" " all response header fields, treated as error", stream->s.id); - *err = CURLE_HTTP3; - goto out; + return CURLE_HTTP3; } - *err = CURLE_OK; - nread = 0; - -out: - return nread; + return CURLE_OK; } -static ssize_t cf_osslq_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t len, CURLcode *err) +static CURLcode cf_osslq_recv(struct Curl_cfilter *cf, struct Curl_easy *data, + char *buf, size_t len, size_t *pnread) { struct cf_osslq_ctx *ctx = cf->ctx; struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - ssize_t nread = -1; struct cf_call_data save; - CURLcode result; + CURLcode result = CURLE_OK; (void)ctx; CF_DATA_SAVE(save, cf, data); @@ -2139,69 +2104,55 @@ static ssize_t cf_osslq_recv(struct Curl_cfilter *cf, struct Curl_easy *data, DEBUGASSERT(ctx); DEBUGASSERT(ctx->tls.ossl.ssl); DEBUGASSERT(ctx->h3.conn); - *err = CURLE_OK; + *pnread = 0; if(!stream) { - *err = CURLE_RECV_ERROR; + result = CURLE_RECV_ERROR; goto out; } if(!Curl_bufq_is_empty(&stream->recvbuf)) { - nread = Curl_bufq_read(&stream->recvbuf, - (unsigned char *)buf, len, err); - if(nread < 0) { + result = Curl_bufq_cread(&stream->recvbuf, buf, len, pnread); + if(result) { CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] read recvbuf(len=%zu) " - "-> %zd, %d", stream->s.id, len, nread, *err); + "-> %d, %zu", stream->s.id, len, result, *pnread); goto out; } } - result = cf_progress_ingress(cf, data); - if(result) { - *err = result; - nread = -1; + result = Curl_1st_err(result, cf_progress_ingress(cf, data)); + if(result) goto out; - } /* recvbuf had nothing before, maybe after progressing ingress? */ - if(nread < 0 && !Curl_bufq_is_empty(&stream->recvbuf)) { - nread = Curl_bufq_read(&stream->recvbuf, - (unsigned char *)buf, len, err); - if(nread < 0) { + if(!*pnread && !Curl_bufq_is_empty(&stream->recvbuf)) { + result = Curl_bufq_cread(&stream->recvbuf, buf, len, pnread); + if(result) { CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] read recvbuf(len=%zu) " - "-> %zd, %d", stream->s.id, len, nread, *err); + "-> %d, %zu", stream->s.id, len, result, *pnread); goto out; } } - if(nread > 0) { - h3_drain_stream(cf, data); + if(*pnread) { + Curl_multi_mark_dirty(data); } else { if(stream->closed) { - nread = recv_closed_stream(cf, data, stream, err); + result = recv_closed_stream(cf, data, stream, pnread); goto out; } - *err = CURLE_AGAIN; - nread = -1; + result = CURLE_AGAIN; } out: - if(cf_progress_egress(cf, data)) { - *err = CURLE_SEND_ERROR; - nread = -1; - } - else { - CURLcode result2 = check_and_set_expiry(cf, data); - if(result2) { - *err = result2; - nread = -1; - } - } - CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_recv(len=%zu) -> %zd, %d", - stream ? stream->s.id : -1, len, nread, *err); + result = Curl_1st_err(result, cf_progress_egress(cf, data)); + result = Curl_1st_err(result, check_and_set_expiry(cf, data)); + + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_recv(len=%zu) -> %d, %zu", + stream ? stream->s.id : -1, len, result, *pnread); CF_DATA_RESTORE(cf, save); - return nread; + return result; } /* @@ -2217,9 +2168,9 @@ static bool cf_osslq_data_pending(struct Curl_cfilter *cf, return stream && !Curl_bufq_is_empty(&stream->recvbuf); } -static CURLcode cf_osslq_data_event(struct Curl_cfilter *cf, - struct Curl_easy *data, - int event, int arg1, void *arg2) +static CURLcode cf_osslq_cntrl(struct Curl_cfilter *cf, + struct Curl_easy *data, + int event, int arg1, void *arg2) { struct cf_osslq_ctx *ctx = cf->ctx; CURLcode result = CURLE_OK; @@ -2255,6 +2206,10 @@ static CURLcode cf_osslq_data_event(struct Curl_cfilter *cf, } break; } + case CF_CTRL_CONN_INFO_UPDATE: + if(!cf->sockindex && cf->connected) + cf->conn->httpversion_seen = 30; + break; default: break; } @@ -2315,11 +2270,12 @@ static bool cf_osslq_conn_is_alive(struct Curl_cfilter *cf, return alive; } -static void cf_osslq_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) +static CURLcode cf_osslq_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { struct cf_osslq_ctx *ctx = cf->ctx; + CURLcode result = CURLE_OK; if(!ctx->tls.ossl.ssl) { /* NOP */ @@ -2327,9 +2283,9 @@ static void cf_osslq_adjust_pollset(struct Curl_cfilter *cf, else if(!cf->connected) { /* during handshake, transfer has not started yet. we always * add our socket for polling if SSL wants to send/recv */ - Curl_pollset_set(data, ps, ctx->q.sockfd, - SSL_net_read_desired(ctx->tls.ossl.ssl), - SSL_net_write_desired(ctx->tls.ossl.ssl)); + result = Curl_pollset_set(data, ps, ctx->q.sockfd, + SSL_net_read_desired(ctx->tls.ossl.ssl), + SSL_net_write_desired(ctx->tls.ossl.ssl)); } else { /* once connected, we only modify the socket if it is present. @@ -2337,15 +2293,16 @@ static void cf_osslq_adjust_pollset(struct Curl_cfilter *cf, bool want_recv, want_send; Curl_pollset_check(data, ps, ctx->q.sockfd, &want_recv, &want_send); if(want_recv || want_send) { - Curl_pollset_set(data, ps, ctx->q.sockfd, - SSL_net_read_desired(ctx->tls.ossl.ssl), - SSL_net_write_desired(ctx->tls.ossl.ssl)); + result = Curl_pollset_set(data, ps, ctx->q.sockfd, + SSL_net_read_desired(ctx->tls.ossl.ssl), + SSL_net_write_desired(ctx->tls.ossl.ssl)); } else if(ctx->need_recv || ctx->need_send) { - Curl_pollset_set(data, ps, ctx->q.sockfd, - ctx->need_recv, ctx->need_send); + result = Curl_pollset_set(data, ps, ctx->q.sockfd, + ctx->need_recv, ctx->need_send); } } + return result; } static CURLcode cf_osslq_query(struct Curl_cfilter *cf, @@ -2358,8 +2315,9 @@ static CURLcode cf_osslq_query(struct Curl_cfilter *cf, case CF_QUERY_MAX_CONCURRENT: { #ifdef SSL_VALUE_QUIC_STREAM_BIDI_LOCAL_AVAIL /* Added in OpenSSL v3.3.x */ - uint64_t v; - if(!SSL_get_value_uint(ctx->tls.ossl.ssl, SSL_VALUE_CLASS_GENERIC, + uint64_t v = 0; + if(ctx->tls.ossl.ssl && + !SSL_get_value_uint(ctx->tls.ossl.ssl, SSL_VALUE_CLASS_GENERIC, SSL_VALUE_QUIC_STREAM_BIDI_LOCAL_AVAIL, &v)) { CURL_TRC_CF(data, cf, "error getting available local bidi streams"); return CURLE_HTTP3; @@ -2396,6 +2354,20 @@ static CURLcode cf_osslq_query(struct Curl_cfilter *cf, case CF_QUERY_HTTP_VERSION: *pres1 = 30; return CURLE_OK; + case CF_QUERY_SSL_INFO: + case CF_QUERY_SSL_CTX_INFO: { + struct curl_tlssessioninfo *info = pres2; + if(Curl_vquic_tls_get_ssl_info(&ctx->tls, + (query == CF_QUERY_SSL_CTX_INFO), info)) + return CURLE_OK; + break; + } + case CF_QUERY_ALPN_NEGOTIATED: { + const char **palpn = pres2; + DEBUGASSERT(palpn); + *palpn = cf->connected ? "h3" : NULL; + return CURLE_OK; + } default: break; } @@ -2412,12 +2384,11 @@ struct Curl_cftype Curl_cft_http3 = { cf_osslq_connect, cf_osslq_close, cf_osslq_shutdown, - Curl_cf_def_get_host, cf_osslq_adjust_pollset, cf_osslq_data_pending, cf_osslq_send, cf_osslq_recv, - cf_osslq_data_event, + cf_osslq_cntrl, cf_osslq_conn_is_alive, Curl_cf_def_conn_keep_alive, cf_osslq_query, @@ -2489,4 +2460,4 @@ void Curl_osslq_ver(char *p, size_t len) (void)msnprintf(p, len, "nghttp3/%s", ht3->version_str); } -#endif /* USE_OPENSSL_QUIC && USE_NGHTTP3 */ +#endif /* !CURL_DISABLE_HTTP && USE_OPENSSL_QUIC && USE_NGHTTP3 */ diff --git a/vendor/curl/lib/vquic/curl_osslq.h b/vendor/curl/lib/vquic/curl_osslq.h index a2809c92bcc..9f5025f8aeb 100644 --- a/vendor/curl/lib/vquic/curl_osslq.h +++ b/vendor/curl/lib/vquic/curl_osslq.h @@ -26,7 +26,8 @@ #include "../curl_setup.h" -#if defined(USE_OPENSSL_QUIC) && defined(USE_NGHTTP3) +#if !defined(CURL_DISABLE_HTTP) && defined(USE_OPENSSL_QUIC) && \ + defined(USE_NGHTTP3) #ifdef HAVE_NETINET_UDP_H #include diff --git a/vendor/curl/lib/vquic/curl_quiche.c b/vendor/curl/lib/vquic/curl_quiche.c index 88065328896..179ccf8aa1a 100644 --- a/vendor/curl/lib/vquic/curl_quiche.c +++ b/vendor/curl/lib/vquic/curl_quiche.c @@ -24,7 +24,7 @@ #include "../curl_setup.h" -#ifdef USE_QUICHE +#if !defined(CURL_DISABLE_HTTP) && defined(USE_QUICHE) #include #include #include @@ -36,17 +36,18 @@ #include "../sendf.h" #include "../strdup.h" #include "../rand.h" -#include "../strcase.h" #include "../multiif.h" #include "../connect.h" #include "../progress.h" #include "../strerror.h" +#include "../select.h" #include "../http1.h" #include "vquic.h" #include "vquic_int.h" #include "vquic-tls.h" #include "curl_quiche.h" #include "../transfer.h" +#include "../url.h" #include "../curlx/inet_pton.h" #include "../vtls/openssl.h" #include "../vtls/keylog.h" @@ -237,7 +238,7 @@ static bool cf_quiche_do_resume(struct Curl_cfilter *cf, (void)user_data; if(stream->quic_flow_blocked) { stream->quic_flow_blocked = FALSE; - Curl_expire(sdata, 0, EXPIRE_RUN_NOW); + Curl_multi_mark_dirty(sdata); CURL_TRC_CF(sdata, cf, "[%"FMT_PRIu64"] unblock", stream->id); } return TRUE; @@ -250,8 +251,8 @@ static bool cf_quiche_do_expire(struct Curl_cfilter *cf, { (void)stream; (void)user_data; - CURL_TRC_CF(sdata, cf, "conn closed, expire transfer"); - Curl_expire(sdata, 0, EXPIRE_RUN_NOW); + CURL_TRC_CF(sdata, cf, "conn closed, mark as dirty"); + Curl_multi_mark_dirty(sdata); return TRUE; } @@ -307,23 +308,6 @@ static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data) } } -static void h3_drain_stream(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - unsigned char bits; - - (void)cf; - bits = CURL_CSELECT_IN; - if(stream && !stream->send_closed) - bits |= CURL_CSELECT_OUT; - if(data->state.select_bits != bits) { - data->state.select_bits = bits; - Curl_expire(data, 0, EXPIRE_RUN_NOW); - } -} - static void cf_quiche_expire_conn_closed(struct Curl_cfilter *cf, struct Curl_easy *data) { @@ -344,16 +328,16 @@ static CURLcode write_resp_raw(struct Curl_cfilter *cf, struct cf_quiche_ctx *ctx = cf->ctx; struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); CURLcode result = CURLE_OK; - ssize_t nwritten; + size_t nwritten; (void)cf; if(!stream) return CURLE_RECV_ERROR; - nwritten = Curl_bufq_write(&stream->recvbuf, mem, memlen, &result); - if(nwritten < 0) + result = Curl_bufq_write(&stream->recvbuf, mem, memlen, &nwritten); + if(result) return result; - if((size_t)nwritten < memlen) { + if(nwritten < memlen) { /* This MUST not happen. Our recbuf is dimensioned to hold the * full max_stream_window and then some for this very reason. */ DEBUGASSERT(0); @@ -407,30 +391,26 @@ static int cb_each_header(uint8_t *name, size_t name_len, return result; } -static ssize_t stream_resp_read(void *reader_ctx, - unsigned char *buf, size_t len, - CURLcode *err) +static CURLcode stream_resp_read(void *reader_ctx, + unsigned char *buf, size_t len, + size_t *pnread) { struct cb_ctx *x = reader_ctx; struct cf_quiche_ctx *ctx = x->cf->ctx; struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, x->data); ssize_t nread; - if(!stream) { - *err = CURLE_RECV_ERROR; - return -1; - } + *pnread = 0; + if(!stream) + return CURLE_RECV_ERROR; - nread = quiche_h3_recv_body(ctx->h3c, ctx->qconn, stream->id, - buf, len); + nread = quiche_h3_recv_body(ctx->h3c, ctx->qconn, stream->id, buf, len); if(nread >= 0) { - *err = CURLE_OK; - return nread; - } - else { - *err = CURLE_AGAIN; - return -1; + *pnread = (size_t)nread; + return CURLE_OK; } + else + return CURLE_AGAIN; } static CURLcode cf_recv_body(struct Curl_cfilter *cf, @@ -438,7 +418,7 @@ static CURLcode cf_recv_body(struct Curl_cfilter *cf, { struct cf_quiche_ctx *ctx = cf->ctx; struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - ssize_t nwritten; + size_t nread; struct cb_ctx cb_ctx; CURLcode result = CURLE_OK; @@ -454,12 +434,12 @@ static CURLcode cf_recv_body(struct Curl_cfilter *cf, cb_ctx.cf = cf; cb_ctx.data = data; - nwritten = Curl_bufq_slurp(&stream->recvbuf, - stream_resp_read, &cb_ctx, &result); + result = Curl_bufq_slurp(&stream->recvbuf, + stream_resp_read, &cb_ctx, &nread); - if(nwritten < 0 && result != CURLE_AGAIN) { - CURL_TRC_CF(data, cf, "[%"FMT_PRIu64"] recv_body error %zd", - stream->id, nwritten); + if(result && result != CURLE_AGAIN) { + CURL_TRC_CF(data, cf, "[%"FMT_PRIu64"] recv_body error %zu", + stream->id, nread); failf(data, "Error %d in HTTP/3 response body for stream[%"FMT_PRIu64"]", result, stream->id); stream->closed = TRUE; @@ -562,7 +542,7 @@ static CURLcode cf_quiche_ev_process(struct Curl_cfilter *cf, quiche_h3_event *ev) { CURLcode result = h3_process_event(cf, data, stream, ev); - h3_drain_stream(cf, data); + Curl_multi_mark_dirty(data); if(result) CURL_TRC_CF(data, cf, "error processing event %s " "for [%"FMT_PRIu64"] -> %d", cf_ev_name(ev), @@ -731,27 +711,25 @@ struct read_ctx { quiche_send_info send_info; }; -static ssize_t read_pkt_to_send(void *userp, - unsigned char *buf, size_t buflen, - CURLcode *err) +static CURLcode read_pkt_to_send(void *userp, + unsigned char *buf, size_t buflen, + size_t *pnread) { struct read_ctx *x = userp; struct cf_quiche_ctx *ctx = x->cf->ctx; - ssize_t nwritten; + ssize_t n; - nwritten = quiche_conn_send(ctx->qconn, buf, buflen, &x->send_info); - if(nwritten == QUICHE_ERR_DONE) { - *err = CURLE_AGAIN; - return -1; - } + *pnread = 0; + n = quiche_conn_send(ctx->qconn, buf, buflen, &x->send_info); + if(n == QUICHE_ERR_DONE) + return CURLE_AGAIN; - if(nwritten < 0) { - failf(x->data, "quiche_conn_send returned %zd", nwritten); - *err = CURLE_SEND_ERROR; - return -1; + if(n < 0) { + failf(x->data, "quiche_conn_send returned %zd", n); + return CURLE_SEND_ERROR; } - *err = CURLE_OK; - return nwritten; + *pnread = (size_t)n; + return CURLE_OK; } /* @@ -762,7 +740,7 @@ static CURLcode cf_flush_egress(struct Curl_cfilter *cf, struct Curl_easy *data) { struct cf_quiche_ctx *ctx = cf->ctx; - ssize_t nread; + size_t nread; CURLcode result; curl_int64_t expiry_ns; curl_int64_t timeout_ns; @@ -800,9 +778,9 @@ static CURLcode cf_flush_egress(struct Curl_cfilter *cf, gsolen = quiche_conn_max_send_udp_payload_size(ctx->qconn); for(;;) { /* add the next packet to send, if any, to our buffer */ - nread = Curl_bufq_sipn(&ctx->q.sendbuf, 0, - read_pkt_to_send, &readx, &result); - if(nread < 0) { + result = Curl_bufq_sipn(&ctx->q.sendbuf, 0, + read_pkt_to_send, &readx, &nread); + if(result) { if(result != CURLE_AGAIN) return result; /* Nothing more to add, flush and leave */ @@ -818,7 +796,7 @@ static CURLcode cf_flush_egress(struct Curl_cfilter *cf, } ++pkt_count; - if((size_t)nread < gsolen || pkt_count >= MAX_PKT_BURST) { + if(nread < gsolen || pkt_count >= MAX_PKT_BURST) { result = vquic_send(cf, data, &ctx->q, gsolen); if(result) { if(result == CURLE_AGAIN) { @@ -840,123 +818,105 @@ static CURLcode cf_flush_egress(struct Curl_cfilter *cf, return result; } -static ssize_t recv_closed_stream(struct Curl_cfilter *cf, - struct Curl_easy *data, - CURLcode *err) +static CURLcode recv_closed_stream(struct Curl_cfilter *cf, + struct Curl_easy *data, + size_t *pnread) { struct cf_quiche_ctx *ctx = cf->ctx; struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - ssize_t nread = -1; + CURLcode result = CURLE_OK; DEBUGASSERT(stream); + *pnread = 0; if(stream->reset) { failf(data, "HTTP/3 stream %" FMT_PRIu64 " reset by server", stream->id); - *err = data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP3; + result = data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP3; CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] cf_recv, was reset -> %d", - stream->id, *err); + stream->id, result); } else if(!stream->resp_got_header) { failf(data, "HTTP/3 stream %" FMT_PRIu64 " was closed cleanly, but before " "getting all response header fields, treated as error", stream->id); - /* *err = CURLE_PARTIAL_FILE; */ - *err = CURLE_HTTP3; - CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] cf_recv, closed incomplete" - " -> %d", stream->id, *err); - } - else { - *err = CURLE_OK; - nread = 0; + result = CURLE_HTTP3; } - return nread; + return result; } -static ssize_t cf_quiche_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t len, CURLcode *err) +static CURLcode cf_quiche_recv(struct Curl_cfilter *cf, struct Curl_easy *data, + char *buf, size_t len, size_t *pnread) { struct cf_quiche_ctx *ctx = cf->ctx; struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - ssize_t nread = -1; - CURLcode result; + CURLcode result = CURLE_OK; + *pnread = 0; vquic_ctx_update_time(&ctx->q); - if(!stream) { - *err = CURLE_RECV_ERROR; - return -1; - } + if(!stream) + return CURLE_RECV_ERROR; + if(!Curl_bufq_is_empty(&stream->recvbuf)) { - nread = Curl_bufq_read(&stream->recvbuf, - (unsigned char *)buf, len, err); + result = Curl_bufq_cread(&stream->recvbuf, buf, len, pnread); CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] read recvbuf(len=%zu) " - "-> %zd, %d", stream->id, len, nread, *err); - if(nread < 0) + "-> %d, %zu", stream->id, len, result, *pnread); + if(result) goto out; } if(cf_process_ingress(cf, data)) { CURL_TRC_CF(data, cf, "cf_recv, error on ingress"); - *err = CURLE_RECV_ERROR; - nread = -1; + result = CURLE_RECV_ERROR; goto out; } /* recvbuf had nothing before, maybe after progressing ingress? */ - if(nread < 0 && !Curl_bufq_is_empty(&stream->recvbuf)) { - nread = Curl_bufq_read(&stream->recvbuf, - (unsigned char *)buf, len, err); + if(!*pnread && !Curl_bufq_is_empty(&stream->recvbuf)) { + result = Curl_bufq_cread(&stream->recvbuf, buf, len, pnread); CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] read recvbuf(len=%zu) " - "-> %zd, %d", stream->id, len, nread, *err); - if(nread < 0) + "-> %d, %zu", stream->id, len, result, *pnread); + if(result) goto out; } - if(nread > 0) { + if(*pnread) { if(stream->closed) - h3_drain_stream(cf, data); + Curl_multi_mark_dirty(data); } else { - if(stream->closed) { - nread = recv_closed_stream(cf, data, err); - goto out; - } + if(stream->closed) + result = recv_closed_stream(cf, data, pnread); else if(quiche_conn_is_draining(ctx->qconn)) { failf(data, "QUIC connection is draining"); - *err = CURLE_HTTP3; - nread = -1; - goto out; + result = CURLE_HTTP3; } - *err = CURLE_AGAIN; - nread = -1; + else + result = CURLE_AGAIN; } out: - result = cf_flush_egress(cf, data); - if(result) { - CURL_TRC_CF(data, cf, "cf_recv, flush egress failed"); - *err = result; - nread = -1; - } - if(nread > 0) - ctx->data_recvd += nread; + result = Curl_1st_err(result, cf_flush_egress(cf, data)); + if(*pnread > 0) + ctx->data_recvd += *pnread; CURL_TRC_CF(data, cf, "[%"FMT_PRIu64"] cf_recv(total=%" - FMT_OFF_T ") -> %zd, %d", - stream->id, ctx->data_recvd, nread, *err); - return nread; + FMT_OFF_T ") -> %d, %zu", + stream->id, ctx->data_recvd, result, *pnread); + return result; } -static ssize_t cf_quiche_send_body(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h3_stream_ctx *stream, - const void *buf, size_t len, bool eos, - CURLcode *err) +static CURLcode cf_quiche_send_body(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct h3_stream_ctx *stream, + const void *buf, size_t len, bool eos, + size_t *pnwritten) { struct cf_quiche_ctx *ctx = cf->ctx; ssize_t nwritten; + *pnwritten = 0; nwritten = quiche_h3_send_body(ctx->h3c, ctx->qconn, stream->id, (uint8_t *)CURL_UNCONST(buf), len, eos); if(nwritten == QUICHE_H3_ERR_DONE || (nwritten == 0 && len > 0)) { @@ -967,26 +927,22 @@ static ssize_t cf_quiche_send_body(struct Curl_cfilter *cf, "-> window exhausted", stream->id, len); stream->quic_flow_blocked = TRUE; } - *err = CURLE_AGAIN; - return -1; + return CURLE_AGAIN; } else if(nwritten == QUICHE_H3_TRANSPORT_ERR_INVALID_STREAM_STATE) { CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] send_body(len=%zu) " "-> invalid stream state", stream->id, len); - *err = CURLE_HTTP3; - return -1; + return CURLE_HTTP3; } else if(nwritten == QUICHE_H3_TRANSPORT_ERR_FINAL_SIZE) { CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] send_body(len=%zu) " "-> exceeds size", stream->id, len); - *err = CURLE_SEND_ERROR; - return -1; + return CURLE_SEND_ERROR; } else if(nwritten < 0) { CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] send_body(len=%zu) " "-> quiche err %zd", stream->id, len, nwritten); - *err = CURLE_SEND_ERROR; - return -1; + return CURLE_SEND_ERROR; } else { if(eos && (len == (size_t)nwritten)) @@ -994,8 +950,8 @@ static ssize_t cf_quiche_send_body(struct Curl_cfilter *cf, CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] send body(len=%zu, " "eos=%d) -> %zd", stream->id, len, stream->send_closed, nwritten); - *err = CURLE_OK; - return nwritten; + *pnwritten = (size_t)nwritten; + return CURLE_OK; } } @@ -1003,10 +959,10 @@ static ssize_t cf_quiche_send_body(struct Curl_cfilter *cf, field list. */ #define AUTHORITY_DST_IDX 3 -static ssize_t h3_open_stream(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *buf, size_t len, bool eos, - CURLcode *err) +static CURLcode h3_open_stream(struct Curl_cfilter *cf, + struct Curl_easy *data, + const char *buf, size_t blen, bool eos, + size_t *pnwritten) { struct cf_quiche_ctx *ctx = cf->ctx; struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); @@ -1014,13 +970,14 @@ static ssize_t h3_open_stream(struct Curl_cfilter *cf, curl_int64_t stream3_id; struct dynhds h2_headers; quiche_h3_header *nva = NULL; + CURLcode result = CURLE_OK; ssize_t nwritten; + *pnwritten = 0; if(!stream) { - *err = h3_data_setup(cf, data); - if(*err) { - return -1; - } + result = h3_data_setup(cf, data); + if(result) + return result; stream = H3_STREAM_CTX(ctx, data); DEBUGASSERT(stream); } @@ -1028,7 +985,7 @@ static ssize_t h3_open_stream(struct Curl_cfilter *cf, Curl_dynhds_init(&h2_headers, 0, DYN_HTTP_REQUEST); DEBUGASSERT(stream); - nwritten = Curl_h1_req_parse_read(&stream->h1, buf, len, NULL, 0, err); + nwritten = Curl_h1_req_parse_read(&stream->h1, buf, blen, NULL, 0, &result); if(nwritten < 0) goto out; if(!stream->h1.done) { @@ -1037,19 +994,17 @@ static ssize_t h3_open_stream(struct Curl_cfilter *cf, } DEBUGASSERT(stream->h1.req); - *err = Curl_http_req_to_h2(&h2_headers, stream->h1.req, data); - if(*err) { - nwritten = -1; + result = Curl_http_req_to_h2(&h2_headers, stream->h1.req, data); + if(result) goto out; - } + /* no longer needed */ Curl_h1_req_parse_free(&stream->h1); nheader = Curl_dynhds_count(&h2_headers); nva = malloc(sizeof(quiche_h3_header) * nheader); if(!nva) { - *err = CURLE_OUT_OF_MEMORY; - nwritten = -1; + result = CURLE_OUT_OF_MEMORY; goto out; } @@ -1061,32 +1016,34 @@ static ssize_t h3_open_stream(struct Curl_cfilter *cf, nva[i].value_len = e->valuelen; } - if(eos && ((size_t)nwritten == len)) + *pnwritten = (size_t)nwritten; + buf += *pnwritten; + blen -= *pnwritten; + + if(eos && !blen) stream->send_closed = TRUE; stream3_id = quiche_h3_send_request(ctx->h3c, ctx->qconn, nva, nheader, stream->send_closed); + CURL_TRC_CF(data, cf, "quiche_send_request() -> %" FMT_PRIu64, stream3_id); if(stream3_id < 0) { if(QUICHE_H3_ERR_STREAM_BLOCKED == stream3_id) { /* quiche seems to report this error if the connection window is * exhausted. Which happens frequently and intermittent. */ CURL_TRC_CF(data, cf, "[%"FMT_PRIu64"] blocked", stream->id); stream->quic_flow_blocked = TRUE; - *err = CURLE_AGAIN; - nwritten = -1; + result = CURLE_AGAIN; goto out; } else { CURL_TRC_CF(data, cf, "send_request(%s) -> %" FMT_PRIu64, data->state.url, stream3_id); } - *err = CURLE_SEND_ERROR; - nwritten = -1; + result = CURLE_SEND_ERROR; goto out; } DEBUGASSERT(!stream->opened); - *err = CURLE_OK; stream->id = stream3_id; stream->opened = TRUE; stream->closed = FALSE; @@ -1102,48 +1059,43 @@ static ssize_t h3_open_stream(struct Curl_cfilter *cf, } } - if(nwritten > 0 && ((size_t)nwritten < len)) { - /* after the headers, there was request BODY data */ - size_t hds_len = (size_t)nwritten; - ssize_t bwritten; + if(blen) { /* after the headers, there was request BODY data */ + size_t bwritten; + CURLcode r2 = CURLE_OK; - bwritten = cf_quiche_send_body(cf, data, stream, - buf + hds_len, len - hds_len, eos, err); - if((bwritten < 0) && (CURLE_AGAIN != *err)) { - /* real error, fail */ - nwritten = -1; + r2 = cf_quiche_send_body(cf, data, stream, buf, blen, eos, &bwritten); + if(r2 && (CURLE_AGAIN != r2)) { /* real error, fail */ + result = r2; } else if(bwritten > 0) { - nwritten += bwritten; + *pnwritten += (size_t)bwritten; } } out: free(nva); Curl_dynhds_free(&h2_headers); - return nwritten; + return result; } -static ssize_t cf_quiche_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, bool eos, - CURLcode *err) +static CURLcode cf_quiche_send(struct Curl_cfilter *cf, struct Curl_easy *data, + const void *buf, size_t len, bool eos, + size_t *pnwritten) { struct cf_quiche_ctx *ctx = cf->ctx; struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); CURLcode result; - ssize_t nwritten; + *pnwritten = 0; vquic_ctx_update_time(&ctx->q); - *err = cf_process_ingress(cf, data); - if(*err) { - nwritten = -1; + result = cf_process_ingress(cf, data); + if(result) goto out; - } if(!stream || !stream->opened) { - nwritten = h3_open_stream(cf, data, buf, len, eos, err); - if(nwritten < 0) + result = h3_open_stream(cf, data, buf, len, eos, pnwritten); + if(result) goto out; stream = H3_STREAM_CTX(ctx, data); } @@ -1159,29 +1111,26 @@ static ssize_t cf_quiche_send(struct Curl_cfilter *cf, struct Curl_easy *data, * it would see the response and stop/discard sending on its own- */ CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] discarding data" "on closed stream with response", stream->id); - *err = CURLE_OK; - nwritten = (ssize_t)len; + result = CURLE_OK; + *pnwritten = len; goto out; } CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] send_body(len=%zu) " "-> stream closed", stream->id, len); - *err = CURLE_HTTP3; - nwritten = -1; + result = CURLE_HTTP3; goto out; } else { - nwritten = cf_quiche_send_body(cf, data, stream, buf, len, eos, err); + result = cf_quiche_send_body(cf, data, stream, buf, len, eos, pnwritten); } out: - result = cf_flush_egress(cf, data); - if(result) { - *err = result; - nwritten = -1; - } - CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] cf_send(len=%zu) -> %zd, %d", - stream ? stream->id : (curl_uint64_t)~0, len, nwritten, *err); - return nwritten; + result = Curl_1st_err(result, cf_flush_egress(cf, data)); + + CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] cf_send(len=%zu) -> %d, %zu", + stream ? stream->id : (curl_uint64_t)~0, len, + result, *pnwritten); + return result; } static bool stream_is_writeable(struct Curl_cfilter *cf, @@ -1194,15 +1143,16 @@ static bool stream_is_writeable(struct Curl_cfilter *cf, ctx->qconn, (curl_uint64_t)stream->id, 1) > 0); } -static void cf_quiche_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) +static CURLcode cf_quiche_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { struct cf_quiche_ctx *ctx = cf->ctx; bool want_recv, want_send; + CURLcode result = CURLE_OK; if(!ctx->qconn) - return; + return CURLE_OK; Curl_pollset_check(data, ps, ctx->q.sockfd, &want_recv, &want_send); if(want_recv || want_send) { @@ -1217,8 +1167,9 @@ static void cf_quiche_adjust_pollset(struct Curl_cfilter *cf, want_send = (!s_exhaust && want_send) || !Curl_bufq_is_empty(&ctx->q.sendbuf); - Curl_pollset_set(data, ps, ctx->q.sockfd, want_recv, want_send); + result = Curl_pollset_set(data, ps, ctx->q.sockfd, want_recv, want_send); } + return result; } /* @@ -1240,16 +1191,16 @@ static CURLcode h3_data_pause(struct Curl_cfilter *cf, { /* There seems to exist no API in quiche to shrink/enlarge the streams * windows. As we do in HTTP/2. */ + (void)cf; if(!pause) { - h3_drain_stream(cf, data); - Curl_expire(data, 0, EXPIRE_RUN_NOW); + Curl_multi_mark_dirty(data); } return CURLE_OK; } -static CURLcode cf_quiche_data_event(struct Curl_cfilter *cf, - struct Curl_easy *data, - int event, int arg1, void *arg2) +static CURLcode cf_quiche_cntrl(struct Curl_cfilter *cf, + struct Curl_easy *data, + int event, int arg1, void *arg2) { struct cf_quiche_ctx *ctx = cf->ctx; CURLcode result = CURLE_OK; @@ -1269,13 +1220,13 @@ static CURLcode cf_quiche_data_event(struct Curl_cfilter *cf, struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); if(stream && !stream->send_closed) { unsigned char body[1]; - ssize_t sent; + size_t sent; stream->send_closed = TRUE; body[0] = 'X'; - sent = cf_quiche_send(cf, data, body, 0, TRUE, &result); - CURL_TRC_CF(data, cf, "[%"FMT_PRIu64"] DONE_SEND -> %zd, %d", - stream->id, sent, result); + result = cf_quiche_send(cf, data, body, 0, TRUE, &sent); + CURL_TRC_CF(data, cf, "[%"FMT_PRIu64"] DONE_SEND -> %d, %zu", + stream->id, result, sent); } break; } @@ -1288,6 +1239,10 @@ static CURLcode cf_quiche_data_event(struct Curl_cfilter *cf, } break; } + case CF_CTRL_CONN_INFO_UPDATE: + if(!cf->sockindex && cf->connected) + cf->conn->httpversion_seen = 30; + break; default: break; } @@ -1469,7 +1424,6 @@ static CURLcode cf_quiche_connect(struct Curl_cfilter *cf, goto out; } cf->connected = TRUE; - cf->conn->alpn = CURL_HTTP_VERSION_3; *done = TRUE; connkeep(cf->conn, "HTTP/3 default"); } @@ -1569,7 +1523,7 @@ static CURLcode cf_quiche_query(struct Curl_cfilter *cf, switch(query) { case CF_QUERY_MAX_CONCURRENT: { curl_uint64_t max_streams = CONN_ATTACHED(cf->conn); - if(!ctx->goaway) { + if(!ctx->goaway && ctx->qconn) { max_streams += quiche_conn_peer_streams_left_bidi(ctx->qconn); } *pres1 = (max_streams > INT_MAX) ? INT_MAX : (int)max_streams; @@ -1601,6 +1555,20 @@ static CURLcode cf_quiche_query(struct Curl_cfilter *cf, case CF_QUERY_HTTP_VERSION: *pres1 = 30; return CURLE_OK; + case CF_QUERY_SSL_INFO: + case CF_QUERY_SSL_CTX_INFO: { + struct curl_tlssessioninfo *info = pres2; + if(Curl_vquic_tls_get_ssl_info(&ctx->tls, + (query == CF_QUERY_SSL_CTX_INFO), info)) + return CURLE_OK; + break; + } + case CF_QUERY_ALPN_NEGOTIATED: { + const char **palpn = pres2; + DEBUGASSERT(palpn); + *palpn = cf->connected ? "h3" : NULL; + return CURLE_OK; + } default: break; } @@ -1654,12 +1622,11 @@ struct Curl_cftype Curl_cft_http3 = { cf_quiche_connect, cf_quiche_close, cf_quiche_shutdown, - Curl_cf_def_get_host, cf_quiche_adjust_pollset, cf_quiche_data_pending, cf_quiche_send, cf_quiche_recv, - cf_quiche_data_event, + cf_quiche_cntrl, cf_quiche_conn_is_alive, Curl_cf_def_conn_keep_alive, cf_quiche_query, @@ -1707,20 +1674,4 @@ CURLcode Curl_cf_quiche_create(struct Curl_cfilter **pcf, return result; } -bool Curl_conn_is_quiche(const struct Curl_easy *data, - const struct connectdata *conn, - int sockindex) -{ - struct Curl_cfilter *cf = conn ? conn->cfilter[sockindex] : NULL; - - (void)data; - for(; cf; cf = cf->next) { - if(cf->cft == &Curl_cft_http3) - return TRUE; - if(cf->cft->flags & CF_TYPE_IP_CONNECT) - return FALSE; - } - return FALSE; -} - #endif diff --git a/vendor/curl/lib/vquic/curl_quiche.h b/vendor/curl/lib/vquic/curl_quiche.h index 9832687bdc1..bee966eeb7a 100644 --- a/vendor/curl/lib/vquic/curl_quiche.h +++ b/vendor/curl/lib/vquic/curl_quiche.h @@ -26,7 +26,7 @@ #include "../curl_setup.h" -#ifdef USE_QUICHE +#if !defined(CURL_DISABLE_HTTP) && defined(USE_QUICHE) #include #include @@ -41,10 +41,6 @@ CURLcode Curl_cf_quiche_create(struct Curl_cfilter **pcf, struct connectdata *conn, const struct Curl_addrinfo *ai); -bool Curl_conn_is_quiche(const struct Curl_easy *data, - const struct connectdata *conn, - int sockindex); - #endif #endif /* HEADER_CURL_VQUIC_CURL_QUICHE_H */ diff --git a/vendor/curl/lib/vquic/vquic-tls.c b/vendor/curl/lib/vquic/vquic-tls.c index 2a5be138fc6..4bdd23c981c 100644 --- a/vendor/curl/lib/vquic/vquic-tls.c +++ b/vendor/curl/lib/vquic/vquic-tls.c @@ -167,7 +167,7 @@ CURLcode Curl_vquic_tls_verify_peer(struct curl_tls_ctx *ctx, #ifdef USE_OPENSSL (void)conn_config; - result = Curl_oss_check_peer_cert(cf, data, &ctx->ossl, peer); + result = Curl_ossl_check_peer_cert(cf, data, &ctx->ossl, peer); #elif defined(USE_GNUTLS) if(conn_config->verifyhost) { result = Curl_gtls_verifyserver(data, ctx->gtls.session, @@ -197,4 +197,46 @@ CURLcode Curl_vquic_tls_verify_peer(struct curl_tls_ctx *ctx, } +bool Curl_vquic_tls_get_ssl_info(struct curl_tls_ctx *ctx, + bool give_ssl_ctx, + struct curl_tlssessioninfo *info) +{ +#ifdef USE_OPENSSL + info->backend = CURLSSLBACKEND_OPENSSL; + info->internals = give_ssl_ctx ? + (void *)ctx->ossl.ssl_ctx : (void *)ctx->ossl.ssl; + return TRUE; +#elif defined(USE_GNUTLS) + (void)give_ssl_ctx; /* gnutls always returns its session */ + info->backend = CURLSSLBACKEND_GNUTLS; + info->internals = ctx->gtls.session; + return TRUE; +#elif defined(USE_WOLFSSL) + info->backend = CURLSSLBACKEND_WOLFSSL; + info->internals = give_ssl_ctx ? + (void *)ctx->wssl.ssl_ctx : (void *)ctx->wssl.ssl; + return TRUE; +#else + return FALSE; +#endif +} + +void Curl_vquic_report_handshake(struct curl_tls_ctx *ctx, + struct Curl_cfilter *cf, + struct Curl_easy *data) +{ + (void)cf; +#ifdef USE_OPENSSL + (void)cf; + Curl_ossl_report_handshake(data, &ctx->ossl); +#elif defined(USE_GNUTLS) + Curl_gtls_report_handshake(data, &ctx->gtls); +#elif defined(USE_WOLFSSL) + Curl_wssl_report_handshake(data, &ctx->wssl); +#else + (void)data; + (void)ctx; +#endif +} + #endif /* !USE_HTTP3 && (USE_OPENSSL || USE_GNUTLS || USE_WOLFSSL) */ diff --git a/vendor/curl/lib/vquic/vquic-tls.h b/vendor/curl/lib/vquic/vquic-tls.h index bf29eecc916..c694e23e4e6 100644 --- a/vendor/curl/lib/vquic/vquic-tls.h +++ b/vendor/curl/lib/vquic/vquic-tls.h @@ -37,6 +37,7 @@ struct ssl_peer; struct Curl_ssl_session; +struct curl_tlssessioninfo; struct curl_tls_ctx { #ifdef USE_OPENSSL @@ -106,6 +107,14 @@ CURLcode Curl_vquic_tls_verify_peer(struct curl_tls_ctx *ctx, struct Curl_easy *data, struct ssl_peer *peer); +bool Curl_vquic_tls_get_ssl_info(struct curl_tls_ctx *ctx, + bool give_ssl_ctx, + struct curl_tlssessioninfo *info); + +void Curl_vquic_report_handshake(struct curl_tls_ctx *ctx, + struct Curl_cfilter *cf, + struct Curl_easy *data); + #endif /* !USE_HTTP3 && (USE_OPENSSL || USE_GNUTLS || USE_WOLFSSL) */ #endif /* HEADER_CURL_VQUIC_TLS_H */ diff --git a/vendor/curl/lib/vquic/vquic.c b/vendor/curl/lib/vquic/vquic.c index b5dc44f8aa9..f8ce34129ba 100644 --- a/vendor/curl/lib/vquic/vquic.c +++ b/vendor/curl/lib/vquic/vquic.c @@ -35,7 +35,6 @@ #include "../curlx/dynbuf.h" #include "../cfilters.h" #include "../curl_trc.h" -#include "curl_msh3.h" #include "curl_ngtcp2.h" #include "curl_osslq.h" #include "curl_quiche.h" @@ -52,7 +51,7 @@ #include "../memdebug.h" -#ifdef USE_HTTP3 +#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP3) #define NW_CHUNK_SIZE (64 * 1024) #define NW_SEND_CHUNKS 2 @@ -76,8 +75,6 @@ void Curl_quic_ver(char *p, size_t len) Curl_osslq_ver(p, len); #elif defined(USE_QUICHE) Curl_quiche_ver(p, len); -#elif defined(USE_MSH3) - Curl_msh3_ver(p, len); #endif } @@ -308,7 +305,7 @@ CURLcode vquic_flush(struct Curl_cfilter *cf, struct Curl_easy *data, } CURLcode vquic_send(struct Curl_cfilter *cf, struct Curl_easy *data, - struct cf_quic_ctx *qctx, size_t gsolen) + struct cf_quic_ctx *qctx, size_t gsolen) { qctx->gsolen = gsolen; return vquic_flush(cf, data, qctx); @@ -615,7 +612,7 @@ CURLcode vquic_recv_packets(struct Curl_cfilter *cf, vquic_recv_pkt_cb *recv_cb, void *userp) { CURLcode result; -#if defined(HAVE_SENDMMSG) +#ifdef HAVE_SENDMMSG result = recvmmsg_packets(cf, data, qctx, max_pkts, recv_cb, userp); #elif defined(HAVE_SENDMSG) result = recvmsg_packets(cf, data, qctx, max_pkts, recv_cb, userp); @@ -645,7 +642,7 @@ CURLcode Curl_qlogdir(struct Curl_easy *data, size_t scidlen, int *qlogfdp) { - const char *qlog_dir = getenv("QLOGDIR"); + char *qlog_dir = curl_getenv("QLOGDIR"); *qlogfdp = -1; if(qlog_dir) { struct dynbuf fname; @@ -670,6 +667,7 @@ CURLcode Curl_qlogdir(struct Curl_easy *data, *qlogfdp = qlogfd; } curlx_dyn_free(&fname); + free(qlog_dir); if(result) return result; } @@ -691,8 +689,6 @@ CURLcode Curl_cf_quic_create(struct Curl_cfilter **pcf, return Curl_cf_osslq_create(pcf, data, conn, ai); #elif defined(USE_QUICHE) return Curl_cf_quiche_create(pcf, data, conn, ai); -#elif defined(USE_MSH3) - return Curl_cf_msh3_create(pcf, data, conn, ai); #else *pcf = NULL; (void)data; @@ -703,9 +699,10 @@ CURLcode Curl_cf_quic_create(struct Curl_cfilter **pcf, } CURLcode Curl_conn_may_http3(struct Curl_easy *data, - const struct connectdata *conn) + const struct connectdata *conn, + unsigned char transport) { - if(conn->transport == TRNSPRT_UNIX) { + if(transport == TRNSPRT_UNIX) { /* cannot do QUIC over a Unix domain socket */ return CURLE_QUIC_CONNECT_ERROR; } @@ -727,15 +724,17 @@ CURLcode Curl_conn_may_http3(struct Curl_easy *data, return CURLE_OK; } -#else /* USE_HTTP3 */ +#else /* CURL_DISABLE_HTTP || !USE_HTTP3 */ CURLcode Curl_conn_may_http3(struct Curl_easy *data, - const struct connectdata *conn) + const struct connectdata *conn, + unsigned char transport) { (void)conn; (void)data; + (void)transport; DEBUGF(infof(data, "QUIC is not supported in this build")); return CURLE_NOT_BUILT_IN; } -#endif /* !USE_HTTP3 */ +#endif /* !CURL_DISABLE_HTTP && USE_HTTP3 */ diff --git a/vendor/curl/lib/vquic/vquic.h b/vendor/curl/lib/vquic/vquic.h index dbf63b1f6fe..0f81334f293 100644 --- a/vendor/curl/lib/vquic/vquic.h +++ b/vendor/curl/lib/vquic/vquic.h @@ -26,7 +26,7 @@ #include "../curl_setup.h" -#ifdef USE_HTTP3 +#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP3) struct Curl_cfilter; struct Curl_easy; struct connectdata; @@ -51,9 +51,10 @@ extern struct Curl_cftype Curl_cft_http3; #else #define Curl_vquic_init() 1 -#endif /* !USE_HTTP3 */ +#endif /* !CURL_DISABLE_HTTP && USE_HTTP3 */ CURLcode Curl_conn_may_http3(struct Curl_easy *data, - const struct connectdata *conn); + const struct connectdata *conn, + unsigned char transport); #endif /* HEADER_CURL_VQUIC_QUIC_H */ diff --git a/vendor/curl/lib/vquic/vquic_int.h b/vendor/curl/lib/vquic/vquic_int.h index 4641c3125b0..d271368d290 100644 --- a/vendor/curl/lib/vquic/vquic_int.h +++ b/vendor/curl/lib/vquic/vquic_int.h @@ -68,7 +68,7 @@ CURLcode vquic_send_blocked_pkts(struct Curl_cfilter *cf, struct cf_quic_ctx *qctx); CURLcode vquic_send(struct Curl_cfilter *cf, struct Curl_easy *data, - struct cf_quic_ctx *qctx, size_t gsolen); + struct cf_quic_ctx *qctx, size_t gsolen); CURLcode vquic_send_tail_split(struct Curl_cfilter *cf, struct Curl_easy *data, struct cf_quic_ctx *qctx, size_t gsolen, diff --git a/vendor/curl/lib/vssh/curl_path.c b/vendor/curl/lib/vssh/curl_path.c index 117d2e6009f..021e85faf8e 100644 --- a/vendor/curl/lib/vssh/curl_path.c +++ b/vendor/curl/lib/vssh/curl_path.c @@ -24,7 +24,7 @@ #include "../curl_setup.h" -#if defined(USE_SSH) +#ifdef USE_SSH #include "curl_path.h" #include @@ -84,6 +84,12 @@ CURLcode Curl_getworkingpath(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; } } + else { + if(curlx_dyn_add(&npath, "/")) { + free(working_path); + return CURLE_OUT_OF_MEMORY; + } + } } if(curlx_dyn_len(&npath)) { diff --git a/vendor/curl/lib/vssh/libssh.c b/vendor/curl/lib/vssh/libssh.c index 86f1e1a568b..8c366aafae1 100644 --- a/vendor/curl/lib/vssh/libssh.c +++ b/vendor/curl/lib/vssh/libssh.c @@ -58,11 +58,9 @@ #include "../speedcheck.h" #include "../getinfo.h" #include "../strdup.h" -#include "../strcase.h" #include "../vtls/vtls.h" #include "../cfilters.h" #include "../connect.h" -#include "../inet_ntop.h" #include "../parsedate.h" /* for the week day and month names */ #include "../sockaddr.h" /* required for Curl_sockaddr_storage */ #include "../curlx/strparse.h" @@ -71,9 +69,6 @@ #include "../curlx/warnless.h" #include "curl_path.h" -#ifdef HAVE_SYS_STAT_H -#include -#endif #ifdef HAVE_UNISTD_H #include #endif @@ -130,12 +125,8 @@ CURLcode sftp_perform(struct Curl_easy *data, bool *connected, bool *dophase_done); -static void sftp_quote(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp); -static void sftp_quote_stat(struct Curl_easy *data, struct ssh_conn *sshc); -static int myssh_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *sock); +static CURLcode myssh_pollset(struct Curl_easy *data, + struct easy_pollset *ps); static void myssh_block2waitfor(struct connectdata *conn, struct ssh_conn *sshc, bool block); @@ -157,10 +148,10 @@ const struct Curl_handler Curl_handler_scp = { myssh_connect, /* connect_it */ myssh_multi_statemach, /* connecting */ scp_doing, /* doing */ - myssh_getsock, /* proto_getsock */ - myssh_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - myssh_getsock, /* perform_getsock */ + myssh_pollset, /* proto_pollset */ + myssh_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + myssh_pollset, /* perform_pollset */ scp_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -186,10 +177,10 @@ const struct Curl_handler Curl_handler_sftp = { myssh_connect, /* connect_it */ myssh_multi_statemach, /* connecting */ sftp_doing, /* doing */ - myssh_getsock, /* proto_getsock */ - myssh_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - myssh_getsock, /* perform_getsock */ + myssh_pollset, /* proto_pollset */ + myssh_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + myssh_pollset, /* perform_pollset */ sftp_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -227,10 +218,10 @@ static CURLcode sftp_error_to_CURLE(int err) return CURLE_SSH; } -#ifndef DEBUGBUILD -#define myssh_state(x,y,z) myssh_set_state(x,y,z) +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) +#define myssh_to(x,y,z) myssh_set_state(x,y,z, __LINE__) #else -#define myssh_state(x,y,z) myssh_set_state(x,y,z, __LINE__) +#define myssh_to(x,y,z) myssh_set_state(x,y,z) #endif /* @@ -240,7 +231,7 @@ static CURLcode sftp_error_to_CURLE(int err) static void myssh_set_state(struct Curl_easy *data, struct ssh_conn *sshc, sshstate nowstate -#ifdef DEBUGBUILD +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) , int lineno #endif ) @@ -371,7 +362,7 @@ static int myssh_is_known(struct Curl_easy *data, struct ssh_conn *sshc) infof(data, "SSH MD5 fingerprint: %s", md5buffer); - if(!strcasecompare(md5buffer, pubkey_md5)) { + if(!curl_strequal(md5buffer, pubkey_md5)) { failf(data, "Denied establishing ssh session: mismatch md5 fingerprint. " "Remote %s is not equal to %s", md5buffer, pubkey_md5); @@ -519,52 +510,302 @@ static int myssh_is_known(struct Curl_easy *data, struct ssh_conn *sshc) return rc; } -#define MOVE_TO_ERROR_STATE(_r) do { \ - myssh_state(data, sshc, SSH_SESSION_DISCONNECT); \ - sshc->actualcode = _r; \ - rc = SSH_ERROR; \ - } while(0) +static int myssh_to_ERROR(struct Curl_easy *data, + struct ssh_conn *sshc, + CURLcode result) +{ + myssh_to(data, sshc, SSH_SESSION_DISCONNECT); + sshc->actualcode = result; + return SSH_ERROR; +} -#define MOVE_TO_SFTP_CLOSE_STATE() do { \ - myssh_state(data, sshc, SSH_SFTP_CLOSE); \ - sshc->actualcode = \ - sftp_error_to_CURLE(sftp_get_error(sshc->sftp_session)); \ - rc = SSH_ERROR; \ - } while(0) +static int myssh_to_SFTP_CLOSE(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->actualcode = + sftp_error_to_CURLE(sftp_get_error(sshc->sftp_session)); + return SSH_ERROR; +} -#define MOVE_TO_PASSWD_AUTH do { \ - if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \ - rc = SSH_OK; \ - myssh_state(data, sshc, SSH_AUTH_PASS_INIT); \ - } \ - else { \ - MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); \ - } \ - } while(0) +static int myssh_to_PASSWD_AUTH(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { + myssh_to(data, sshc, SSH_AUTH_PASS_INIT); + return SSH_OK; + } + return myssh_to_ERROR(data, sshc, CURLE_LOGIN_DENIED); +} -#define MOVE_TO_KEY_AUTH do { \ - if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \ - rc = SSH_OK; \ - myssh_state(data, sshc, SSH_AUTH_KEY_INIT); \ - } \ - else { \ - MOVE_TO_PASSWD_AUTH; \ - } \ - } while(0) +static int myssh_to_KEY_AUTH(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { + myssh_to(data, sshc, SSH_AUTH_KEY_INIT); + return SSH_OK; + } + return myssh_to_PASSWD_AUTH(data, sshc); +} -#define MOVE_TO_GSSAPI_AUTH do { \ - if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \ - rc = SSH_OK; \ - myssh_state(data, sshc, SSH_AUTH_GSSAPI); \ - } \ - else { \ - MOVE_TO_KEY_AUTH; \ - } \ - } while(0) +static int myssh_to_GSSAPI_AUTH(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { + myssh_to(data, sshc, SSH_AUTH_GSSAPI); + return SSH_OK; + } + return myssh_to_KEY_AUTH(data, sshc); +} -static -int myssh_auth_interactive(struct connectdata *conn, - struct ssh_conn *sshc) +static int myssh_in_SFTP_READDIR_INIT(struct Curl_easy *data, + struct ssh_conn *sshc, + struct SSHPROTO *sshp) +{ + Curl_pgrsSetDownloadSize(data, -1); + if(data->req.no_body) { + myssh_to(data, sshc, SSH_STOP); + return SSH_NO_ERROR; + } + + /* + * This is a directory that we are trying to get, so produce a directory + * listing + */ + sshc->sftp_dir = sftp_opendir(sshc->sftp_session, + sshp->path); + if(!sshc->sftp_dir) { + failf(data, "Could not open directory for reading: %s", + ssh_get_error(sshc->ssh_session)); + return myssh_to_SFTP_CLOSE(data, sshc); + } + myssh_to(data, sshc, SSH_SFTP_READDIR); + return SSH_NO_ERROR; +} + +static int myssh_in_SFTP_READDIR(struct Curl_easy *data, + struct ssh_conn *sshc, + struct SSHPROTO *sshp) +{ + CURLcode result = CURLE_OK; + + curlx_dyn_reset(&sshc->readdir_buf); + if(sshc->readdir_attrs) + sftp_attributes_free(sshc->readdir_attrs); + + sshc->readdir_attrs = sftp_readdir(sshc->sftp_session, sshc->sftp_dir); + if(sshc->readdir_attrs) { + sshc->readdir_filename = sshc->readdir_attrs->name; + sshc->readdir_longentry = sshc->readdir_attrs->longname; + sshc->readdir_len = strlen(sshc->readdir_filename); + + if(data->set.list_only) { + char *tmpLine; + + tmpLine = aprintf("%s\n", sshc->readdir_filename); + if(!tmpLine) { + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + return SSH_ERROR; + } + result = Curl_client_write(data, CLIENTWRITE_BODY, + tmpLine, sshc->readdir_len + 1); + free(tmpLine); + + if(result) { + myssh_to(data, sshc, SSH_STOP); + return SSH_NO_ERROR; + } + + } + else { + if(curlx_dyn_add(&sshc->readdir_buf, sshc->readdir_longentry)) { + sshc->actualcode = CURLE_OUT_OF_MEMORY; + myssh_to(data, sshc, SSH_STOP); + return SSH_ERROR; + } + + if((sshc->readdir_attrs->flags & SSH_FILEXFER_ATTR_PERMISSIONS) && + ((sshc->readdir_attrs->permissions & SSH_S_IFMT) == + SSH_S_IFLNK)) { + sshc->readdir_linkPath = aprintf("%s%s", sshp->path, + sshc->readdir_filename); + + if(!sshc->readdir_linkPath) { + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + return SSH_ERROR; + } + + myssh_to(data, sshc, SSH_SFTP_READDIR_LINK); + return SSH_NO_ERROR; + } + myssh_to(data, sshc, SSH_SFTP_READDIR_BOTTOM); + return SSH_NO_ERROR; + } + } + else if(sftp_dir_eof(sshc->sftp_dir)) { + myssh_to(data, sshc, SSH_SFTP_READDIR_DONE); + } + else { + failf(data, "Could not open remote directory for reading: %s", + ssh_get_error(sshc->ssh_session)); + return myssh_to_SFTP_CLOSE(data, sshc); + } + return SSH_NO_ERROR; +} + +static int myssh_in_SFTP_READDIR_LINK(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + if(sshc->readdir_link_attrs) + sftp_attributes_free(sshc->readdir_link_attrs); + + sshc->readdir_link_attrs = sftp_lstat(sshc->sftp_session, + sshc->readdir_linkPath); + if(!sshc->readdir_link_attrs) { + failf(data, "Could not read symlink for reading: %s", + ssh_get_error(sshc->ssh_session)); + return myssh_to_SFTP_CLOSE(data, sshc); + } + + if(!sshc->readdir_link_attrs->name) { + sshc->readdir_tmp = sftp_readlink(sshc->sftp_session, + sshc->readdir_linkPath); + if(!sshc->readdir_tmp) + sshc->readdir_len = 0; + else + sshc->readdir_len = strlen(sshc->readdir_tmp); + sshc->readdir_longentry = NULL; + sshc->readdir_filename = sshc->readdir_tmp; + } + else { + sshc->readdir_len = strlen(sshc->readdir_link_attrs->name); + sshc->readdir_filename = sshc->readdir_link_attrs->name; + sshc->readdir_longentry = sshc->readdir_link_attrs->longname; + } + + Curl_safefree(sshc->readdir_linkPath); + + if(curlx_dyn_addf(&sshc->readdir_buf, " -> %s", + sshc->readdir_filename)) { + /* Not using: + * return myssh_to_SFTP_CLOSE(data, sshc); + * + * as that assumes an sftp related error while + * assigning sshc->actualcode whereas the current + * error is curlx_dyn_addf() related. + */ + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + return SSH_ERROR; + } + + sftp_attributes_free(sshc->readdir_link_attrs); + sshc->readdir_link_attrs = NULL; + sshc->readdir_filename = NULL; + sshc->readdir_longentry = NULL; + + myssh_to(data, sshc, SSH_SFTP_READDIR_BOTTOM); + return SSH_NO_ERROR; +} + +static int myssh_in_SFTP_READDIR_BOTTOM(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + CURLcode result; + + if(curlx_dyn_addn(&sshc->readdir_buf, "\n", 1)) + result = CURLE_OUT_OF_MEMORY; + else + result = Curl_client_write(data, CLIENTWRITE_BODY, + curlx_dyn_ptr(&sshc->readdir_buf), + curlx_dyn_len(&sshc->readdir_buf)); + + ssh_string_free_char(sshc->readdir_tmp); + sshc->readdir_tmp = NULL; + + if(result) + myssh_to(data, sshc, SSH_STOP); + else + myssh_to(data, sshc, SSH_SFTP_READDIR); + return SSH_NO_ERROR; +} + +static int myssh_in_SFTP_READDIR_DONE(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + sftp_closedir(sshc->sftp_dir); + sshc->sftp_dir = NULL; + + /* no data to transfer */ + Curl_xfer_setup_nop(data); + myssh_to(data, sshc, SSH_STOP); + return SSH_NO_ERROR; +} + +static int myssh_in_SFTP_QUOTE_STATVFS(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + sftp_statvfs_t statvfs; + + statvfs = sftp_statvfs(sshc->sftp_session, sshc->quote_path1); + if(!statvfs && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + failf(data, "statvfs command failed: %s", + ssh_get_error(sshc->ssh_session)); + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return SSH_OK; + } + else if(statvfs) { + #ifdef _MSC_VER + #define CURL_LIBSSH_VFS_SIZE_MASK "I64u" + #else + #define CURL_LIBSSH_VFS_SIZE_MASK PRIu64 + #endif + CURLcode result; + char *tmp = aprintf("statvfs:\n" + "f_bsize: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" + "f_frsize: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" + "f_blocks: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" + "f_bfree: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" + "f_bavail: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" + "f_files: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" + "f_ffree: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" + "f_favail: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" + "f_fsid: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" + "f_flag: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" + "f_namemax: %" CURL_LIBSSH_VFS_SIZE_MASK "\n", + statvfs->f_bsize, statvfs->f_frsize, + statvfs->f_blocks, statvfs->f_bfree, + statvfs->f_bavail, statvfs->f_files, + statvfs->f_ffree, statvfs->f_favail, + statvfs->f_fsid, statvfs->f_flag, + statvfs->f_namemax); + sftp_statvfs_free(statvfs); + + if(!tmp) { + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + return SSH_OK; + } + + result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp)); + free(tmp); + if(result) { + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + } + } + myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); + return SSH_OK; +} + +static int myssh_auth_interactive(struct connectdata *conn, + struct ssh_conn *sshc) { int rc; int nprompts; @@ -642,11 +883,11 @@ static void myssh_state_init(struct Curl_easy *data, non-blocking */ ssh_set_blocking(sshc->ssh_session, 0); - myssh_state(data, sshc, SSH_S_STARTUP); + myssh_to(data, sshc, SSH_S_STARTUP); } -static int myssh_state_startup(struct Curl_easy *data, - struct ssh_conn *sshc) +static int myssh_in_S_STARTUP(struct Curl_easy *data, + struct ssh_conn *sshc) { struct connectdata *conn = data->conn; int rc = ssh_connect(sshc->ssh_session); @@ -657,16 +898,16 @@ static int myssh_state_startup(struct Curl_easy *data, } else if(rc != SSH_OK) { failf(data, "Failure establishing ssh session"); - MOVE_TO_ERROR_STATE(CURLE_FAILED_INIT); + rc = myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT); } else - myssh_state(data, sshc, SSH_HOSTKEY); + myssh_to(data, sshc, SSH_HOSTKEY); return rc; } -static int myssh_state_authlist(struct Curl_easy *data, - struct ssh_conn *sshc) +static int myssh_in_AUTHLIST(struct Curl_easy *data, + struct ssh_conn *sshc) { int rc; sshc->authed = FALSE; @@ -678,11 +919,11 @@ static int myssh_state_authlist(struct Curl_easy *data, if(rc == SSH_AUTH_SUCCESS) { sshc->authed = TRUE; infof(data, "Authenticated with none"); - myssh_state(data, sshc, SSH_AUTH_DONE); + myssh_to(data, sshc, SSH_AUTH_DONE); return rc; } else if(rc == SSH_AUTH_ERROR) { - MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + rc = myssh_to_ERROR(data, sshc, CURLE_LOGIN_DENIED); return rc; } @@ -699,31 +940,31 @@ static int myssh_state_authlist(struct Curl_easy *data, sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD ? "password": ""); if(sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) { - myssh_state(data, sshc, SSH_AUTH_PKEY_INIT); + myssh_to(data, sshc, SSH_AUTH_PKEY_INIT); infof(data, "Authentication using SSH public key file"); } else if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { - myssh_state(data, sshc, SSH_AUTH_GSSAPI); + myssh_to(data, sshc, SSH_AUTH_GSSAPI); } else if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { - myssh_state(data, sshc, SSH_AUTH_KEY_INIT); + myssh_to(data, sshc, SSH_AUTH_KEY_INIT); } else if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { - myssh_state(data, sshc, SSH_AUTH_PASS_INIT); + myssh_to(data, sshc, SSH_AUTH_PASS_INIT); } else { /* unsupported authentication method */ - MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + rc = myssh_to_ERROR(data, sshc, CURLE_LOGIN_DENIED); } return rc; } -static int myssh_state_auth_pkey_init(struct Curl_easy *data, - struct ssh_conn *sshc) +static int myssh_in_AUTH_PKEY_INIT(struct Curl_easy *data, + struct ssh_conn *sshc) { int rc; if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY)) { - MOVE_TO_GSSAPI_AUTH; - return 0; + rc = myssh_to_GSSAPI_AUTH(data, sshc); + return rc; } /* Two choices, (1) private key was given on CMD, @@ -736,7 +977,7 @@ static int myssh_state_auth_pkey_init(struct Curl_easy *data, return SSH_AGAIN; if(rc != SSH_OK) { - MOVE_TO_GSSAPI_AUTH; + rc = myssh_to_GSSAPI_AUTH(data, sshc); return rc; } } @@ -748,11 +989,11 @@ static int myssh_state_auth_pkey_init(struct Curl_easy *data, if(rc != SSH_OK) { failf(data, "Could not load private key file %s", data->set.str[STRING_SSH_PRIVATE_KEY]); - MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + rc = myssh_to_ERROR(data, sshc, CURLE_LOGIN_DENIED); return rc; } - myssh_state(data, sshc, SSH_AUTH_PKEY); + myssh_to(data, sshc, SSH_AUTH_PKEY); } else { rc = ssh_userauth_publickey_auto(sshc->ssh_session, NULL, @@ -764,18 +1005,131 @@ static int myssh_state_auth_pkey_init(struct Curl_easy *data, rc = SSH_OK; sshc->authed = TRUE; infof(data, "Completed public key authentication"); - myssh_state(data, sshc, SSH_AUTH_DONE); + myssh_to(data, sshc, SSH_AUTH_DONE); return rc; } - MOVE_TO_GSSAPI_AUTH; + rc = myssh_to_GSSAPI_AUTH(data, sshc); } return rc; } -static int myssh_state_upload_init(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) +static int myssh_in_AUTH_PKEY(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + int rc = ssh_userauth_publickey(sshc->ssh_session, NULL, sshc->privkey); + if(rc == SSH_AUTH_AGAIN) + return SSH_AGAIN; + else if(rc == SSH_AUTH_SUCCESS) { + sshc->authed = TRUE; + infof(data, "Completed public key authentication"); + myssh_to(data, sshc, SSH_AUTH_DONE); + return SSH_OK; + } + else { + infof(data, "Failed public key authentication (rc: %d)", rc); + return myssh_to_GSSAPI_AUTH(data, sshc); + } +} + +static int myssh_in_AUTH_GSSAPI(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + int rc; + if(!(data->set.ssh_auth_types & CURLSSH_AUTH_GSSAPI)) + return myssh_to_KEY_AUTH(data, sshc); + + rc = ssh_userauth_gssapi(sshc->ssh_session); + if(rc == SSH_AUTH_AGAIN) + return SSH_AGAIN; + + if(rc == SSH_AUTH_SUCCESS) { + sshc->authed = TRUE; + infof(data, "Completed gssapi authentication"); + myssh_to(data, sshc, SSH_AUTH_DONE); + return SSH_OK; + } + + return myssh_to_KEY_AUTH(data, sshc); +} + +static int myssh_in_AUTH_KEY_INIT(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + if(data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) { + myssh_to(data, sshc, SSH_AUTH_KEY); + return SSH_NO_ERROR; + } + return myssh_to_PASSWD_AUTH(data, sshc); +} + +static int myssh_in_AUTH_KEY(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + /* keyboard-interactive authentication */ + int rc = myssh_auth_interactive(data->conn, sshc); + if(rc == SSH_AGAIN) + return rc; + else if(rc == SSH_OK) { + sshc->authed = TRUE; + infof(data, "completed keyboard interactive authentication"); + myssh_to(data, sshc, SSH_AUTH_DONE); + return SSH_NO_ERROR; + } + else + return myssh_to_PASSWD_AUTH(data, sshc); +} + +static int myssh_in_AUTH_PASS_INIT(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD)) + return myssh_to_ERROR(data, sshc, CURLE_LOGIN_DENIED); + myssh_to(data, sshc, SSH_AUTH_PASS); + return SSH_NO_ERROR; +} + +static int myssh_in_AUTH_PASS(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + int rc = ssh_userauth_password(sshc->ssh_session, NULL, data->conn->passwd); + if(rc == SSH_AUTH_AGAIN) + return SSH_AGAIN; + else if(rc == SSH_AUTH_SUCCESS) { + sshc->authed = TRUE; + infof(data, "Completed password authentication"); + myssh_to(data, sshc, SSH_AUTH_DONE); + return SSH_NO_ERROR; + } + return myssh_to_ERROR(data, sshc, CURLE_LOGIN_DENIED); +} + +static int myssh_in_AUTH_DONE(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + if(!sshc->authed) { + failf(data, "Authentication failure"); + return myssh_to_ERROR(data, sshc, CURLE_LOGIN_DENIED); + } + + /* At this point we have an authenticated ssh session. */ + infof(data, "Authentication complete"); + Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSH is connected */ + data->conn->recv_idx = FIRSTSOCKET; + data->conn->send_idx = -1; + + if(data->conn->handler->protocol == CURLPROTO_SFTP) { + myssh_to(data, sshc, SSH_SFTP_INIT); + return SSH_NO_ERROR; + } + infof(data, "SSH CONNECT phase done"); + myssh_to(data, sshc, SSH_STOP); + return SSH_NO_ERROR; +} + +static int myssh_in_UPLOAD_INIT(struct Curl_easy *data, + struct ssh_conn *sshc, + struct SSHPROTO *sshp) { int flags; int rc = 0; @@ -789,7 +1143,7 @@ static int myssh_state_upload_init(struct Curl_easy *data, curl_off_t size = attrs->size; if(size < 0) { failf(data, "Bad file size (%" FMT_OFF_T ")", size); - MOVE_TO_ERROR_STATE(CURLE_BAD_DOWNLOAD_RESUME); + rc = myssh_to_ERROR(data, sshc, CURLE_BAD_DOWNLOAD_RESUME); return rc; } data->state.resume_from = attrs->size; @@ -827,11 +1181,11 @@ static int myssh_state_upload_init(struct Curl_easy *data, /* try to create the path remotely */ rc = 0; sshc->secondCreateDirs = 1; - myssh_state(data, sshc, SSH_SFTP_CREATE_DIRS_INIT); + myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS_INIT); return rc; } else { - MOVE_TO_SFTP_CLOSE_STATE(); + rc = myssh_to_SFTP_CLOSE(data, sshc); return rc; } } @@ -853,7 +1207,7 @@ static int myssh_state_upload_init(struct Curl_easy *data, if(seekerr != CURL_SEEKFUNC_CANTSEEK) { failf(data, "Could not seek stream"); - MOVE_TO_ERROR_STATE(CURLE_FTP_COULDNT_USE_REST); + rc = myssh_to_ERROR(data, sshc, CURLE_FTP_COULDNT_USE_REST); return rc; } /* seekerr == CURL_SEEKFUNC_CANTSEEK (cannot seek to offset) */ @@ -873,7 +1227,7 @@ static int myssh_state_upload_init(struct Curl_easy *data, /* this checks for greater-than only to make sure that the CURL_READFUNC_ABORT return code still aborts */ failf(data, "Failed to read data"); - MOVE_TO_ERROR_STATE(CURLE_FTP_COULDNT_USE_REST); + rc = myssh_to_ERROR(data, sshc, CURLE_FTP_COULDNT_USE_REST); return rc; } } while(passed < data->state.resume_from); @@ -888,7 +1242,7 @@ static int myssh_state_upload_init(struct Curl_easy *data, rc = sftp_seek64(sshc->sftp_file, data->state.resume_from); if(rc) { - MOVE_TO_SFTP_CLOSE_STATE(); + rc = myssh_to_SFTP_CLOSE(data, sshc); return rc; } } @@ -897,33 +1251,48 @@ static int myssh_state_upload_init(struct Curl_easy *data, Curl_pgrsSetUploadSize(data, data->state.infilesize); } /* upload data */ - Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE); + Curl_xfer_setup_send(data, FIRSTSOCKET); /* not set by Curl_xfer_setup to preserve keepon bits */ - data->conn->sockfd = data->conn->writesockfd; + data->conn->recv_idx = FIRSTSOCKET; /* store this original bitmask setup to use later on if we cannot figure out a "real" bitmask */ sshc->orig_waitfor = data->req.keepon; - /* we want to use the _sending_ function even when the socket turns - out readable as the underlying libssh sftp send function will deal - with both accordingly */ - data->state.select_bits = CURL_CSELECT_OUT; - /* since we do not really wait for anything at this point, we want the - state machine to move on as soon as possible so we set a very short - timeout here */ - Curl_expire(data, 0, EXPIRE_RUN_NOW); + state machine to move on as soon as possible so we mark this as dirty */ + Curl_multi_mark_dirty(data); #if LIBSSH_VERSION_INT > SSH_VERSION_INT(0, 11, 0) sshc->sftp_send_state = 0; #endif - myssh_state(data, sshc, SSH_STOP); + myssh_to(data, sshc, SSH_STOP); return rc; } -static int myssh_state_sftp_download_stat(struct Curl_easy *data, - struct ssh_conn *sshc) +static int myssh_in_SFTP_DOWNLOAD_INIT(struct Curl_easy *data, + struct ssh_conn *sshc, + struct SSHPROTO *sshp) +{ + /* Work on getting the specified file */ + if(sshc->sftp_file) + sftp_close(sshc->sftp_file); + + sshc->sftp_file = sftp_open(sshc->sftp_session, sshp->path, + O_RDONLY, (mode_t)data->set.new_file_perms); + if(!sshc->sftp_file) { + failf(data, "Could not open remote file for reading: %s", + ssh_get_error(sshc->ssh_session)); + + return myssh_to_SFTP_CLOSE(data, sshc); + } + sftp_file_set_nonblocking(sshc->sftp_file); + myssh_to(data, sshc, SSH_SFTP_DOWNLOAD_STAT); + return SSH_NO_ERROR; +} + +static int myssh_in_SFTP_DOWNLOAD_STAT(struct Curl_easy *data, + struct ssh_conn *sshc) { curl_off_t size; int rc = 0; @@ -951,7 +1320,7 @@ static int myssh_state_sftp_download_stat(struct Curl_easy *data, if(size < 0) { failf(data, "Bad file size (%" FMT_OFF_T ")", size); - MOVE_TO_ERROR_STATE(CURLE_BAD_DOWNLOAD_RESUME); + rc = myssh_to_ERROR(data, sshc, CURLE_BAD_DOWNLOAD_RESUME); return rc; } if(data->state.use_range) { @@ -961,7 +1330,7 @@ static int myssh_state_sftp_download_stat(struct Curl_easy *data, from_t = curlx_str_number(&p, &from, CURL_OFF_T_MAX); if(from_t == STRE_OVERFLOW) { - MOVE_TO_ERROR_STATE(CURLE_RANGE_ERROR); + rc = myssh_to_ERROR(data, sshc, CURLE_RANGE_ERROR); return rc; } curlx_str_passblanks(&p); @@ -985,7 +1354,7 @@ static int myssh_state_sftp_download_stat(struct Curl_easy *data, if(from > size) { failf(data, "Offset (%" FMT_OFF_T ") was beyond file size (%" FMT_OFF_T ")", from, size); - MOVE_TO_ERROR_STATE(CURLE_BAD_DOWNLOAD_RESUME); + rc = myssh_to_ERROR(data, sshc, CURLE_BAD_DOWNLOAD_RESUME); return rc; } if(from > to) { @@ -994,7 +1363,7 @@ static int myssh_state_sftp_download_stat(struct Curl_easy *data, } else { if((to - from) == CURL_OFF_T_MAX) { - MOVE_TO_ERROR_STATE(CURLE_RANGE_ERROR); + rc = myssh_to_ERROR(data, sshc, CURLE_RANGE_ERROR); return rc; } size = to - from + 1; @@ -1002,7 +1371,7 @@ static int myssh_state_sftp_download_stat(struct Curl_easy *data, rc = sftp_seek64(sshc->sftp_file, from); if(rc) { - MOVE_TO_SFTP_CLOSE_STATE(); + rc = myssh_to_SFTP_CLOSE(data, sshc); return rc; } } @@ -1018,7 +1387,7 @@ static int myssh_state_sftp_download_stat(struct Curl_easy *data, if((curl_off_t)size < -data->state.resume_from) { failf(data, "Offset (%" FMT_OFF_T ") was beyond file size (%" FMT_OFF_T ")", data->state.resume_from, size); - MOVE_TO_ERROR_STATE(CURLE_BAD_DOWNLOAD_RESUME); + rc = myssh_to_ERROR(data, sshc, CURLE_BAD_DOWNLOAD_RESUME); return rc; } /* download from where? */ @@ -1029,7 +1398,7 @@ static int myssh_state_sftp_download_stat(struct Curl_easy *data, failf(data, "Offset (%" FMT_OFF_T ") was beyond file size (%" FMT_OFF_T ")", data->state.resume_from, size); - MOVE_TO_ERROR_STATE(CURLE_BAD_DOWNLOAD_RESUME); + rc = myssh_to_ERROR(data, sshc, CURLE_BAD_DOWNLOAD_RESUME); return rc; } } @@ -1041,7 +1410,7 @@ static int myssh_state_sftp_download_stat(struct Curl_easy *data, rc = sftp_seek64(sshc->sftp_file, data->state.resume_from); if(rc) { - MOVE_TO_SFTP_CLOSE_STATE(); + rc = myssh_to_SFTP_CLOSE(data, sshc); return rc; } } @@ -1051,285 +1420,557 @@ static int myssh_state_sftp_download_stat(struct Curl_easy *data, /* no data to transfer */ Curl_xfer_setup_nop(data); infof(data, "File already completely downloaded"); - myssh_state(data, sshc, SSH_STOP); + myssh_to(data, sshc, SSH_STOP); return rc; } - Curl_xfer_setup1(data, CURL_XFER_RECV, data->req.size, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, data->req.size); /* not set by Curl_xfer_setup to preserve keepon bits */ - data->conn->writesockfd = data->conn->sockfd; - - /* we want to use the _receiving_ function even when the socket turns - out writableable as the underlying libssh recv function will deal - with both accordingly */ - data->state.select_bits = CURL_CSELECT_IN; + data->conn->send_idx = 0; sshc->sftp_recv_state = 0; - myssh_state(data, sshc, SSH_STOP); + myssh_to(data, sshc, SSH_STOP); return rc; } -/* - * ssh_statemach_act() runs the SSH state machine as far as it can without - * blocking and without reaching the end. The data the pointer 'block' points - * to will be set to TRUE if the libssh function returns SSH_AGAIN - * meaning it wants to be called again when the socket is ready - */ -static CURLcode myssh_statemach_act(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp, - bool *block) +static int myssh_in_SFTP_CLOSE(struct Curl_easy *data, + struct ssh_conn *sshc, + struct SSHPROTO *sshp) { - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - curl_socket_t sock = conn->sock[FIRSTSOCKET]; - int rc = SSH_NO_ERROR, err; - const char *err_msg; - *block = 0; /* we are not blocking by default */ - - do { + if(sshc->sftp_file) { + sftp_close(sshc->sftp_file); + sshc->sftp_file = NULL; + } + Curl_safefree(sshp->path); - switch(sshc->state) { - case SSH_INIT: - myssh_state_init(data, sshc); - FALLTHROUGH(); + DEBUGF(infof(data, "SFTP DONE done")); - case SSH_S_STARTUP: - rc = myssh_state_startup(data, sshc); - if(rc) - break; - FALLTHROUGH(); - case SSH_HOSTKEY: - rc = myssh_is_known(data, sshc); - if(rc != SSH_OK) { - MOVE_TO_ERROR_STATE(CURLE_PEER_FAILED_VERIFICATION); - break; - } + /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT + After nextstate is executed, the control should come back to + SSH_SFTP_CLOSE to pass the correct result back */ + if(sshc->nextstate != SSH_NO_STATE && + sshc->nextstate != SSH_SFTP_CLOSE) { + myssh_to(data, sshc, sshc->nextstate); + sshc->nextstate = SSH_SFTP_CLOSE; + } + else { + myssh_to(data, sshc, SSH_STOP); + } + return SSH_NO_ERROR; +} - myssh_state(data, sshc, SSH_AUTHLIST); - FALLTHROUGH(); - case SSH_AUTHLIST: - rc = myssh_state_authlist(data, sshc); - break; - case SSH_AUTH_PKEY_INIT: - rc = myssh_state_auth_pkey_init(data, sshc); - break; - case SSH_AUTH_PKEY: - rc = ssh_userauth_publickey(sshc->ssh_session, NULL, sshc->privkey); - if(rc == SSH_AUTH_AGAIN) { - rc = SSH_AGAIN; - break; - } +static int myssh_in_SFTP_SHUTDOWN(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + /* during times we get here due to a broken transfer and then the + sftp_handle might not have been taken down so make sure that is done + before we proceed */ + ssh_set_blocking(sshc->ssh_session, 0); +#if LIBSSH_VERSION_INT > SSH_VERSION_INT(0, 11, 0) + SFTP_AIO_FREE(sshc->sftp_send_aio); + SFTP_AIO_FREE(sshc->sftp_recv_aio); +#endif - if(rc == SSH_AUTH_SUCCESS) { - sshc->authed = TRUE; - infof(data, "Completed public key authentication"); - myssh_state(data, sshc, SSH_AUTH_DONE); - break; - } - else { - infof(data, "Failed public key authentication (rc: %d)", rc); - MOVE_TO_GSSAPI_AUTH; - } - break; + if(sshc->sftp_file) { + sftp_close(sshc->sftp_file); + sshc->sftp_file = NULL; + } - case SSH_AUTH_GSSAPI: - if(!(data->set.ssh_auth_types & CURLSSH_AUTH_GSSAPI)) { - MOVE_TO_KEY_AUTH; - break; - } + if(sshc->sftp_session) { + sftp_free(sshc->sftp_session); + sshc->sftp_session = NULL; + } - rc = ssh_userauth_gssapi(sshc->ssh_session); - if(rc == SSH_AUTH_AGAIN) { - rc = SSH_AGAIN; - break; - } + SSH_STRING_FREE_CHAR(sshc->homedir); - if(rc == SSH_AUTH_SUCCESS) { - rc = SSH_OK; - sshc->authed = TRUE; - infof(data, "Completed gssapi authentication"); - myssh_state(data, sshc, SSH_AUTH_DONE); - break; - } + myssh_to(data, sshc, SSH_SESSION_DISCONNECT); + return SSH_NO_ERROR; +} - MOVE_TO_KEY_AUTH; - break; +static int myssh_in_SFTP_INIT(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + int rc; + ssh_set_blocking(sshc->ssh_session, 1); - case SSH_AUTH_KEY_INIT: - if(data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) { - myssh_state(data, sshc, SSH_AUTH_KEY); - } - else { - MOVE_TO_PASSWD_AUTH; - } - break; + sshc->sftp_session = sftp_new(sshc->ssh_session); + if(!sshc->sftp_session) { + failf(data, "Failure initializing sftp session: %s", + ssh_get_error(sshc->ssh_session)); + return myssh_to_ERROR(data, sshc, CURLE_COULDNT_CONNECT); + } - case SSH_AUTH_KEY: - /* keyboard-interactive authentication */ - rc = myssh_auth_interactive(conn, sshc); - if(rc == SSH_AGAIN) { - break; - } - if(rc == SSH_OK) { - sshc->authed = TRUE; - infof(data, "completed keyboard interactive authentication"); - myssh_state(data, sshc, SSH_AUTH_DONE); - } - else { - MOVE_TO_PASSWD_AUTH; - } - break; + rc = sftp_init(sshc->sftp_session); + if(rc != SSH_OK) { + failf(data, "Failure initializing sftp session: %s", + ssh_get_error(sshc->ssh_session)); + return myssh_to_ERROR(data, sshc, sftp_error_to_CURLE(SSH_FX_FAILURE)); + } + myssh_to(data, sshc, SSH_SFTP_REALPATH); + return SSH_NO_ERROR; +} - case SSH_AUTH_PASS_INIT: - if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD)) { - MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); - break; - } - myssh_state(data, sshc, SSH_AUTH_PASS); - FALLTHROUGH(); +static int myssh_in_SFTP_REALPATH(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + /* Get the "home" directory */ + sshc->homedir = sftp_canonicalize_path(sshc->sftp_session, "."); + if(!sshc->homedir) + return myssh_to_ERROR(data, sshc, CURLE_COULDNT_CONNECT); + + free(data->state.most_recent_ftp_entrypath); + data->state.most_recent_ftp_entrypath = strdup(sshc->homedir); + if(!data->state.most_recent_ftp_entrypath) + return myssh_to_ERROR(data, sshc, CURLE_OUT_OF_MEMORY); + + /* This is the last step in the SFTP connect phase. Do note that while + we get the homedir here, we get the "workingpath" in the DO action + since the homedir will remain the same between request but the + working path will not. */ + DEBUGF(infof(data, "SSH CONNECT phase done")); + myssh_to(data, sshc, SSH_STOP); + return SSH_NO_ERROR; +} - case SSH_AUTH_PASS: - rc = ssh_userauth_password(sshc->ssh_session, NULL, conn->passwd); - if(rc == SSH_AUTH_AGAIN) { - rc = SSH_AGAIN; - break; - } +static int myssh_in_SFTP_QUOTE_INIT(struct Curl_easy *data, + struct ssh_conn *sshc, + struct SSHPROTO *sshp) +{ + CURLcode result = Curl_getworkingpath(data, sshc->homedir, &sshp->path); + if(result) { + sshc->actualcode = result; + myssh_to(data, sshc, SSH_STOP); + } + else if(data->set.quote) { + infof(data, "Sending quote commands"); + sshc->quote_item = data->set.quote; + myssh_to(data, sshc, SSH_SFTP_QUOTE); + } + else + myssh_to(data, sshc, SSH_SFTP_GETINFO); + return SSH_NO_ERROR; +} - if(rc == SSH_AUTH_SUCCESS) { - sshc->authed = TRUE; - infof(data, "Completed password authentication"); - myssh_state(data, sshc, SSH_AUTH_DONE); - } - else { - MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); - } - break; +static int myssh_in_SFTP_POSTQUOTE_INIT(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + if(data->set.postquote) { + infof(data, "Sending quote commands"); + sshc->quote_item = data->set.postquote; + myssh_to(data, sshc, SSH_SFTP_QUOTE); + } + else { + myssh_to(data, sshc, SSH_STOP); + } + return SSH_NO_ERROR; +} - case SSH_AUTH_DONE: - if(!sshc->authed) { - failf(data, "Authentication failure"); - MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); - break; - } +static int myssh_in_SFTP_QUOTE(struct Curl_easy *data, + struct ssh_conn *sshc, + struct SSHPROTO *sshp) +{ + const char *cp; + CURLcode result; - /* - * At this point we have an authenticated ssh session. - */ - infof(data, "Authentication complete"); + /* + * Support some of the "FTP" commands + */ + char *cmd = sshc->quote_item->data; + sshc->acceptfail = FALSE; - Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSH is connected */ + /* if a command starts with an asterisk, which a legal SFTP command never + can, the command will be allowed to fail without it causing any + aborts or cancels etc. It will cause libcurl to act as if the command + is successful, whatever the server responds. */ - conn->sockfd = sock; - conn->writesockfd = CURL_SOCKET_BAD; + if(cmd[0] == '*') { + cmd++; + sshc->acceptfail = TRUE; + } - if(conn->handler->protocol == CURLPROTO_SFTP) { - myssh_state(data, sshc, SSH_SFTP_INIT); - break; - } - infof(data, "SSH CONNECT phase done"); - myssh_state(data, sshc, SSH_STOP); - break; + if(curl_strequal("pwd", cmd)) { + /* output debug output if that is requested */ + char *tmp = aprintf("257 \"%s\" is current directory.\n", sshp->path); + if(!tmp) { + sshc->actualcode = CURLE_OUT_OF_MEMORY; + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + return SSH_NO_ERROR; + } + Curl_debug(data, CURLINFO_HEADER_OUT, "PWD\n", 4); + Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp)); - case SSH_SFTP_INIT: - ssh_set_blocking(sshc->ssh_session, 1); + /* this sends an FTP-like "header" to the header callback so that the + current directory can be read very similar to how it is read when + using ordinary FTP. */ + result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp)); + free(tmp); + if(result) { + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + } + else + myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); + return SSH_NO_ERROR; + } - sshc->sftp_session = sftp_new(sshc->ssh_session); - if(!sshc->sftp_session) { - failf(data, "Failure initializing sftp session: %s", - ssh_get_error(sshc->ssh_session)); - MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); - break; - } + /* + * the arguments following the command must be separated from the + * command with a space so we can check for it unconditionally + */ + cp = strchr(cmd, ' '); + if(!cp) { + failf(data, "Syntax error in SFTP command. Supply parameter(s)"); + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return SSH_NO_ERROR; + } - rc = sftp_init(sshc->sftp_session); - if(rc != SSH_OK) { - failf(data, "Failure initializing sftp session: %s", - ssh_get_error(sshc->ssh_session)); - MOVE_TO_ERROR_STATE(sftp_error_to_CURLE(SSH_FX_FAILURE)); + /* + * also, every command takes at least one argument so we get that + * first argument right now + */ + result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, "Syntax error: Bad first parameter"); + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + return SSH_NO_ERROR; + } + + /* + * SFTP is a binary protocol, so we do not send text commands + * to the server. Instead, we scan for commands used by + * OpenSSH's sftp program and call the appropriate libssh + * functions. + */ + if(!strncmp(cmd, "chgrp ", 6) || + !strncmp(cmd, "chmod ", 6) || + !strncmp(cmd, "chown ", 6) || + !strncmp(cmd, "atime ", 6) || + !strncmp(cmd, "mtime ", 6)) { + /* attribute change */ + + /* sshc->quote_path1 contains the mode to set */ + /* get the destination */ + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, "Syntax error in chgrp/chmod/chown/atime/mtime: " + "Bad second parameter"); + Curl_safefree(sshc->quote_path1); + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + return SSH_NO_ERROR; + } + sshc->quote_attrs = NULL; + myssh_to(data, sshc, SSH_SFTP_QUOTE_STAT); + return SSH_NO_ERROR; + } + if(!strncmp(cmd, "ln ", 3) || + !strncmp(cmd, "symlink ", 8)) { + /* symbolic linking */ + /* sshc->quote_path1 is the source */ + /* get the destination */ + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, "Syntax error in ln/symlink: Bad second parameter"); + Curl_safefree(sshc->quote_path1); + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + return SSH_NO_ERROR; + } + myssh_to(data, sshc, SSH_SFTP_QUOTE_SYMLINK); + return SSH_NO_ERROR; + } + else if(!strncmp(cmd, "mkdir ", 6)) { + /* create dir */ + myssh_to(data, sshc, SSH_SFTP_QUOTE_MKDIR); + return SSH_NO_ERROR; + } + else if(!strncmp(cmd, "rename ", 7)) { + /* rename file */ + /* first param is the source path */ + /* second param is the dest. path */ + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, "Syntax error in rename: Bad second parameter"); + Curl_safefree(sshc->quote_path1); + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + return SSH_NO_ERROR; + } + myssh_to(data, sshc, SSH_SFTP_QUOTE_RENAME); + return SSH_NO_ERROR; + } + else if(!strncmp(cmd, "rmdir ", 6)) { + /* delete dir */ + myssh_to(data, sshc, SSH_SFTP_QUOTE_RMDIR); + return SSH_NO_ERROR; + } + else if(!strncmp(cmd, "rm ", 3)) { + myssh_to(data, sshc, SSH_SFTP_QUOTE_UNLINK); + return SSH_NO_ERROR; + } +#ifdef HAS_STATVFS_SUPPORT + else if(!strncmp(cmd, "statvfs ", 8)) { + myssh_to(data, sshc, SSH_SFTP_QUOTE_STATVFS); + return SSH_NO_ERROR; + } +#endif + + failf(data, "Unknown SFTP command"); + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return SSH_NO_ERROR; +} + +static int myssh_in_SFTP_NEXT_QUOTE(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + + sshc->quote_item = sshc->quote_item->next; + + if(sshc->quote_item) { + myssh_to(data, sshc, SSH_SFTP_QUOTE); + } + else { + if(sshc->nextstate != SSH_NO_STATE) { + myssh_to(data, sshc, sshc->nextstate); + sshc->nextstate = SSH_NO_STATE; + } + else { + myssh_to(data, sshc, SSH_SFTP_GETINFO); + } + } + return SSH_NO_ERROR; +} + +static int myssh_in_SFTP_QUOTE_STAT(struct Curl_easy *data, + struct ssh_conn *sshc) +{ + char *cmd = sshc->quote_item->data; + sshc->acceptfail = FALSE; + + /* if a command starts with an asterisk, which a legal SFTP command never + can, the command will be allowed to fail without it causing any + aborts or cancels etc. It will cause libcurl to act as if the command + is successful, whatever the server responds. */ + + if(cmd[0] == '*') { + cmd++; + sshc->acceptfail = TRUE; + } + + /* We read the file attributes, store them in sshc->quote_attrs + * and modify them accordingly to command. Then we switch to + * QUOTE_SETSTAT state to write new ones. + */ + + if(sshc->quote_attrs) + sftp_attributes_free(sshc->quote_attrs); + sshc->quote_attrs = sftp_stat(sshc->sftp_session, sshc->quote_path2); + if(!sshc->quote_attrs) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Attempt to get SFTP stats failed: %d", + sftp_get_error(sshc->sftp_session)); + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return SSH_NO_ERROR; + } + + /* Now set the new attributes... */ + if(!strncmp(cmd, "chgrp", 5)) { + const char *p = sshc->quote_path1; + curl_off_t gid; + (void)curlx_str_number(&p, &gid, UINT_MAX); + sshc->quote_attrs->gid = (uint32_t)gid; + if(sshc->quote_attrs->gid == 0 && !ISDIGIT(sshc->quote_path1[0]) && + !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: chgrp gid not a number"); + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return SSH_NO_ERROR; + } + sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID; + } + else if(!strncmp(cmd, "chmod", 5)) { + curl_off_t perms; + const char *p = sshc->quote_path1; + if(curlx_str_octal(&p, &perms, 07777)) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: chmod permissions not a number"); + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return SSH_NO_ERROR; + } + sshc->quote_attrs->permissions = (mode_t)perms; + sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_PERMISSIONS; + } + else if(!strncmp(cmd, "chown", 5)) { + const char *p = sshc->quote_path1; + curl_off_t uid; + (void)curlx_str_number(&p, &uid, UINT_MAX); + if(sshc->quote_attrs->uid == 0 && !ISDIGIT(sshc->quote_path1[0]) && + !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: chown uid not a number"); + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return SSH_NO_ERROR; + } + sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID; + } + else if(!strncmp(cmd, "atime", 5) || + !strncmp(cmd, "mtime", 5)) { + time_t date = Curl_getdate_capped(sshc->quote_path1); + bool fail = FALSE; + if(date == -1) { + failf(data, "incorrect date format for %.*s", 5, cmd); + fail = TRUE; + } +#if SIZEOF_TIME_T > 4 + else if(date > 0xffffffff) { + failf(data, "date overflow"); + fail = TRUE; /* avoid setting a capped time */ + } +#endif + if(fail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + myssh_to(data, sshc, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return SSH_NO_ERROR; + } + if(!strncmp(cmd, "atime", 5)) + sshc->quote_attrs->atime = (uint32_t)date; + else /* mtime */ + sshc->quote_attrs->mtime = (uint32_t)date; + + sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_ACMODTIME; + } + + /* Now send the completed structure... */ + myssh_to(data, sshc, SSH_SFTP_QUOTE_SETSTAT); + return SSH_NO_ERROR; +} + +/* + * ssh_statemach_act() runs the SSH state machine as far as it can without + * blocking and without reaching the end. The data the pointer 'block' points + * to will be set to TRUE if the libssh function returns SSH_AGAIN + * meaning it wants to be called again when the socket is ready + */ +static CURLcode myssh_statemach_act(struct Curl_easy *data, + struct ssh_conn *sshc, + struct SSHPROTO *sshp, + bool *block) +{ + CURLcode result = CURLE_OK; + struct connectdata *conn = data->conn; + int rc = SSH_NO_ERROR, err; + const char *err_msg; + + *block = FALSE; /* we are not blocking by default */ + do { + + switch(sshc->state) { + case SSH_INIT: + myssh_state_init(data, sshc); + FALLTHROUGH(); + case SSH_S_STARTUP: + rc = myssh_in_S_STARTUP(data, sshc); + if(rc) break; - } - myssh_state(data, sshc, SSH_SFTP_REALPATH); FALLTHROUGH(); - case SSH_SFTP_REALPATH: - /* - * Get the "home" directory - */ - sshc->homedir = sftp_canonicalize_path(sshc->sftp_session, "."); - if(!sshc->homedir) { - MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); + case SSH_HOSTKEY: + rc = myssh_is_known(data, sshc); + if(rc != SSH_OK) { + rc = myssh_to_ERROR(data, sshc, CURLE_PEER_FAILED_VERIFICATION); break; } - free(data->state.most_recent_ftp_entrypath); - data->state.most_recent_ftp_entrypath = strdup(sshc->homedir); - if(!data->state.most_recent_ftp_entrypath) - return CURLE_OUT_OF_MEMORY; - - /* This is the last step in the SFTP connect phase. Do note that while - we get the homedir here, we get the "workingpath" in the DO action - since the homedir will remain the same between request but the - working path will not. */ - DEBUGF(infof(data, "SSH CONNECT phase done")); - myssh_state(data, sshc, SSH_STOP); + myssh_to(data, sshc, SSH_AUTHLIST); + FALLTHROUGH(); + case SSH_AUTHLIST: + rc = myssh_in_AUTHLIST(data, sshc); break; - - case SSH_SFTP_QUOTE_INIT: - result = Curl_getworkingpath(data, sshc->homedir, &sshp->path); - if(result) { - sshc->actualcode = result; - myssh_state(data, sshc, SSH_STOP); - break; - } - - if(data->set.quote) { - infof(data, "Sending quote commands"); - sshc->quote_item = data->set.quote; - myssh_state(data, sshc, SSH_SFTP_QUOTE); - } - else { - myssh_state(data, sshc, SSH_SFTP_GETINFO); - } + case SSH_AUTH_PKEY_INIT: + rc = myssh_in_AUTH_PKEY_INIT(data, sshc); + break; + case SSH_AUTH_PKEY: + rc = myssh_in_AUTH_PKEY(data, sshc); + break; + case SSH_AUTH_GSSAPI: + rc = myssh_in_AUTH_GSSAPI(data, sshc); + break; + case SSH_AUTH_KEY_INIT: + rc = myssh_in_AUTH_KEY_INIT(data, sshc); + break; + case SSH_AUTH_KEY: + rc = myssh_in_AUTH_KEY(data, sshc); + break; + case SSH_AUTH_PASS_INIT: + rc = myssh_in_AUTH_PASS_INIT(data, sshc); + break; + case SSH_AUTH_PASS: + rc = myssh_in_AUTH_PASS(data, sshc); + break; + case SSH_AUTH_DONE: + rc = myssh_in_AUTH_DONE(data, sshc); + break; + case SSH_SFTP_INIT: + rc = myssh_in_SFTP_INIT(data, sshc); + break; + case SSH_SFTP_REALPATH: + rc = myssh_in_SFTP_REALPATH(data, sshc); + break; + case SSH_SFTP_QUOTE_INIT: + rc = myssh_in_SFTP_QUOTE_INIT(data, sshc, sshp); break; - case SSH_SFTP_POSTQUOTE_INIT: - if(data->set.postquote) { - infof(data, "Sending quote commands"); - sshc->quote_item = data->set.postquote; - myssh_state(data, sshc, SSH_SFTP_QUOTE); - } - else { - myssh_state(data, sshc, SSH_STOP); - } + rc = myssh_in_SFTP_POSTQUOTE_INIT(data, sshc); break; - case SSH_SFTP_QUOTE: - /* Send any quote commands */ - sftp_quote(data, sshc, sshp); + rc = myssh_in_SFTP_QUOTE(data, sshc, sshp); break; - case SSH_SFTP_NEXT_QUOTE: - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - - sshc->quote_item = sshc->quote_item->next; - - if(sshc->quote_item) { - myssh_state(data, sshc, SSH_SFTP_QUOTE); - } - else { - if(sshc->nextstate != SSH_NO_STATE) { - myssh_state(data, sshc, sshc->nextstate); - sshc->nextstate = SSH_NO_STATE; - } - else { - myssh_state(data, sshc, SSH_SFTP_GETINFO); - } - } + rc = myssh_in_SFTP_NEXT_QUOTE(data, sshc); break; - case SSH_SFTP_QUOTE_STAT: - sftp_quote_stat(data, sshc); + rc = myssh_in_SFTP_QUOTE_STAT(data, sshc); break; case SSH_SFTP_QUOTE_SETSTAT: @@ -1340,7 +1981,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, Curl_safefree(sshc->quote_path2); failf(data, "Attempt to set SFTP stats failed: %s", ssh_get_error(sshc->ssh_session)); - myssh_state(data, sshc, SSH_SFTP_CLOSE); + myssh_to(data, sshc, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; /* sshc->actualcode = sftp_error_to_CURLE(err); @@ -1348,7 +1989,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, * the error the libssh2 backend is returning */ break; } - myssh_state(data, sshc, SSH_SFTP_NEXT_QUOTE); + myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); break; case SSH_SFTP_QUOTE_SYMLINK: @@ -1359,12 +2000,12 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, Curl_safefree(sshc->quote_path2); failf(data, "symlink command failed: %s", ssh_get_error(sshc->ssh_session)); - myssh_state(data, sshc, SSH_SFTP_CLOSE); + myssh_to(data, sshc, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; } - myssh_state(data, sshc, SSH_SFTP_NEXT_QUOTE); + myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); break; case SSH_SFTP_QUOTE_MKDIR: @@ -1374,12 +2015,12 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, Curl_safefree(sshc->quote_path1); failf(data, "mkdir command failed: %s", ssh_get_error(sshc->ssh_session)); - myssh_state(data, sshc, SSH_SFTP_CLOSE); + myssh_to(data, sshc, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; } - myssh_state(data, sshc, SSH_SFTP_NEXT_QUOTE); + myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); break; case SSH_SFTP_QUOTE_RENAME: @@ -1390,12 +2031,12 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, Curl_safefree(sshc->quote_path2); failf(data, "rename command failed: %s", ssh_get_error(sshc->ssh_session)); - myssh_state(data, sshc, SSH_SFTP_CLOSE); + myssh_to(data, sshc, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; } - myssh_state(data, sshc, SSH_SFTP_NEXT_QUOTE); + myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); break; case SSH_SFTP_QUOTE_RMDIR: @@ -1404,12 +2045,12 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, Curl_safefree(sshc->quote_path1); failf(data, "rmdir command failed: %s", ssh_get_error(sshc->ssh_session)); - myssh_state(data, sshc, SSH_SFTP_CLOSE); + myssh_to(data, sshc, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; } - myssh_state(data, sshc, SSH_SFTP_NEXT_QUOTE); + myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); break; case SSH_SFTP_QUOTE_UNLINK: @@ -1418,84 +2059,28 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, Curl_safefree(sshc->quote_path1); failf(data, "rm command failed: %s", ssh_get_error(sshc->ssh_session)); - myssh_state(data, sshc, SSH_SFTP_CLOSE); + myssh_to(data, sshc, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; } - myssh_state(data, sshc, SSH_SFTP_NEXT_QUOTE); + myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); break; case SSH_SFTP_QUOTE_STATVFS: - { - sftp_statvfs_t statvfs; - - statvfs = sftp_statvfs(sshc->sftp_session, sshc->quote_path1); - if(!statvfs && !sshc->acceptfail) { - Curl_safefree(sshc->quote_path1); - failf(data, "statvfs command failed: %s", - ssh_get_error(sshc->ssh_session)); - myssh_state(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - else if(statvfs) { - #ifdef _MSC_VER - #define CURL_LIBSSH_VFS_SIZE_MASK "I64u" - #else - #define CURL_LIBSSH_VFS_SIZE_MASK PRIu64 - #endif - char *tmp = aprintf("statvfs:\n" - "f_bsize: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_frsize: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_blocks: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_bfree: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_bavail: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_files: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_ffree: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_favail: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_fsid: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_flag: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_namemax: %" CURL_LIBSSH_VFS_SIZE_MASK "\n", - statvfs->f_bsize, statvfs->f_frsize, - statvfs->f_blocks, statvfs->f_bfree, - statvfs->f_bavail, statvfs->f_files, - statvfs->f_ffree, statvfs->f_favail, - statvfs->f_fsid, statvfs->f_flag, - statvfs->f_namemax); - sftp_statvfs_free(statvfs); - - if(!tmp) { - result = CURLE_OUT_OF_MEMORY; - myssh_state(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - break; - } - - result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp)); - free(tmp); - if(result) { - myssh_state(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - } - } - myssh_state(data, sshc, SSH_SFTP_NEXT_QUOTE); + rc = myssh_in_SFTP_QUOTE_STATVFS(data, sshc); break; - } case SSH_SFTP_GETINFO: if(data->set.get_filetime) { - myssh_state(data, sshc, SSH_SFTP_FILETIME); + myssh_to(data, sshc, SSH_SFTP_FILETIME); } else { - myssh_state(data, sshc, SSH_SFTP_TRANS_INIT); + myssh_to(data, sshc, SSH_SFTP_TRANS_INIT); } break; - case SSH_SFTP_FILETIME: - { + case SSH_SFTP_FILETIME: { sftp_attributes attrs; attrs = sftp_stat(sshc->sftp_session, sshp->path); @@ -1504,32 +2089,32 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, sftp_attributes_free(attrs); } - myssh_state(data, sshc, SSH_SFTP_TRANS_INIT); + myssh_to(data, sshc, SSH_SFTP_TRANS_INIT); break; } case SSH_SFTP_TRANS_INIT: if(data->state.upload) - myssh_state(data, sshc, SSH_SFTP_UPLOAD_INIT); + myssh_to(data, sshc, SSH_SFTP_UPLOAD_INIT); else { if(sshp->path[strlen(sshp->path)-1] == '/') - myssh_state(data, sshc, SSH_SFTP_READDIR_INIT); + myssh_to(data, sshc, SSH_SFTP_READDIR_INIT); else - myssh_state(data, sshc, SSH_SFTP_DOWNLOAD_INIT); + myssh_to(data, sshc, SSH_SFTP_DOWNLOAD_INIT); } break; case SSH_SFTP_UPLOAD_INIT: - rc = myssh_state_upload_init(data, sshc, sshp); + rc = myssh_in_UPLOAD_INIT(data, sshc, sshp); break; case SSH_SFTP_CREATE_DIRS_INIT: if(strlen(sshp->path) > 1) { sshc->slash_pos = sshp->path + 1; /* ignore the leading '/' */ - myssh_state(data, sshc, SSH_SFTP_CREATE_DIRS); + myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS); } else { - myssh_state(data, sshc, SSH_SFTP_UPLOAD_INIT); + myssh_to(data, sshc, SSH_SFTP_UPLOAD_INIT); } break; @@ -1539,10 +2124,10 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, *sshc->slash_pos = 0; infof(data, "Creating directory '%s'", sshp->path); - myssh_state(data, sshc, SSH_SFTP_CREATE_DIRS_MKDIR); + myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS_MKDIR); break; } - myssh_state(data, sshc, SSH_SFTP_UPLOAD_INIT); + myssh_to(data, sshc, SSH_SFTP_UPLOAD_INIT); break; case SSH_SFTP_CREATE_DIRS_MKDIR: @@ -1561,254 +2146,47 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, if((err != SSH_FX_FILE_ALREADY_EXISTS) && (err != SSH_FX_FAILURE) && (err != SSH_FX_PERMISSION_DENIED)) { - MOVE_TO_SFTP_CLOSE_STATE(); + rc = myssh_to_SFTP_CLOSE(data, sshc); break; } rc = 0; /* clear rc and continue */ } - myssh_state(data, sshc, SSH_SFTP_CREATE_DIRS); + myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS); break; case SSH_SFTP_READDIR_INIT: - Curl_pgrsSetDownloadSize(data, -1); - if(data->req.no_body) { - myssh_state(data, sshc, SSH_STOP); - break; - } - - /* - * This is a directory that we are trying to get, so produce a directory - * listing - */ - sshc->sftp_dir = sftp_opendir(sshc->sftp_session, - sshp->path); - if(!sshc->sftp_dir) { - failf(data, "Could not open directory for reading: %s", - ssh_get_error(sshc->ssh_session)); - MOVE_TO_SFTP_CLOSE_STATE(); - break; - } - myssh_state(data, sshc, SSH_SFTP_READDIR); + rc = myssh_in_SFTP_READDIR_INIT(data, sshc, sshp); break; - case SSH_SFTP_READDIR: - curlx_dyn_reset(&sshc->readdir_buf); - if(sshc->readdir_attrs) - sftp_attributes_free(sshc->readdir_attrs); - - sshc->readdir_attrs = sftp_readdir(sshc->sftp_session, sshc->sftp_dir); - if(sshc->readdir_attrs) { - sshc->readdir_filename = sshc->readdir_attrs->name; - sshc->readdir_longentry = sshc->readdir_attrs->longname; - sshc->readdir_len = strlen(sshc->readdir_filename); - - if(data->set.list_only) { - char *tmpLine; - - tmpLine = aprintf("%s\n", sshc->readdir_filename); - if(!tmpLine) { - myssh_state(data, sshc, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - break; - } - result = Curl_client_write(data, CLIENTWRITE_BODY, - tmpLine, sshc->readdir_len + 1); - free(tmpLine); - - if(result) { - myssh_state(data, sshc, SSH_STOP); - break; - } - - } - else { - if(curlx_dyn_add(&sshc->readdir_buf, sshc->readdir_longentry)) { - sshc->actualcode = CURLE_OUT_OF_MEMORY; - myssh_state(data, sshc, SSH_STOP); - break; - } - - if((sshc->readdir_attrs->flags & SSH_FILEXFER_ATTR_PERMISSIONS) && - ((sshc->readdir_attrs->permissions & SSH_S_IFMT) == - SSH_S_IFLNK)) { - sshc->readdir_linkPath = aprintf("%s%s", sshp->path, - sshc->readdir_filename); - - if(!sshc->readdir_linkPath) { - myssh_state(data, sshc, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - break; - } - - myssh_state(data, sshc, SSH_SFTP_READDIR_LINK); - break; - } - myssh_state(data, sshc, SSH_SFTP_READDIR_BOTTOM); - break; - } - } - else if(sftp_dir_eof(sshc->sftp_dir)) { - myssh_state(data, sshc, SSH_SFTP_READDIR_DONE); - break; - } - else { - failf(data, "Could not open remote file for reading: %s", - ssh_get_error(sshc->ssh_session)); - MOVE_TO_SFTP_CLOSE_STATE(); - break; - } + rc = myssh_in_SFTP_READDIR(data, sshc, sshp); break; - case SSH_SFTP_READDIR_LINK: - if(sshc->readdir_link_attrs) - sftp_attributes_free(sshc->readdir_link_attrs); - - sshc->readdir_link_attrs = sftp_lstat(sshc->sftp_session, - sshc->readdir_linkPath); - if(sshc->readdir_link_attrs == 0) { - failf(data, "Could not read symlink for reading: %s", - ssh_get_error(sshc->ssh_session)); - MOVE_TO_SFTP_CLOSE_STATE(); - break; - } - - if(!sshc->readdir_link_attrs->name) { - sshc->readdir_tmp = sftp_readlink(sshc->sftp_session, - sshc->readdir_linkPath); - if(!sshc->readdir_filename) - sshc->readdir_len = 0; - else - sshc->readdir_len = strlen(sshc->readdir_tmp); - sshc->readdir_longentry = NULL; - sshc->readdir_filename = sshc->readdir_tmp; - } - else { - sshc->readdir_len = strlen(sshc->readdir_link_attrs->name); - sshc->readdir_filename = sshc->readdir_link_attrs->name; - sshc->readdir_longentry = sshc->readdir_link_attrs->longname; - } - - Curl_safefree(sshc->readdir_linkPath); - - if(curlx_dyn_addf(&sshc->readdir_buf, " -> %s", - sshc->readdir_filename)) { - sshc->actualcode = CURLE_OUT_OF_MEMORY; - break; - } - - sftp_attributes_free(sshc->readdir_link_attrs); - sshc->readdir_link_attrs = NULL; - sshc->readdir_filename = NULL; - sshc->readdir_longentry = NULL; - - myssh_state(data, sshc, SSH_SFTP_READDIR_BOTTOM); - FALLTHROUGH(); + rc = myssh_in_SFTP_READDIR_LINK(data, sshc); + break; case SSH_SFTP_READDIR_BOTTOM: - if(curlx_dyn_addn(&sshc->readdir_buf, "\n", 1)) - result = CURLE_OUT_OF_MEMORY; - else - result = Curl_client_write(data, CLIENTWRITE_BODY, - curlx_dyn_ptr(&sshc->readdir_buf), - curlx_dyn_len(&sshc->readdir_buf)); - - ssh_string_free_char(sshc->readdir_tmp); - sshc->readdir_tmp = NULL; - - if(result) { - myssh_state(data, sshc, SSH_STOP); - } - else - myssh_state(data, sshc, SSH_SFTP_READDIR); + rc = myssh_in_SFTP_READDIR_BOTTOM(data, sshc); break; - case SSH_SFTP_READDIR_DONE: - sftp_closedir(sshc->sftp_dir); - sshc->sftp_dir = NULL; - - /* no data to transfer */ - Curl_xfer_setup_nop(data); - myssh_state(data, sshc, SSH_STOP); + rc = myssh_in_SFTP_READDIR_DONE(data, sshc); break; - case SSH_SFTP_DOWNLOAD_INIT: - /* - * Work on getting the specified file - */ - if(sshc->sftp_file) - sftp_close(sshc->sftp_file); - - sshc->sftp_file = sftp_open(sshc->sftp_session, sshp->path, - O_RDONLY, (mode_t)data->set.new_file_perms); - if(!sshc->sftp_file) { - failf(data, "Could not open remote file for reading: %s", - ssh_get_error(sshc->ssh_session)); - - MOVE_TO_SFTP_CLOSE_STATE(); - break; - } - sftp_file_set_nonblocking(sshc->sftp_file); - myssh_state(data, sshc, SSH_SFTP_DOWNLOAD_STAT); + rc = myssh_in_SFTP_DOWNLOAD_INIT(data, sshc, sshp); break; - case SSH_SFTP_DOWNLOAD_STAT: - rc = myssh_state_sftp_download_stat(data, sshc); + rc = myssh_in_SFTP_DOWNLOAD_STAT(data, sshc); break; - case SSH_SFTP_CLOSE: - if(sshc->sftp_file) { - sftp_close(sshc->sftp_file); - sshc->sftp_file = NULL; - } - Curl_safefree(sshp->path); - - DEBUGF(infof(data, "SFTP DONE done")); - - /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT - After nextstate is executed, the control should come back to - SSH_SFTP_CLOSE to pass the correct result back */ - if(sshc->nextstate != SSH_NO_STATE && - sshc->nextstate != SSH_SFTP_CLOSE) { - myssh_state(data, sshc, sshc->nextstate); - sshc->nextstate = SSH_SFTP_CLOSE; - } - else { - myssh_state(data, sshc, SSH_STOP); - result = sshc->actualcode; - } + rc = myssh_in_SFTP_CLOSE(data, sshc, sshp); break; - case SSH_SFTP_SHUTDOWN: - /* during times we get here due to a broken transfer and then the - sftp_handle might not have been taken down so make sure that is done - before we proceed */ - ssh_set_blocking(sshc->ssh_session, 0); -#if LIBSSH_VERSION_INT > SSH_VERSION_INT(0, 11, 0) - if(sshc->sftp_aio) { - sftp_aio_free(sshc->sftp_aio); - sshc->sftp_aio = NULL; - } -#endif - - if(sshc->sftp_file) { - sftp_close(sshc->sftp_file); - sshc->sftp_file = NULL; - } - - if(sshc->sftp_session) { - sftp_free(sshc->sftp_session); - sshc->sftp_session = NULL; - } - - SSH_STRING_FREE_CHAR(sshc->homedir); - - myssh_state(data, sshc, SSH_SESSION_DISCONNECT); + rc = myssh_in_SFTP_SHUTDOWN(data, sshc); break; case SSH_SCP_TRANS_INIT: result = Curl_getworkingpath(data, sshc->homedir, &sshp->path); if(result) { sshc->actualcode = result; - myssh_state(data, sshc, SSH_STOP); + myssh_to(data, sshc, SSH_STOP); break; } @@ -1819,26 +2197,25 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, if(data->state.infilesize < 0) { failf(data, "SCP requires a known file size for upload"); sshc->actualcode = CURLE_UPLOAD_FAILED; - MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + rc = myssh_to_ERROR(data, sshc, CURLE_UPLOAD_FAILED); break; } sshc->scp_session = ssh_scp_new(sshc->ssh_session, SSH_SCP_WRITE, sshp->path); - myssh_state(data, sshc, SSH_SCP_UPLOAD_INIT); + myssh_to(data, sshc, SSH_SCP_UPLOAD_INIT); } else { sshc->scp_session = ssh_scp_new(sshc->ssh_session, SSH_SCP_READ, sshp->path); - myssh_state(data, sshc, SSH_SCP_DOWNLOAD_INIT); + myssh_to(data, sshc, SSH_SCP_DOWNLOAD_INIT); } if(!sshc->scp_session) { err_msg = ssh_get_error(sshc->ssh_session); failf(data, "%s", err_msg); - MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + rc = myssh_to_ERROR(data, sshc, CURLE_UPLOAD_FAILED); } - break; case SSH_SCP_UPLOAD_INIT: @@ -1847,7 +2224,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, if(rc != SSH_OK) { err_msg = ssh_get_error(sshc->ssh_session); failf(data, "%s", err_msg); - MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + rc = myssh_to_ERROR(data, sshc, CURLE_UPLOAD_FAILED); break; } @@ -1858,26 +2235,21 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, if(rc != SSH_OK) { err_msg = ssh_get_error(sshc->ssh_session); failf(data, "%s", err_msg); - MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + rc = myssh_to_ERROR(data, sshc, CURLE_UPLOAD_FAILED); break; } /* upload data */ - Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE); + Curl_xfer_setup_send(data, FIRSTSOCKET); /* not set by Curl_xfer_setup to preserve keepon bits */ - conn->sockfd = conn->writesockfd; + data->conn->recv_idx = FIRSTSOCKET; /* store this original bitmask setup to use later on if we cannot figure out a "real" bitmask */ sshc->orig_waitfor = data->req.keepon; - /* we want to use the _sending_ function even when the socket turns - out readable as the underlying libssh scp send function will deal - with both accordingly */ - data->state.select_bits = CURL_CSELECT_OUT; - - myssh_state(data, sshc, SSH_STOP); + myssh_to(data, sshc, SSH_STOP); break; @@ -1887,44 +2259,39 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, if(rc != SSH_OK) { err_msg = ssh_get_error(sshc->ssh_session); failf(data, "%s", err_msg); - MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); + rc = myssh_to_ERROR(data, sshc, CURLE_COULDNT_CONNECT); break; } - myssh_state(data, sshc, SSH_SCP_DOWNLOAD); + myssh_to(data, sshc, SSH_SCP_DOWNLOAD); FALLTHROUGH(); - case SSH_SCP_DOWNLOAD:{ + case SSH_SCP_DOWNLOAD: { curl_off_t bytecount; rc = ssh_scp_pull_request(sshc->scp_session); if(rc != SSH_SCP_REQUEST_NEWFILE) { err_msg = ssh_get_error(sshc->ssh_session); failf(data, "%s", err_msg); - MOVE_TO_ERROR_STATE(CURLE_REMOTE_FILE_NOT_FOUND); + rc = myssh_to_ERROR(data, sshc, CURLE_REMOTE_FILE_NOT_FOUND); break; } /* download data */ bytecount = ssh_scp_request_get_size(sshc->scp_session); data->req.maxdownload = (curl_off_t) bytecount; - Curl_xfer_setup1(data, CURL_XFER_RECV, bytecount, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, bytecount); /* not set by Curl_xfer_setup to preserve keepon bits */ - conn->writesockfd = conn->sockfd; + conn->send_idx = 0; - /* we want to use the _receiving_ function even when the socket turns - out writableable as the underlying libssh recv function will deal - with both accordingly */ - data->state.select_bits = CURL_CSELECT_IN; - - myssh_state(data, sshc, SSH_STOP); + myssh_to(data, sshc, SSH_STOP); break; - } + } case SSH_SCP_DONE: if(data->state.upload) - myssh_state(data, sshc, SSH_SCP_SEND_EOF); + myssh_to(data, sshc, SSH_SCP_SEND_EOF); else - myssh_state(data, sshc, SSH_SCP_CHANNEL_FREE); + myssh_to(data, sshc, SSH_SCP_CHANNEL_FREE); break; case SSH_SCP_SEND_EOF: @@ -1942,7 +2309,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, } } - myssh_state(data, sshc, SSH_SCP_CHANNEL_FREE); + myssh_to(data, sshc, SSH_SCP_CHANNEL_FREE); break; case SSH_SCP_CHANNEL_FREE: @@ -1954,7 +2321,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, ssh_set_blocking(sshc->ssh_session, 0); - myssh_state(data, sshc, SSH_SESSION_DISCONNECT); + myssh_to(data, sshc, SSH_SESSION_DISCONNECT); FALLTHROUGH(); case SSH_SESSION_DISCONNECT: @@ -1985,7 +2352,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, SSH_STRING_FREE_CHAR(sshc->homedir); - myssh_state(data, sshc, SSH_SESSION_FREE); + myssh_to(data, sshc, SSH_SESSION_FREE); FALLTHROUGH(); case SSH_SESSION_FREE: sshc_cleanup(sshc); @@ -1995,14 +2362,14 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, connclose(conn, "SSH session free"); sshc->state = SSH_SESSION_FREE; /* current */ sshc->nextstate = SSH_NO_STATE; - myssh_state(data, sshc, SSH_STOP); + myssh_to(data, sshc, SSH_STOP); break; case SSH_QUIT: default: /* internal error */ sshc->nextstate = SSH_NO_STATE; - myssh_state(data, sshc, SSH_STOP); + myssh_to(data, sshc, SSH_STOP); break; } @@ -2014,32 +2381,28 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, right direction too)! */ *block = TRUE; } - + if(!result && (sshc->state == SSH_STOP)) + result = sshc->actualcode; + DEBUGF(infof(data, "SSH: myssh_statemach_act -> %d", result)); return result; } /* called by the multi interface to figure out what socket(s) to wait for and for what actions in the DO_DONE, PERFORM and WAITPERFORM states */ -static int myssh_getsock(struct Curl_easy *data, - struct connectdata *conn, - curl_socket_t *sock) +static CURLcode myssh_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { - int bitmap = GETSOCK_BLANK; - (void)data; - sock[0] = conn->sock[FIRSTSOCKET]; - - if(conn->waitfor & KEEP_RECV) - bitmap |= GETSOCK_READSOCK(FIRSTSOCKET); - - if(conn->waitfor & KEEP_SEND) - bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET); - - if(!conn->waitfor) - bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET); - - DEBUGF(infof(data, "ssh_getsock -> %x", bitmap)); - return bitmap; + int flags = 0; + if(data->conn->waitfor & KEEP_RECV) + flags |= CURL_POLL_IN; + if(data->conn->waitfor & KEEP_SEND) + flags |= CURL_POLL_OUT; + if(!data->conn->waitfor) + flags |= CURL_POLL_OUT; + return flags ? + Curl_pollset_change(data, ps, data->conn->sock[FIRSTSOCKET], flags, 0) : + CURLE_OK; } static void myssh_block2waitfor(struct connectdata *conn, @@ -2068,7 +2431,7 @@ static CURLcode myssh_multi_statemach(struct Curl_easy *data, struct connectdata *conn = data->conn; struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY); - bool block; /* we store the status and use that to provide a ssh_getsock() + bool block; /* we store the status and use that to provide a ssh_pollset() implementation */ CURLcode result; @@ -2116,8 +2479,8 @@ static CURLcode myssh_block_statemach(struct Curl_easy *data, if(block) { curl_socket_t fd_read = conn->sock[FIRSTSOCKET]; /* wait for the socket to become ready */ - (void) Curl_socket_check(fd_read, CURL_SOCKET_BAD, - CURL_SOCKET_BAD, left > 1000 ? 1000 : left); + (void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, + CURL_SOCKET_BAD, left > 1000 ? 1000 : left); } } @@ -2284,7 +2647,7 @@ static CURLcode myssh_connect(struct Curl_easy *data, bool *done) /* we do not verify here, we do it at the state machine, * after connection */ - myssh_state(data, sshc, SSH_INIT); + myssh_to(data, sshc, SSH_INIT); result = myssh_multi_statemach(data, done); @@ -2327,7 +2690,7 @@ CURLcode scp_perform(struct Curl_easy *data, return CURLE_FAILED_INIT; /* start the first command in the DO phase */ - myssh_state(data, sshc, SSH_SCP_TRANS_INIT); + myssh_to(data, sshc, SSH_SCP_TRANS_INIT); result = myssh_multi_statemach(data, dophase_done); @@ -2436,12 +2799,12 @@ static CURLcode scp_disconnect(struct Curl_easy *data, CURLcode result = CURLE_OK; struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY); - (void) dead_connection; + (void)dead_connection; if(sshc && sshc->ssh_session && sshp) { /* only if there is a session still around to use! */ - myssh_state(data, sshc, SSH_SESSION_DISCONNECT); + myssh_to(data, sshc, SSH_SESSION_DISCONNECT); result = myssh_block_statemach(data, sshc, sshp, TRUE); } @@ -2477,29 +2840,30 @@ static CURLcode scp_done(struct Curl_easy *data, CURLcode status, bool premature) { struct ssh_conn *sshc = Curl_conn_meta_get(data->conn, CURL_META_SSH_CONN); - (void) premature; /* not used */ + (void)premature; /* not used */ if(!sshc) return CURLE_FAILED_INIT; if(!status) - myssh_state(data, sshc, SSH_SCP_DONE); + myssh_to(data, sshc, SSH_SCP_DONE); return myssh_done(data, sshc, status); } -static ssize_t scp_send(struct Curl_easy *data, int sockindex, - const void *mem, size_t len, bool eos, CURLcode *err) +static CURLcode scp_send(struct Curl_easy *data, int sockindex, + const void *mem, size_t len, bool eos, + size_t *pnwritten) { int rc; struct connectdata *conn = data->conn; struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - (void) sockindex; /* we only support SCP on the fixed known primary socket */ + + (void)sockindex; /* we only support SCP on the fixed known primary socket */ (void)eos; + *pnwritten = 0; - if(!sshc) { - *err = CURLE_FAILED_INIT; - return -1; - } + if(!sshc) + return CURLE_FAILED_INIT; rc = ssh_scp_write(sshc->scp_session, mem, len); @@ -2509,32 +2873,30 @@ static ssize_t scp_send(struct Curl_easy *data, int sockindex, * Currently rc can only be number of bytes read or SSH_ERROR. */ myssh_block2waitfor(conn, sshc, (rc == SSH_AGAIN)); - if(rc == SSH_AGAIN) { - *err = CURLE_AGAIN; - return 0; - } + if(rc == SSH_AGAIN) + return CURLE_AGAIN; else #endif - if(rc != SSH_OK) { - *err = CURLE_SSH; - return -1; - } + if(rc != SSH_OK) + return CURLE_SSH; - return len; + *pnwritten = len; + return CURLE_OK; } -static ssize_t scp_recv(struct Curl_easy *data, int sockindex, - char *mem, size_t len, CURLcode *err) +static CURLcode scp_recv(struct Curl_easy *data, int sockindex, + char *mem, size_t len, size_t *pnread) { - ssize_t nread; struct connectdata *conn = data->conn; struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - (void) sockindex; /* we only support SCP on the fixed known primary socket */ + ssize_t nread; + + (void)sockindex; /* we only support SCP on the fixed known primary socket */ + *pnread = 0; + + if(!sshc) + return CURLE_FAILED_INIT; - if(!sshc) { - *err = CURLE_FAILED_INIT; - return -1; - } /* libssh returns int */ nread = ssh_scp_read(sshc->scp_session, mem, len); @@ -2544,13 +2906,11 @@ static ssize_t scp_recv(struct Curl_easy *data, int sockindex, * Currently rc can only be SSH_OK or SSH_ERROR. */ myssh_block2waitfor(conn, sshc, (nread == SSH_AGAIN)); - if(nread == SSH_AGAIN) { - *err = CURLE_AGAIN; - nread = -1; - } + if(nread == SSH_AGAIN) + return CURLE_AGAIN; #endif - - return nread; + *pnread = (size_t)nread; + return CURLE_OK; } /* @@ -2581,7 +2941,7 @@ CURLcode sftp_perform(struct Curl_easy *data, return CURLE_FAILED_INIT; /* start the first command in the DO phase */ - myssh_state(data, sshc, SSH_SFTP_QUOTE_INIT); + myssh_to(data, sshc, SSH_SFTP_QUOTE_INIT); /* run the state-machine */ result = myssh_multi_statemach(data, dophase_done); @@ -2616,13 +2976,13 @@ static CURLcode sftp_disconnect(struct Curl_easy *data, struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY); CURLcode result = CURLE_OK; - (void) dead_connection; + (void)dead_connection; DEBUGF(infof(data, "SSH DISCONNECT starts now")); if(sshc && sshc->ssh_session && sshp) { /* only if there is a session still around to use! */ - myssh_state(data, sshc, SSH_SFTP_SHUTDOWN); + myssh_to(data, sshc, SSH_SFTP_SHUTDOWN); result = myssh_block_statemach(data, sshc, sshp, TRUE); } @@ -2644,435 +3004,156 @@ static CURLcode sftp_done(struct Curl_easy *data, CURLcode status, operation */ if(!premature && data->set.postquote && !conn->bits.retry) sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT; - myssh_state(data, sshc, SSH_SFTP_CLOSE); + myssh_to(data, sshc, SSH_SFTP_CLOSE); } return myssh_done(data, sshc, status); } /* return number of sent bytes */ -static ssize_t sftp_send(struct Curl_easy *data, int sockindex, - const void *mem, size_t len, bool eos, - CURLcode *err) +static CURLcode sftp_send(struct Curl_easy *data, int sockindex, + const void *mem, size_t len, bool eos, + size_t *pnwritten) { - ssize_t nwrite; struct connectdata *conn = data->conn; struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); + ssize_t nwrite; + (void)sockindex; (void)eos; + *pnwritten = 0; + + if(!sshc) + return CURLE_FAILED_INIT; - if(!sshc) { - *err = CURLE_FAILED_INIT; - return -1; - } - /* limit the writes to the maximum specified in Section 3 of - * https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02 - */ - if(len > 32768) - len = 32768; #if LIBSSH_VERSION_INT > SSH_VERSION_INT(0, 11, 0) switch(sshc->sftp_send_state) { case 0: sftp_file_set_nonblocking(sshc->sftp_file); if(sftp_aio_begin_write(sshc->sftp_file, mem, len, - &sshc->sftp_aio) == SSH_ERROR) { - *err = CURLE_SEND_ERROR; - return -1; + &sshc->sftp_send_aio) == SSH_ERROR) { + return CURLE_SEND_ERROR; } sshc->sftp_send_state = 1; FALLTHROUGH(); case 1: - nwrite = sftp_aio_wait_write(&sshc->sftp_aio); + nwrite = sftp_aio_wait_write(&sshc->sftp_send_aio); myssh_block2waitfor(conn, sshc, (nwrite == SSH_AGAIN) ? TRUE : FALSE); - if(nwrite == SSH_AGAIN) { - *err = CURLE_AGAIN; - return 0; - } - else if(nwrite < 0) { - *err = CURLE_SEND_ERROR; - return -1; - } - if(sshc->sftp_aio) { - sftp_aio_free(sshc->sftp_aio); - sshc->sftp_aio = NULL; - } - sshc->sftp_send_state = 0; - return nwrite; - default: - /* we never reach here */ - return -1; - } -#else - nwrite = sftp_write(sshc->sftp_file, mem, len); - - myssh_block2waitfor(conn, sshc, FALSE); - -#if 0 /* not returned by libssh on write */ - if(nwrite == SSH_AGAIN) { - *err = CURLE_AGAIN; - nwrite = 0; - } - else -#endif - if(nwrite < 0) { - *err = CURLE_SSH; - nwrite = -1; - } - - return nwrite; -#endif -} - -/* - * Return number of received (decrypted) bytes - * or <0 on error - */ -static ssize_t sftp_recv(struct Curl_easy *data, int sockindex, - char *mem, size_t len, CURLcode *err) -{ - ssize_t nread; - struct connectdata *conn = data->conn; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - (void)sockindex; - - DEBUGASSERT(len < CURL_MAX_READ_SIZE); - if(!sshc) { - *err = CURLE_FAILED_INIT; - return -1; - } - - switch(sshc->sftp_recv_state) { - case 0: - sshc->sftp_file_index = - sftp_async_read_begin(sshc->sftp_file, (uint32_t)len); - if(sshc->sftp_file_index < 0) { - *err = CURLE_RECV_ERROR; - return -1; - } - - FALLTHROUGH(); - case 1: - sshc->sftp_recv_state = 1; - nread = sftp_async_read(sshc->sftp_file, mem, (uint32_t)len, - (uint32_t)sshc->sftp_file_index); - - myssh_block2waitfor(conn, sshc, (nread == SSH_AGAIN)); - - if(nread == SSH_AGAIN) { - *err = CURLE_AGAIN; - return -1; - } - else if(nread < 0) { - *err = CURLE_RECV_ERROR; - return -1; - } - - sshc->sftp_recv_state = 0; - return nread; - - default: - /* we never reach here */ - return -1; - } -} - -static void sftp_quote(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - const char *cp; - CURLcode result; - - /* - * Support some of the "FTP" commands - */ - char *cmd = sshc->quote_item->data; - sshc->acceptfail = FALSE; - - /* if a command starts with an asterisk, which a legal SFTP command never - can, the command will be allowed to fail without it causing any - aborts or cancels etc. It will cause libcurl to act as if the command - is successful, whatever the server responds. */ - - if(cmd[0] == '*') { - cmd++; - sshc->acceptfail = TRUE; - } + if(nwrite == SSH_AGAIN) + return CURLE_AGAIN; + else if(nwrite < 0) + return CURLE_SEND_ERROR; - if(strcasecompare("pwd", cmd)) { - /* output debug output if that is requested */ - char *tmp = aprintf("257 \"%s\" is current directory.\n", sshp->path); - if(!tmp) { - sshc->actualcode = CURLE_OUT_OF_MEMORY; - myssh_state(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - return; - } - Curl_debug(data, CURLINFO_HEADER_OUT, "PWD\n", 4); - Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp)); + /* + * sftp_aio_wait_write() would free sftp_send_aio and + * assign it NULL in all cases except when it returns + * SSH_AGAIN. + */ - /* this sends an FTP-like "header" to the header callback so that the - current directory can be read very similar to how it is read when - using ordinary FTP. */ - result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp)); - free(tmp); - if(result) { - myssh_state(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - } - else - myssh_state(data, sshc, SSH_SFTP_NEXT_QUOTE); - return; + sshc->sftp_send_state = 0; + *pnwritten = (size_t)nwrite; + return CURLE_OK; + default: + /* we never reach here */ + return CURLE_SEND_ERROR; } - +#else /* - * the arguments following the command must be separated from the - * command with a space so we can check for it unconditionally + * limit the writes to the maximum specified in Section 3 of + * https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02 + * + * libssh started applying appropriate read/write length limits + * internally since version 0.11.0, hence such an operation is + * not needed for versions after (and including) 0.11.0. */ - cp = strchr(cmd, ' '); - if(!cp) { - failf(data, "Syntax error in SFTP command. Supply parameter(s)"); - myssh_state(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - return; - } + if(len > 32768) + len = 32768; - /* - * also, every command takes at least one argument so we get that - * first argument right now - */ - result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else - failf(data, "Syntax error: Bad first parameter"); - myssh_state(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - return; - } + nwrite = sftp_write(sshc->sftp_file, mem, len); - /* - * SFTP is a binary protocol, so we do not send text commands - * to the server. Instead, we scan for commands used by - * OpenSSH's sftp program and call the appropriate libssh - * functions. - */ - if(!strncmp(cmd, "chgrp ", 6) || - !strncmp(cmd, "chmod ", 6) || - !strncmp(cmd, "chown ", 6) || - !strncmp(cmd, "atime ", 6) || - !strncmp(cmd, "mtime ", 6)) { - /* attribute change */ + myssh_block2waitfor(conn, sshc, FALSE); - /* sshc->quote_path1 contains the mode to set */ - /* get the destination */ - result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else - failf(data, "Syntax error in chgrp/chmod/chown/atime/mtime: " - "Bad second parameter"); - Curl_safefree(sshc->quote_path1); - myssh_state(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - return; - } - sshc->quote_attrs = NULL; - myssh_state(data, sshc, SSH_SFTP_QUOTE_STAT); - return; - } - if(!strncmp(cmd, "ln ", 3) || - !strncmp(cmd, "symlink ", 8)) { - /* symbolic linking */ - /* sshc->quote_path1 is the source */ - /* get the destination */ - result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else - failf(data, "Syntax error in ln/symlink: Bad second parameter"); - Curl_safefree(sshc->quote_path1); - myssh_state(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - return; - } - myssh_state(data, sshc, SSH_SFTP_QUOTE_SYMLINK); - return; - } - else if(!strncmp(cmd, "mkdir ", 6)) { - /* create dir */ - myssh_state(data, sshc, SSH_SFTP_QUOTE_MKDIR); - return; - } - else if(!strncmp(cmd, "rename ", 7)) { - /* rename file */ - /* first param is the source path */ - /* second param is the dest. path */ - result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else - failf(data, "Syntax error in rename: Bad second parameter"); - Curl_safefree(sshc->quote_path1); - myssh_state(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - return; - } - myssh_state(data, sshc, SSH_SFTP_QUOTE_RENAME); - return; - } - else if(!strncmp(cmd, "rmdir ", 6)) { - /* delete dir */ - myssh_state(data, sshc, SSH_SFTP_QUOTE_RMDIR); - return; - } - else if(!strncmp(cmd, "rm ", 3)) { - myssh_state(data, sshc, SSH_SFTP_QUOTE_UNLINK); - return; - } -#ifdef HAS_STATVFS_SUPPORT - else if(!strncmp(cmd, "statvfs ", 8)) { - myssh_state(data, sshc, SSH_SFTP_QUOTE_STATVFS); - return; +#if 0 /* not returned by libssh on write */ + if(nwrite == SSH_AGAIN) { + *err = CURLE_AGAIN; + nwrite = 0; } + else #endif + if(nwrite < 0) + return CURLE_SSH; - failf(data, "Unknown SFTP command"); - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - myssh_state(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; + *pnwritten = (size_t)nwrite; + return CURLE_OK; +#endif } -static void sftp_quote_stat(struct Curl_easy *data, - struct ssh_conn *sshc) +/* + * Return number of received (decrypted) bytes + * or <0 on error + */ +static CURLcode sftp_recv(struct Curl_easy *data, int sockindex, + char *mem, size_t len, size_t *pnread) { - char *cmd = sshc->quote_item->data; - sshc->acceptfail = FALSE; + struct connectdata *conn = data->conn; + struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); + ssize_t nread; - /* if a command starts with an asterisk, which a legal SFTP command never - can, the command will be allowed to fail without it causing any - aborts or cancels etc. It will cause libcurl to act as if the command - is successful, whatever the server responds. */ + (void)sockindex; + *pnread = 0; - if(cmd[0] == '*') { - cmd++; - sshc->acceptfail = TRUE; - } + DEBUGASSERT(len < CURL_MAX_READ_SIZE); + if(!sshc) + return CURLE_FAILED_INIT; - /* We read the file attributes, store them in sshc->quote_attrs - * and modify them accordingly to command. Then we switch to - * QUOTE_SETSTAT state to write new ones. - */ + switch(sshc->sftp_recv_state) { + case 0: +#if LIBSSH_VERSION_INT > SSH_VERSION_INT(0, 11, 0) + if(sftp_aio_begin_read(sshc->sftp_file, len, + &sshc->sftp_recv_aio) == SSH_ERROR) { + return CURLE_RECV_ERROR; + } +#else + sshc->sftp_file_index = + sftp_async_read_begin(sshc->sftp_file, (uint32_t)len); + if(sshc->sftp_file_index < 0) + return CURLE_RECV_ERROR; +#endif - if(sshc->quote_attrs) - sftp_attributes_free(sshc->quote_attrs); - sshc->quote_attrs = sftp_stat(sshc->sftp_session, sshc->quote_path2); - if(!sshc->quote_attrs) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Attempt to get SFTP stats failed: %d", - sftp_get_error(sshc->sftp_session)); - myssh_state(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - return; - } + FALLTHROUGH(); + case 1: + sshc->sftp_recv_state = 1; - /* Now set the new attributes... */ - if(!strncmp(cmd, "chgrp", 5)) { - const char *p = sshc->quote_path1; - curl_off_t gid; - (void)curlx_str_number(&p, &gid, UINT_MAX); - sshc->quote_attrs->gid = (uint32_t)gid; - if(sshc->quote_attrs->gid == 0 && !ISDIGIT(sshc->quote_path1[0]) && - !sshc->acceptfail) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Syntax error: chgrp gid not a number"); - myssh_state(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - return; - } - sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID; - } - else if(!strncmp(cmd, "chmod", 5)) { - curl_off_t perms; - const char *p = sshc->quote_path1; - if(curlx_str_octal(&p, &perms, 07777)) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Syntax error: chmod permissions not a number"); - myssh_state(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - return; - } - sshc->quote_attrs->permissions = (mode_t)perms; - sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_PERMISSIONS; - } - else if(!strncmp(cmd, "chown", 5)) { - const char *p = sshc->quote_path1; - curl_off_t uid; - (void)curlx_str_number(&p, &uid, UINT_MAX); - if(sshc->quote_attrs->uid == 0 && !ISDIGIT(sshc->quote_path1[0]) && - !sshc->acceptfail) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Syntax error: chown uid not a number"); - myssh_state(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - return; - } - sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID; - } - else if(!strncmp(cmd, "atime", 5) || - !strncmp(cmd, "mtime", 5)) { - time_t date = Curl_getdate_capped(sshc->quote_path1); - bool fail = FALSE; - if(date == -1) { - failf(data, "incorrect date format for %.*s", 5, cmd); - fail = TRUE; - } -#if SIZEOF_TIME_T > 4 - else if(date > 0xffffffff) { - failf(data, "date overflow"); - fail = TRUE; /* avoid setting a capped time */ - } +#if LIBSSH_VERSION_INT > SSH_VERSION_INT(0, 11, 0) + nread = sftp_aio_wait_read(&sshc->sftp_recv_aio, mem, len); +#else + nread = sftp_async_read(sshc->sftp_file, mem, (uint32_t)len, + (uint32_t)sshc->sftp_file_index); #endif - if(fail) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - myssh_state(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - return; - } - if(!strncmp(cmd, "atime", 5)) - sshc->quote_attrs->atime = (uint32_t)date; - else /* mtime */ - sshc->quote_attrs->mtime = (uint32_t)date; - sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_ACMODTIME; - } + myssh_block2waitfor(conn, sshc, (nread == SSH_AGAIN)); - /* Now send the completed structure... */ - myssh_state(data, sshc, SSH_SFTP_QUOTE_SETSTAT); - return; + if(nread == SSH_AGAIN) + return CURLE_AGAIN; + else if(nread < 0) + return CURLE_RECV_ERROR; + + /* + * sftp_aio_wait_read() would free sftp_recv_aio and + * assign it NULL in all cases except when it returns + * SSH_AGAIN. + */ + + sshc->sftp_recv_state = 0; + *pnread = (size_t)nread; + return CURLE_OK; + + default: + /* we never reach here */ + return CURLE_RECV_ERROR; + } } + CURLcode Curl_ssh_init(void) { if(ssh_init()) { diff --git a/vendor/curl/lib/vssh/libssh2.c b/vendor/curl/lib/vssh/libssh2.c index c16b3ac3886..f6985ed251b 100644 --- a/vendor/curl/lib/vssh/libssh2.c +++ b/vendor/curl/lib/vssh/libssh2.c @@ -61,11 +61,9 @@ #include "../speedcheck.h" #include "../getinfo.h" #include "../strdup.h" -#include "../strcase.h" #include "../vtls/vtls.h" #include "../cfilters.h" #include "../connect.h" -#include "../inet_ntop.h" #include "../parsedate.h" /* for the week day and month names */ #include "../sockaddr.h" /* required for Curl_sockaddr_storage */ #include "../multiif.h" @@ -101,8 +99,8 @@ static CURLcode sftp_disconnect(struct Curl_easy *data, struct connectdata *conn, bool dead); static CURLcode sftp_perform(struct Curl_easy *data, bool *connected, bool *dophase_done); -static int ssh_getsock(struct Curl_easy *data, struct connectdata *conn, - curl_socket_t *sock); +static CURLcode ssh_pollset(struct Curl_easy *data, + struct easy_pollset *ps); static CURLcode ssh_setup_connection(struct Curl_easy *data, struct connectdata *conn); static void ssh_attach(struct Curl_easy *data, struct connectdata *conn); @@ -121,10 +119,10 @@ const struct Curl_handler Curl_handler_scp = { ssh_connect, /* connect_it */ ssh_multi_statemach, /* connecting */ scp_doing, /* doing */ - ssh_getsock, /* proto_getsock */ - ssh_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ssh_getsock, /* perform_getsock */ + ssh_pollset, /* proto_pollset */ + ssh_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ssh_pollset, /* perform_pollset */ scp_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -152,10 +150,10 @@ const struct Curl_handler Curl_handler_sftp = { ssh_connect, /* connect_it */ ssh_multi_statemach, /* connecting */ sftp_doing, /* doing */ - ssh_getsock, /* proto_getsock */ - ssh_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ssh_getsock, /* perform_getsock */ + ssh_pollset, /* proto_pollset */ + ssh_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ssh_pollset, /* perform_pollset */ sftp_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -696,7 +694,7 @@ static CURLcode ssh_check_fingerprint(struct Curl_easy *data, /* This does NOT verify the length of 'pubkey_md5' separately, which will make the comparison below fail unless it is exactly 32 characters */ - if(!fingerprint || !strcasecompare(md5buffer, pubkey_md5)) { + if(!fingerprint || !curl_strequal(md5buffer, pubkey_md5)) { if(fingerprint) { failf(data, "Denied establishing ssh session: mismatch md5 fingerprint. " @@ -920,7 +918,7 @@ static CURLcode sftp_quote(struct Curl_easy *data, sshc->acceptfail = TRUE; } - if(strcasecompare("pwd", cmd)) { + if(curl_strequal("pwd", cmd)) { /* output debug output if that is requested */ char *tmp = aprintf("257 \"%s\" is current directory.\n", sshp->path); if(!tmp) @@ -1201,24 +1199,18 @@ sftp_upload_init(struct Curl_easy *data, Curl_pgrsSetUploadSize(data, data->state.infilesize); } /* upload data */ - Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE); + Curl_xfer_setup_send(data, FIRSTSOCKET); /* not set by Curl_xfer_setup to preserve keepon bits */ - data->conn->sockfd = data->conn->writesockfd; + data->conn->recv_idx = FIRSTSOCKET; /* store this original bitmask setup to use later on if we cannot figure out a "real" bitmask */ sshc->orig_waitfor = data->req.keepon; - /* we want to use the _sending_ function even when the socket turns - out readable as the underlying libssh2 sftp send function will deal - with both accordingly */ - data->state.select_bits = CURL_CSELECT_OUT; - /* since we do not really wait for anything at this point, we want the - state machine to move on as soon as possible so we set a very short - timeout here */ - Curl_expire(data, 0, EXPIRE_RUN_NOW); + state machine to move on as soon as possible so mark this as dirty */ + Curl_multi_mark_dirty(data); myssh_state(data, sshc, SSH_STOP); return CURLE_OK; @@ -1548,15 +1540,11 @@ sftp_download_stat(struct Curl_easy *data, myssh_state(data, sshc, SSH_STOP); return CURLE_OK; } - Curl_xfer_setup1(data, CURL_XFER_RECV, data->req.size, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, data->req.size); /* not set by Curl_xfer_setup to preserve keepon bits */ - data->conn->writesockfd = data->conn->sockfd; + data->conn->send_idx = 0; - /* we want to use the _receiving_ function even when the socket turns - out writableable as the underlying libssh2 recv function will deal - with both accordingly */ - data->state.select_bits = CURL_CSELECT_IN; myssh_state(data, sshc, SSH_STOP); return CURLE_OK; @@ -1809,7 +1797,7 @@ static CURLcode ssh_state_auth_host_init(struct Curl_easy *data, } static CURLcode ssh_state_auth_agent_init(struct Curl_easy *data, - struct ssh_conn *sshc) + struct ssh_conn *sshc) { int rc = 0; if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT) @@ -1918,7 +1906,7 @@ static CURLcode ssh_state_auth_key_init(struct Curl_easy *data, } static CURLcode ssh_state_auth_key(struct Curl_easy *data, - struct ssh_conn *sshc) + struct ssh_conn *sshc) { /* Authentication failed. Continue with keyboard-interactive now. */ struct connectdata *conn = data->conn; @@ -1957,8 +1945,8 @@ static CURLcode ssh_state_auth_done(struct Curl_easy *data, Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSH is connected */ - conn->sockfd = conn->sock[FIRSTSOCKET]; - conn->writesockfd = CURL_SOCKET_BAD; + data->conn->recv_idx = FIRSTSOCKET; + conn->send_idx = -1; if(conn->handler->protocol == CURLPROTO_SFTP) { myssh_state(data, sshc, SSH_SFTP_INIT); @@ -2274,7 +2262,7 @@ static CURLcode ssh_state_sftp_quote_unlink(struct Curl_easy *data, } static CURLcode ssh_state_sftp_quote_statvfs(struct Curl_easy *data, - struct ssh_conn *sshc) + struct ssh_conn *sshc) { LIBSSH2_SFTP_STATVFS statvfs; int rc = libssh2_sftp_statvfs(sshc->sftp_session, sshc->quote_path1, @@ -2472,15 +2460,10 @@ static CURLcode ssh_state_scp_download_init(struct Curl_easy *data, /* download data */ bytecount = (curl_off_t)sb.st_size; data->req.maxdownload = (curl_off_t)sb.st_size; - Curl_xfer_setup1(data, CURL_XFER_RECV, bytecount, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, bytecount); /* not set by Curl_xfer_setup to preserve keepon bits */ - data->conn->writesockfd = data->conn->sockfd; - - /* we want to use the _receiving_ function even when the socket turns - out writableable as the underlying libssh2 recv function will deal - with both accordingly */ - data->state.select_bits = CURL_CSELECT_IN; + data->conn->send_idx = 0; myssh_state(data, sshc, SSH_STOP); return CURLE_OK; @@ -2524,7 +2507,7 @@ static CURLcode ssh_state_sftp_close(struct Curl_easy *data, } static CURLcode ssh_state_sftp_shutdown(struct Curl_easy *data, - struct ssh_conn *sshc) + struct ssh_conn *sshc) { /* during times we get here due to a broken transfer and then the sftp_handle might not have been taken down so make sure that is done @@ -2626,20 +2609,15 @@ static CURLcode ssh_state_scp_upload_init(struct Curl_easy *data, /* upload data */ data->req.size = data->state.infilesize; Curl_pgrsSetUploadSize(data, data->state.infilesize); - Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE); + Curl_xfer_setup_send(data, FIRSTSOCKET); /* not set by Curl_xfer_setup to preserve keepon bits */ - data->conn->sockfd = data->conn->writesockfd; + data->conn->recv_idx = FIRSTSOCKET; /* store this original bitmask setup to use later on if we cannot figure out a "real" bitmask */ sshc->orig_waitfor = data->req.keepon; - /* we want to use the _sending_ function even when the socket turns - out readable as the underlying libssh2 scp send function will deal - with both accordingly */ - data->state.select_bits = CURL_CSELECT_OUT; - myssh_state(data, sshc, SSH_STOP); return CURLE_OK; @@ -3109,22 +3087,17 @@ static CURLcode ssh_statemachine(struct Curl_easy *data, /* called by the multi interface to figure out what socket(s) to wait for and for what actions in the DO_DONE, PERFORM and WAITPERFORM states */ -static int ssh_getsock(struct Curl_easy *data, - struct connectdata *conn, - curl_socket_t *sock) +static CURLcode ssh_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { - int bitmap = GETSOCK_BLANK; - (void)data; - - sock[0] = conn->sock[FIRSTSOCKET]; - - if(conn->waitfor & KEEP_RECV) - bitmap |= GETSOCK_READSOCK(FIRSTSOCKET); - - if(conn->waitfor & KEEP_SEND) - bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET); - - return bitmap; + int flags = 0; + if(data->conn->waitfor & KEEP_RECV) + flags |= CURL_POLL_IN; + if(data->conn->waitfor & KEEP_SEND) + flags |= CURL_POLL_OUT; + return flags ? + Curl_pollset_change(data, ps, data->conn->sock[FIRSTSOCKET], flags, 0) : + CURLE_OK; } /* @@ -3161,7 +3134,7 @@ static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done) struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY); CURLcode result = CURLE_OK; - bool block; /* we store the status and use that to provide a ssh_getsock() + bool block; /* we store the status and use that to provide a ssh_pollset() implementation */ if(!sshc || !sshp) return CURLE_FAILED_INIT; @@ -3267,7 +3240,6 @@ static CURLcode ssh_setup_connection(struct Curl_easy *data, if(!sshc) return CURLE_OUT_OF_MEMORY; - sshc->initialised = TRUE; if(Curl_conn_meta_set(conn, CURL_META_SSH_CONN, sshc, myssh_conn_dtor)) return CURLE_OUT_OF_MEMORY; @@ -3291,7 +3263,7 @@ static ssize_t ssh_tls_recv(libssh2_socket_t sock, void *buffer, size_t length, int flags, void **abstract) { struct Curl_easy *data = (struct Curl_easy *)*abstract; - ssize_t nread; + size_t nread; CURLcode result; struct connectdata *conn = data->conn; Curl_recv *backup = conn->recv[0]; @@ -3312,7 +3284,7 @@ static ssize_t ssh_tls_recv(libssh2_socket_t sock, void *buffer, else if(result) return -1; /* generic error */ Curl_debug(data, CURLINFO_DATA_IN, (const char *)buffer, (size_t)nread); - return nread; + return (ssize_t)nread; } static ssize_t ssh_tls_send(libssh2_socket_t sock, const void *buffer, @@ -3611,101 +3583,99 @@ static CURLcode sshc_cleanup(struct ssh_conn *sshc, struct Curl_easy *data, { int rc; - if(sshc->initialised) { - if(sshc->kh) { - libssh2_knownhost_free(sshc->kh); - sshc->kh = NULL; - } - - if(sshc->ssh_agent) { - rc = libssh2_agent_disconnect(sshc->ssh_agent); - if(!block && (rc == LIBSSH2_ERROR_EAGAIN)) - return CURLE_AGAIN; + if(sshc->kh) { + libssh2_knownhost_free(sshc->kh); + sshc->kh = NULL; + } - if((rc < 0) && data) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - infof(data, "Failed to disconnect from libssh2 agent: %d %s", - rc, err_msg); - } - libssh2_agent_free(sshc->ssh_agent); - sshc->ssh_agent = NULL; + if(sshc->ssh_agent) { + rc = libssh2_agent_disconnect(sshc->ssh_agent); + if(!block && (rc == LIBSSH2_ERROR_EAGAIN)) + return CURLE_AGAIN; - /* NB: there is no need to free identities, they are part of internal - agent stuff */ - sshc->sshagent_identity = NULL; - sshc->sshagent_prev_identity = NULL; + if((rc < 0) && data) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to disconnect from libssh2 agent: %d %s", + rc, err_msg); } + libssh2_agent_free(sshc->ssh_agent); + sshc->ssh_agent = NULL; - if(sshc->sftp_handle) { - rc = libssh2_sftp_close(sshc->sftp_handle); - if(!block && (rc == LIBSSH2_ERROR_EAGAIN)) - return CURLE_AGAIN; + /* NB: there is no need to free identities, they are part of internal + agent stuff */ + sshc->sshagent_identity = NULL; + sshc->sshagent_prev_identity = NULL; + } - if((rc < 0) && data) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, - NULL, 0); - infof(data, "Failed to close libssh2 file: %d %s", rc, err_msg); - } - sshc->sftp_handle = NULL; + if(sshc->sftp_handle) { + rc = libssh2_sftp_close(sshc->sftp_handle); + if(!block && (rc == LIBSSH2_ERROR_EAGAIN)) + return CURLE_AGAIN; + + if((rc < 0) && data) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, + NULL, 0); + infof(data, "Failed to close libssh2 file: %d %s", rc, err_msg); } + sshc->sftp_handle = NULL; + } - if(sshc->ssh_channel) { - rc = libssh2_channel_free(sshc->ssh_channel); - if(!block && (rc == LIBSSH2_ERROR_EAGAIN)) - return CURLE_AGAIN; + if(sshc->ssh_channel) { + rc = libssh2_channel_free(sshc->ssh_channel); + if(!block && (rc == LIBSSH2_ERROR_EAGAIN)) + return CURLE_AGAIN; - if((rc < 0) && data) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - infof(data, "Failed to free libssh2 scp subsystem: %d %s", - rc, err_msg); - } - sshc->ssh_channel = NULL; + if((rc < 0) && data) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to free libssh2 scp subsystem: %d %s", + rc, err_msg); } + sshc->ssh_channel = NULL; + } - if(sshc->sftp_session) { - rc = libssh2_sftp_shutdown(sshc->sftp_session); - if(!block && (rc == LIBSSH2_ERROR_EAGAIN)) - return CURLE_AGAIN; + if(sshc->sftp_session) { + rc = libssh2_sftp_shutdown(sshc->sftp_session); + if(!block && (rc == LIBSSH2_ERROR_EAGAIN)) + return CURLE_AGAIN; - if((rc < 0) && data) - infof(data, "Failed to stop libssh2 sftp subsystem"); - sshc->sftp_session = NULL; - } + if((rc < 0) && data) + infof(data, "Failed to stop libssh2 sftp subsystem"); + sshc->sftp_session = NULL; + } - if(sshc->ssh_session) { - rc = libssh2_session_free(sshc->ssh_session); - if(!block && (rc == LIBSSH2_ERROR_EAGAIN)) - return CURLE_AGAIN; + if(sshc->ssh_session) { + rc = libssh2_session_free(sshc->ssh_session); + if(!block && (rc == LIBSSH2_ERROR_EAGAIN)) + return CURLE_AGAIN; - if((rc < 0) && data) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - infof(data, "Failed to free libssh2 session: %d %s", rc, err_msg); - } - sshc->ssh_session = NULL; + if((rc < 0) && data) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to free libssh2 session: %d %s", rc, err_msg); } + sshc->ssh_session = NULL; + } - /* worst-case scenario cleanup */ - DEBUGASSERT(sshc->ssh_session == NULL); - DEBUGASSERT(sshc->ssh_channel == NULL); - DEBUGASSERT(sshc->sftp_session == NULL); - DEBUGASSERT(sshc->sftp_handle == NULL); - DEBUGASSERT(sshc->kh == NULL); - DEBUGASSERT(sshc->ssh_agent == NULL); + /* worst-case scenario cleanup */ + DEBUGASSERT(sshc->ssh_session == NULL); + DEBUGASSERT(sshc->ssh_channel == NULL); + DEBUGASSERT(sshc->sftp_session == NULL); + DEBUGASSERT(sshc->sftp_handle == NULL); + DEBUGASSERT(sshc->kh == NULL); + DEBUGASSERT(sshc->ssh_agent == NULL); + + Curl_safefree(sshc->rsa_pub); + Curl_safefree(sshc->rsa); + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + Curl_safefree(sshc->homedir); - Curl_safefree(sshc->rsa_pub); - Curl_safefree(sshc->rsa); - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - Curl_safefree(sshc->homedir); - sshc->initialised = FALSE; - } return CURLE_OK; } @@ -3720,7 +3690,7 @@ static CURLcode scp_disconnect(struct Curl_easy *data, CURLcode result = CURLE_OK; struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY); - (void) dead_connection; + (void)dead_connection; if(sshc && sshc->ssh_session && sshp) { /* only if there is a session still around to use! */ @@ -3770,58 +3740,63 @@ static CURLcode scp_done(struct Curl_easy *data, CURLcode status, return ssh_done(data, status); } -static ssize_t scp_send(struct Curl_easy *data, int sockindex, - const void *mem, size_t len, bool eos, CURLcode *err) +static CURLcode scp_send(struct Curl_easy *data, int sockindex, + const void *mem, size_t len, bool eos, + size_t *pnwritten) { - ssize_t nwrite; struct connectdata *conn = data->conn; struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); + CURLcode result = CURLE_OK; + ssize_t nwritten; + (void)sockindex; /* we only support SCP on the fixed known primary socket */ (void)eos; + *pnwritten = 0; + + if(!sshc) + return CURLE_FAILED_INIT; - if(!sshc) { - *err = CURLE_FAILED_INIT; - return -1; - } /* libssh2_channel_write() returns int! */ - nwrite = (ssize_t) libssh2_channel_write(sshc->ssh_channel, mem, len); + nwritten = (ssize_t) libssh2_channel_write(sshc->ssh_channel, mem, len); - ssh_block2waitfor(data, sshc, (nwrite == LIBSSH2_ERROR_EAGAIN)); + ssh_block2waitfor(data, sshc, (nwritten == LIBSSH2_ERROR_EAGAIN)); - if(nwrite == LIBSSH2_ERROR_EAGAIN) { - *err = CURLE_AGAIN; - nwrite = 0; - } - else if(nwrite < LIBSSH2_ERROR_NONE) { - *err = libssh2_session_error_to_CURLE((int)nwrite); - nwrite = -1; - } + if(nwritten == LIBSSH2_ERROR_EAGAIN) + result = CURLE_AGAIN; + else if(nwritten < LIBSSH2_ERROR_NONE) + result = libssh2_session_error_to_CURLE((int)nwritten); + else + *pnwritten = (size_t)nwritten; - return nwrite; + return result; } -static ssize_t scp_recv(struct Curl_easy *data, int sockindex, - char *mem, size_t len, CURLcode *err) +static CURLcode scp_recv(struct Curl_easy *data, int sockindex, + char *mem, size_t len, size_t *pnread) { - ssize_t nread; struct connectdata *conn = data->conn; struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); + CURLcode result = CURLE_OK; + ssize_t nread; + (void)sockindex; /* we only support SCP on the fixed known primary socket */ + *pnread = 0; + + if(!sshc) + return CURLE_FAILED_INIT; - if(!sshc) { - *err = CURLE_FAILED_INIT; - return -1; - } /* libssh2_channel_read() returns int */ nread = (ssize_t) libssh2_channel_read(sshc->ssh_channel, mem, len); ssh_block2waitfor(data, sshc, (nread == LIBSSH2_ERROR_EAGAIN)); - if(nread == LIBSSH2_ERROR_EAGAIN) { - *err = CURLE_AGAIN; - nread = -1; - } + if(nread == LIBSSH2_ERROR_EAGAIN) + return CURLE_AGAIN; + else if(nread < LIBSSH2_ERROR_NONE) + result = libssh2_session_error_to_CURLE((int)nread); + else + *pnread = (size_t)nread; - return nread; + return result; } /* @@ -3887,7 +3862,7 @@ static CURLcode sftp_disconnect(struct Curl_easy *data, CURLcode result = CURLE_OK; struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY); - (void) dead_connection; + (void)dead_connection; DEBUGF(infof(data, "SSH DISCONNECT starts now")); @@ -3906,7 +3881,7 @@ static CURLcode sftp_disconnect(struct Curl_easy *data, } static CURLcode sftp_done(struct Curl_easy *data, CURLcode status, - bool premature) + bool premature) { struct connectdata *conn = data->conn; struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); @@ -3926,64 +3901,61 @@ static CURLcode sftp_done(struct Curl_easy *data, CURLcode status, } /* return number of sent bytes */ -static ssize_t sftp_send(struct Curl_easy *data, int sockindex, - const void *mem, size_t len, bool eos, CURLcode *err) +static CURLcode sftp_send(struct Curl_easy *data, int sockindex, + const void *mem, size_t len, bool eos, + size_t *pnwritten) { - ssize_t nwrite; struct connectdata *conn = data->conn; struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); + ssize_t nwrite; + (void)sockindex; (void)eos; + *pnwritten = 0; + + if(!sshc) + return CURLE_FAILED_INIT; - if(!sshc) { - *err = CURLE_FAILED_INIT; - return -1; - } nwrite = libssh2_sftp_write(sshc->sftp_handle, mem, len); ssh_block2waitfor(data, sshc, (nwrite == LIBSSH2_ERROR_EAGAIN)); - if(nwrite == LIBSSH2_ERROR_EAGAIN) { - *err = CURLE_AGAIN; - nwrite = 0; - } - else if(nwrite < LIBSSH2_ERROR_NONE) { - *err = libssh2_session_error_to_CURLE((int)nwrite); - nwrite = -1; - } - - return nwrite; + if(nwrite == LIBSSH2_ERROR_EAGAIN) + return CURLE_AGAIN; + else if(nwrite < LIBSSH2_ERROR_NONE) + return libssh2_session_error_to_CURLE((int)nwrite); + *pnwritten = (size_t)nwrite; + return CURLE_OK; } /* * Return number of received (decrypted) bytes * or <0 on error */ -static ssize_t sftp_recv(struct Curl_easy *data, int sockindex, - char *mem, size_t len, CURLcode *err) +static CURLcode sftp_recv(struct Curl_easy *data, int sockindex, + char *mem, size_t len, size_t *pnread) { - ssize_t nread; struct connectdata *conn = data->conn; struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); + ssize_t nread; + (void)sockindex; + *pnread = 0; + + if(!sshc) + return CURLE_FAILED_INIT; - if(!sshc) { - *err = CURLE_FAILED_INIT; - return -1; - } nread = libssh2_sftp_read(sshc->sftp_handle, mem, len); ssh_block2waitfor(data, sshc, (nread == LIBSSH2_ERROR_EAGAIN)); - if(nread == LIBSSH2_ERROR_EAGAIN) { - *err = CURLE_AGAIN; - nread = -1; + if(nread == LIBSSH2_ERROR_EAGAIN) + return CURLE_AGAIN; + else if(nread < 0) + return libssh2_session_error_to_CURLE((int)nread); - } - else if(nread < 0) { - *err = libssh2_session_error_to_CURLE((int)nread); - } - return nread; + *pnread = (size_t)nread; + return CURLE_OK; } static const char *sftp_libssh2_strerror(unsigned long err) diff --git a/vendor/curl/lib/vssh/ssh.h b/vendor/curl/lib/vssh/ssh.h index feee886562e..75b31bd931f 100644 --- a/vendor/curl/lib/vssh/ssh.h +++ b/vendor/curl/lib/vssh/ssh.h @@ -26,7 +26,7 @@ #include "../curl_setup.h" -#if defined(USE_LIBSSH2) +#ifdef USE_LIBSSH2 #include #include #elif defined(USE_LIBSSH) @@ -162,7 +162,7 @@ struct ssh_conn { int orig_waitfor; /* default READ/WRITE bits wait for */ char *slash_pos; /* used by the SFTP_CREATE_DIRS state */ -#if defined(USE_LIBSSH) +#ifdef USE_LIBSSH CURLcode actualcode; /* the actual error code */ char *readdir_linkPath; size_t readdir_len; @@ -180,10 +180,13 @@ struct ssh_conn { unsigned sftp_recv_state; /* 0 or 1 */ #if LIBSSH_VERSION_INT > SSH_VERSION_INT(0, 11, 0) - sftp_aio sftp_aio; + sftp_aio sftp_recv_aio; + + sftp_aio sftp_send_aio; unsigned sftp_send_state; /* 0 or 1 */ -#endif +#else int sftp_file_index; /* for async read */ +#endif sftp_attributes readdir_attrs; /* used by the SFTP readdir actions */ sftp_attributes readdir_link_attrs; /* used by the SFTP readdir actions */ sftp_attributes quote_attrs; /* used by the SFTP_QUOTE state */ @@ -191,6 +194,7 @@ struct ssh_conn { const char *readdir_filename; /* points within readdir_attrs */ const char *readdir_longentry; char *readdir_tmp; + BIT(initialised); #elif defined(USE_LIBSSH2) LIBSSH2_SESSION *ssh_session; /* Secure Shell session */ LIBSSH2_CHANNEL *ssh_channel; /* Secure Shell channel handle */ @@ -214,8 +218,8 @@ struct ssh_conn { word32 handleSz; byte handle[WOLFSSH_MAX_HANDLE]; curl_off_t offset; -#endif /* USE_LIBSSH */ BIT(initialised); +#endif /* USE_LIBSSH */ BIT(authed); /* the connection has been authenticated fine */ BIT(acceptfail); /* used by the SFTP_QUOTE (continue if quote command fails) */ @@ -227,7 +231,7 @@ struct ssh_conn { #endif #endif -#if defined(USE_LIBSSH2) +#ifdef USE_LIBSSH2 /* Feature detection based on version numbers to better work with non-configure platforms */ diff --git a/vendor/curl/lib/vssh/wolfssh.c b/vendor/curl/lib/vssh/wolfssh.c index 5097ca02c51..556eda0cb5f 100644 --- a/vendor/curl/lib/vssh/wolfssh.c +++ b/vendor/curl/lib/vssh/wolfssh.c @@ -66,9 +66,8 @@ static CURLcode wsftp_doing(struct Curl_easy *data, static CURLcode wsftp_disconnect(struct Curl_easy *data, struct connectdata *conn, bool dead); -static int wssh_getsock(struct Curl_easy *data, - struct connectdata *conn, - curl_socket_t *sock); +static CURLcode wssh_pollset(struct Curl_easy *data, + struct easy_pollset *ps); static CURLcode wssh_setup_connection(struct Curl_easy *data, struct connectdata *conn); static void wssh_sshc_cleanup(struct ssh_conn *sshc); @@ -87,10 +86,10 @@ const struct Curl_handler Curl_handler_scp = { wssh_connect, /* connect_it */ wssh_multi_statemach, /* connecting */ wscp_doing, /* doing */ - wssh_getsock, /* proto_getsock */ - wssh_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - wssh_getsock, /* perform_getsock */ + wssh_pollset, /* proto_pollset */ + wssh_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + wssh_pollset, /* perform_pollset */ wscp_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -118,10 +117,10 @@ const struct Curl_handler Curl_handler_sftp = { wssh_connect, /* connect_it */ wssh_multi_statemach, /* connecting */ wsftp_doing, /* doing */ - wssh_getsock, /* proto_getsock */ - wssh_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - wssh_getsock, /* perform_getsock */ + wssh_pollset, /* proto_pollset */ + wssh_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + wssh_pollset, /* perform_pollset */ wsftp_disconnect, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ @@ -220,37 +219,35 @@ static void wssh_state(struct Curl_easy *data, sshc->state = nowstate; } -static ssize_t wscp_send(struct Curl_easy *data, int sockindex, - const void *mem, size_t len, bool eos, - CURLcode *err) +static CURLcode wscp_send(struct Curl_easy *data, int sockindex, + const void *mem, size_t len, bool eos, + size_t *pnwritten) { - ssize_t nwrite = 0; (void)data; (void)sockindex; /* we only support SCP on the fixed known primary socket */ (void)mem; (void)len; (void)eos; - (void)err; - - return nwrite; + *pnwritten = 0; + return CURLE_OK; } -static ssize_t wscp_recv(struct Curl_easy *data, int sockindex, - char *mem, size_t len, CURLcode *err) +static CURLcode wscp_recv(struct Curl_easy *data, int sockindex, + char *mem, size_t len, size_t *pnread) { - ssize_t nread = 0; (void)data; (void)sockindex; /* we only support SCP on the fixed known primary socket */ (void)mem; (void)len; - (void)err; + *pnread = 0; - return nread; + return CURLE_OK; } /* return number of sent bytes */ -static ssize_t wsftp_send(struct Curl_easy *data, int sockindex, - const void *mem, size_t len, bool eos, CURLcode *err) +static CURLcode wsftp_send(struct Curl_easy *data, int sockindex, + const void *mem, size_t len, bool eos, + size_t *pnwritten) { struct connectdata *conn = data->conn; struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); @@ -259,10 +256,10 @@ static ssize_t wsftp_send(struct Curl_easy *data, int sockindex, (void)sockindex; (void)eos; - if(!sshc) { - *err = CURLE_FAILED_INIT; - return -1; - } + *pnwritten = 0; + if(!sshc) + return CURLE_FAILED_INIT; + offset[0] = (word32)sshc->offset & 0xFFFFFFFF; offset[1] = (word32)(sshc->offset >> 32) & 0xFFFFFFFF; @@ -275,31 +272,30 @@ static ssize_t wsftp_send(struct Curl_easy *data, int sockindex, rc = wolfSSH_get_error(sshc->ssh_session); if(rc == WS_WANT_READ) { conn->waitfor = KEEP_RECV; - *err = CURLE_AGAIN; - return -1; + return CURLE_AGAIN; } else if(rc == WS_WANT_WRITE) { conn->waitfor = KEEP_SEND; - *err = CURLE_AGAIN; - return -1; + return CURLE_AGAIN; } if(rc < 0) { failf(data, "wolfSSH_SFTP_SendWritePacket returned %d", rc); - return -1; + return CURLE_SEND_ERROR; } DEBUGASSERT(rc == (int)len); + *pnwritten = (size_t)rc; + sshc->offset += *pnwritten; infof(data, "sent %zu bytes SFTP from offset %" FMT_OFF_T, - len, sshc->offset); - sshc->offset += len; - return (ssize_t)rc; + *pnwritten, sshc->offset); + return CURLE_OK; } /* * Return number of received (decrypted) bytes * or <0 on error */ -static ssize_t wsftp_recv(struct Curl_easy *data, int sockindex, - char *mem, size_t len, CURLcode *err) +static CURLcode wsftp_recv(struct Curl_easy *data, int sockindex, + char *mem, size_t len, size_t *pnread) { int rc; struct connectdata *conn = data->conn; @@ -307,10 +303,10 @@ static ssize_t wsftp_recv(struct Curl_easy *data, int sockindex, word32 offset[2]; (void)sockindex; - if(!sshc) { - *err = CURLE_FAILED_INIT; - return -1; - } + *pnread = 0; + if(!sshc) + return CURLE_FAILED_INIT; + offset[0] = (word32)sshc->offset & 0xFFFFFFFF; offset[1] = (word32)(sshc->offset >> 32) & 0xFFFFFFFF; @@ -322,24 +318,22 @@ static ssize_t wsftp_recv(struct Curl_easy *data, int sockindex, rc = wolfSSH_get_error(sshc->ssh_session); if(rc == WS_WANT_READ) { conn->waitfor = KEEP_RECV; - *err = CURLE_AGAIN; - return -1; + return CURLE_AGAIN; } else if(rc == WS_WANT_WRITE) { conn->waitfor = KEEP_SEND; - *err = CURLE_AGAIN; - return -1; + return CURLE_AGAIN; } DEBUGASSERT(rc <= (int)len); if(rc < 0) { failf(data, "wolfSSH_SFTP_SendReadPacket returned %d", rc); - return -1; + return CURLE_RECV_ERROR; } - sshc->offset += len; - - return (ssize_t)rc; + *pnread = (size_t)rc; + sshc->offset += *pnread; + return CURLE_OK; } static void wssh_easy_dtor(void *key, size_t klen, void *entry) @@ -723,10 +717,10 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, Curl_pgrsSetUploadSize(data, data->state.infilesize); } /* upload data */ - Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE); + Curl_xfer_setup_send(data, FIRSTSOCKET); /* not set by Curl_xfer_setup to preserve keepon bits */ - conn->sockfd = conn->writesockfd; + data->conn->recv_idx = FIRSTSOCKET; if(result) { wssh_state(data, sshc, SSH_SFTP_CLOSE); @@ -737,15 +731,9 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, figure out a "real" bitmask */ sshc->orig_waitfor = data->req.keepon; - /* we want to use the _sending_ function even when the socket turns - out readable as the underlying libssh2 sftp send function will deal - with both accordingly */ - data->state.select_bits = CURL_CSELECT_OUT; - /* since we do not really wait for anything at this point, we want the - state machine to move on as soon as possible so we set a very short - timeout here */ - Curl_expire(data, 0, EXPIRE_RUN_NOW); + state machine to move on as soon as possible */ + Curl_multi_mark_dirty(data); wssh_state(data, sshc, SSH_STOP); } @@ -828,15 +816,10 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, wssh_state(data, sshc, SSH_STOP); break; } - Curl_xfer_setup1(data, CURL_XFER_RECV, data->req.size, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, data->req.size); /* not set by Curl_xfer_setup to preserve keepon bits */ - conn->writesockfd = conn->sockfd; - - /* we want to use the _receiving_ function even when the socket turns - out writableable as the underlying libssh2 recv function will deal - with both accordingly */ - data->state.select_bits = CURL_CSELECT_IN; + conn->send_idx = 0; if(result) { /* this should never occur; the close state should be entered @@ -948,7 +931,7 @@ static CURLcode wssh_multi_statemach(struct Curl_easy *data, bool *done) struct connectdata *conn = data->conn; struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); CURLcode result = CURLE_OK; - bool block; /* we store the status and use that to provide a ssh_getsock() + bool block; /* we store the status and use that to provide a ssh_pollset() implementation */ if(!sshc) return CURLE_FAILED_INIT; @@ -1123,7 +1106,7 @@ static void wssh_sshc_cleanup(struct ssh_conn *sshc) #if 0 static CURLcode wscp_done(struct Curl_easy *data, - CURLcode code, bool premature) + CURLcode code, bool premature) { CURLcode result = CURLE_OK; (void)conn; @@ -1134,7 +1117,7 @@ static CURLcode wscp_done(struct Curl_easy *data, } static CURLcode wscp_doing(struct Curl_easy *data, - bool *dophase_done) + bool *dophase_done) { CURLcode result = CURLE_OK; (void)conn; @@ -1156,7 +1139,7 @@ static CURLcode wscp_disconnect(struct Curl_easy *data, #endif static CURLcode wsftp_done(struct Curl_easy *data, - CURLcode code, bool premature) + CURLcode code, bool premature) { struct ssh_conn *sshc = Curl_conn_meta_get(data->conn, CURL_META_SSH_CONN); (void)premature; @@ -1169,7 +1152,7 @@ static CURLcode wsftp_done(struct Curl_easy *data, } static CURLcode wsftp_doing(struct Curl_easy *data, - bool *dophase_done) + bool *dophase_done) { CURLcode result = wssh_multi_statemach(data, dophase_done); @@ -1201,21 +1184,17 @@ static CURLcode wsftp_disconnect(struct Curl_easy *data, return result; } -static int wssh_getsock(struct Curl_easy *data, - struct connectdata *conn, - curl_socket_t *sock) +static CURLcode wssh_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { - int bitmap = GETSOCK_BLANK; - int dir = conn->waitfor; - (void)data; - sock[0] = conn->sock[FIRSTSOCKET]; - - if(dir == KEEP_RECV) - bitmap |= GETSOCK_READSOCK(FIRSTSOCKET); - else if(dir == KEEP_SEND) - bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET); - - return bitmap; + int flags = 0; + if(data->conn->waitfor & KEEP_RECV) + flags |= CURL_POLL_IN; + if(data->conn->waitfor & KEEP_SEND) + flags |= CURL_POLL_OUT; + return flags ? + Curl_pollset_change(data, ps, data->conn->sock[FIRSTSOCKET], flags, 0) : + CURLE_OK; } void Curl_ssh_version(char *buffer, size_t buflen) diff --git a/vendor/curl/lib/vtls/cipher_suite.c b/vendor/curl/lib/vtls/cipher_suite.c index d058bd3f0e0..4bf60c1a4ab 100644 --- a/vendor/curl/lib/vtls/cipher_suite.c +++ b/vendor/curl/lib/vtls/cipher_suite.c @@ -23,11 +23,9 @@ ***************************************************************************/ #include "../curl_setup.h" -#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || \ - defined(USE_BEARSSL) || defined(USE_RUSTLS) +#if defined(USE_MBEDTLS) || defined(USE_RUSTLS) #include "cipher_suite.h" #include "../curl_printf.h" -#include "../strcase.h" #include /* @@ -72,7 +70,7 @@ static const char *cs_txt = "ECDH" "\0" "ECDHE" "\0" "ECDSA" "\0" - "EDE" "\0" + "EDE" "\0" /* spellchecker:disable-line */ "GCM" "\0" "MD5" "\0" "NULL" "\0" @@ -82,7 +80,7 @@ static const char *cs_txt = "SHA" "\0" "SHA256" "\0" "SHA384" "\0" -#if defined(USE_MBEDTLS) +#ifdef USE_MBEDTLS "ARIA" "\0" "ARIA128" "\0" "ARIA256" "\0" @@ -90,21 +88,6 @@ static const char *cs_txt = "CAMELLIA128" "\0" "CAMELLIA256" "\0" #endif -#if defined(USE_SECTRANSP) - "40" "\0" - "ADH" "\0" - "AECDH" "\0" - "anon" "\0" - "DES40" "\0" - "DH" "\0" - "DSS" "\0" - "EDH" "\0" - "EXP" "\0" - "EXPORT" "\0" - "IDEA" "\0" - "RC2" "\0" - "RC4" "\0" -#endif ; /* Indexes of above cs_txt */ enum { @@ -128,7 +111,7 @@ enum { CS_TXT_IDX_ECDH, CS_TXT_IDX_ECDHE, CS_TXT_IDX_ECDSA, - CS_TXT_IDX_EDE, + CS_TXT_IDX_EDE, /* spellchecker:disable-line */ CS_TXT_IDX_GCM, CS_TXT_IDX_MD5, CS_TXT_IDX_NULL, @@ -138,28 +121,13 @@ enum { CS_TXT_IDX_SHA, CS_TXT_IDX_SHA256, CS_TXT_IDX_SHA384, -#if defined(USE_MBEDTLS) +#ifdef USE_MBEDTLS CS_TXT_IDX_ARIA, CS_TXT_IDX_ARIA128, CS_TXT_IDX_ARIA256, CS_TXT_IDX_CAMELLIA, CS_TXT_IDX_CAMELLIA128, CS_TXT_IDX_CAMELLIA256, -#endif -#if defined(USE_SECTRANSP) - CS_TXT_IDX_40, - CS_TXT_IDX_ADH, - CS_TXT_IDX_AECDH, - CS_TXT_IDX_anon, - CS_TXT_IDX_DES40, - CS_TXT_IDX_DH, - CS_TXT_IDX_DSS, - CS_TXT_IDX_EDH, - CS_TXT_IDX_EXP, - CS_TXT_IDX_EXPORT, - CS_TXT_IDX_IDEA, - CS_TXT_IDX_RC2, - CS_TXT_IDX_RC4, #endif CS_TXT_LEN, }; @@ -192,7 +160,7 @@ struct cs_entry { /* !checksrc! disable COMMANOSPACE all */ static const struct cs_entry cs_list [] = { /* TLS 1.3 ciphers */ -#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_RUSTLS) +#if defined(USE_MBEDTLS) || defined(USE_RUSTLS) CS_ENTRY(0x1301, TLS,AES,128,GCM,SHA256,,,), CS_ENTRY(0x1302, TLS,AES,256,GCM,SHA384,,,), CS_ENTRY(0x1303, TLS,CHACHA20,POLY1305,SHA256,,,,), @@ -212,7 +180,7 @@ static const struct cs_entry cs_list [] = { CS_ENTRY(0xCCA8, ECDHE,RSA,CHACHA20,POLY1305,,,,), CS_ENTRY(0xCCA9, TLS,ECDHE,ECDSA,WITH,CHACHA20,POLY1305,SHA256,), CS_ENTRY(0xCCA9, ECDHE,ECDSA,CHACHA20,POLY1305,,,,), -#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_BEARSSL) +#ifdef USE_MBEDTLS CS_ENTRY(0x002F, TLS,RSA,WITH,AES,128,CBC,SHA,), CS_ENTRY(0x002F, AES128,SHA,,,,,,), CS_ENTRY(0x0035, TLS,RSA,WITH,AES,256,CBC,SHA,), @@ -266,7 +234,7 @@ static const struct cs_entry cs_list [] = { CS_ENTRY(0xC032, TLS,ECDH,RSA,WITH,AES,256,GCM,SHA384), CS_ENTRY(0xC032, ECDH,RSA,AES256,GCM,SHA384,,,), #endif -#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) +#ifdef USE_MBEDTLS CS_ENTRY(0x0001, TLS,RSA,WITH,NULL,MD5,,,), CS_ENTRY(0x0001, NULL,MD5,,,,,,), CS_ENTRY(0x0002, TLS,RSA,WITH,NULL,SHA,,,), @@ -354,19 +322,7 @@ static const struct cs_entry cs_list [] = { CS_ENTRY(0xCCAB, TLS,PSK,WITH,CHACHA20,POLY1305,SHA256,,), CS_ENTRY(0xCCAB, PSK,CHACHA20,POLY1305,,,,,), #endif -#if defined(USE_SECTRANSP) || defined(USE_BEARSSL) - CS_ENTRY(0x000A, TLS,RSA,WITH,3DES,EDE,CBC,SHA,), - CS_ENTRY(0x000A, DES,CBC3,SHA,,,,,), - CS_ENTRY(0xC003, TLS,ECDH,ECDSA,WITH,3DES,EDE,CBC,SHA), - CS_ENTRY(0xC003, ECDH,ECDSA,DES,CBC3,SHA,,,), - CS_ENTRY(0xC008, TLS,ECDHE,ECDSA,WITH,3DES,EDE,CBC,SHA), - CS_ENTRY(0xC008, ECDHE,ECDSA,DES,CBC3,SHA,,,), - CS_ENTRY(0xC00D, TLS,ECDH,RSA,WITH,3DES,EDE,CBC,SHA), - CS_ENTRY(0xC00D, ECDH,RSA,DES,CBC3,SHA,,,), - CS_ENTRY(0xC012, TLS,ECDHE,RSA,WITH,3DES,EDE,CBC,SHA), - CS_ENTRY(0xC012, ECDHE,RSA,DES,CBC3,SHA,,,), -#endif -#if defined(USE_MBEDTLS) || defined(USE_BEARSSL) +#ifdef USE_MBEDTLS CS_ENTRY(0xC09C, TLS,RSA,WITH,AES,128,CCM,,), CS_ENTRY(0xC09C, AES128,CCM,,,,,,), CS_ENTRY(0xC09D, TLS,RSA,WITH,AES,256,CCM,,), @@ -384,142 +340,7 @@ static const struct cs_entry cs_list [] = { CS_ENTRY(0xC0AF, TLS,ECDHE,ECDSA,WITH,AES,256,CCM,8), CS_ENTRY(0xC0AF, ECDHE,ECDSA,AES256,CCM8,,,,), #endif -#if defined(USE_SECTRANSP) - /* entries marked bc are backward compatible aliases for old OpenSSL names */ - CS_ENTRY(0x0003, TLS,RSA,EXPORT,WITH,RC4,40,MD5,), - CS_ENTRY(0x0003, EXP,RC4,MD5,,,,,), - CS_ENTRY(0x0004, TLS,RSA,WITH,RC4,128,MD5,,), - CS_ENTRY(0x0004, RC4,MD5,,,,,,), - CS_ENTRY(0x0005, TLS,RSA,WITH,RC4,128,SHA,,), - CS_ENTRY(0x0005, RC4,SHA,,,,,,), - CS_ENTRY(0x0006, TLS,RSA,EXPORT,WITH,RC2,CBC,40,MD5), - CS_ENTRY(0x0006, EXP,RC2,CBC,MD5,,,,), - CS_ENTRY(0x0007, TLS,RSA,WITH,IDEA,CBC,SHA,,), - CS_ENTRY(0x0007, IDEA,CBC,SHA,,,,,), - CS_ENTRY(0x0008, TLS,RSA,EXPORT,WITH,DES40,CBC,SHA,), - CS_ENTRY(0x0008, EXP,DES,CBC,SHA,,,,), - CS_ENTRY(0x0009, TLS,RSA,WITH,DES,CBC,SHA,,), - CS_ENTRY(0x0009, DES,CBC,SHA,,,,,), - CS_ENTRY(0x000B, TLS,DH,DSS,EXPORT,WITH,DES40,CBC,SHA), - CS_ENTRY(0x000B, EXP,DH,DSS,DES,CBC,SHA,,), - CS_ENTRY(0x000C, TLS,DH,DSS,WITH,DES,CBC,SHA,), - CS_ENTRY(0x000C, DH,DSS,DES,CBC,SHA,,,), - CS_ENTRY(0x000D, TLS,DH,DSS,WITH,3DES,EDE,CBC,SHA), - CS_ENTRY(0x000D, DH,DSS,DES,CBC3,SHA,,,), - CS_ENTRY(0x000E, TLS,DH,RSA,EXPORT,WITH,DES40,CBC,SHA), - CS_ENTRY(0x000E, EXP,DH,RSA,DES,CBC,SHA,,), - CS_ENTRY(0x000F, TLS,DH,RSA,WITH,DES,CBC,SHA,), - CS_ENTRY(0x000F, DH,RSA,DES,CBC,SHA,,,), - CS_ENTRY(0x0010, TLS,DH,RSA,WITH,3DES,EDE,CBC,SHA), - CS_ENTRY(0x0010, DH,RSA,DES,CBC3,SHA,,,), - CS_ENTRY(0x0011, TLS,DHE,DSS,EXPORT,WITH,DES40,CBC,SHA), - CS_ENTRY(0x0011, EXP,DHE,DSS,DES,CBC,SHA,,), - CS_ENTRY(0x0011, EXP,EDH,DSS,DES,CBC,SHA,,), /* bc */ - CS_ENTRY(0x0012, TLS,DHE,DSS,WITH,DES,CBC,SHA,), - CS_ENTRY(0x0012, DHE,DSS,DES,CBC,SHA,,,), - CS_ENTRY(0x0012, EDH,DSS,DES,CBC,SHA,,,), /* bc */ - CS_ENTRY(0x0013, TLS,DHE,DSS,WITH,3DES,EDE,CBC,SHA), - CS_ENTRY(0x0013, DHE,DSS,DES,CBC3,SHA,,,), - CS_ENTRY(0x0013, EDH,DSS,DES,CBC3,SHA,,,), /* bc */ - CS_ENTRY(0x0014, TLS,DHE,RSA,EXPORT,WITH,DES40,CBC,SHA), - CS_ENTRY(0x0014, EXP,DHE,RSA,DES,CBC,SHA,,), - CS_ENTRY(0x0014, EXP,EDH,RSA,DES,CBC,SHA,,), /* bc */ - CS_ENTRY(0x0015, TLS,DHE,RSA,WITH,DES,CBC,SHA,), - CS_ENTRY(0x0015, DHE,RSA,DES,CBC,SHA,,,), - CS_ENTRY(0x0015, EDH,RSA,DES,CBC,SHA,,,), /* bc */ - CS_ENTRY(0x0016, TLS,DHE,RSA,WITH,3DES,EDE,CBC,SHA), - CS_ENTRY(0x0016, DHE,RSA,DES,CBC3,SHA,,,), - CS_ENTRY(0x0016, EDH,RSA,DES,CBC3,SHA,,,), /* bc */ - CS_ENTRY(0x0017, TLS,DH,anon,EXPORT,WITH,RC4,40,MD5), - CS_ENTRY(0x0017, EXP,ADH,RC4,MD5,,,,), - CS_ENTRY(0x0018, TLS,DH,anon,WITH,RC4,128,MD5,), - CS_ENTRY(0x0018, ADH,RC4,MD5,,,,,), - CS_ENTRY(0x0019, TLS,DH,anon,EXPORT,WITH,DES40,CBC,SHA), - CS_ENTRY(0x0019, EXP,ADH,DES,CBC,SHA,,,), - CS_ENTRY(0x001A, TLS,DH,anon,WITH,DES,CBC,SHA,), - CS_ENTRY(0x001A, ADH,DES,CBC,SHA,,,,), - CS_ENTRY(0x001B, TLS,DH,anon,WITH,3DES,EDE,CBC,SHA), - CS_ENTRY(0x001B, ADH,DES,CBC3,SHA,,,,), - CS_ENTRY(0x0030, TLS,DH,DSS,WITH,AES,128,CBC,SHA), - CS_ENTRY(0x0030, DH,DSS,AES128,SHA,,,,), - CS_ENTRY(0x0031, TLS,DH,RSA,WITH,AES,128,CBC,SHA), - CS_ENTRY(0x0031, DH,RSA,AES128,SHA,,,,), - CS_ENTRY(0x0032, TLS,DHE,DSS,WITH,AES,128,CBC,SHA), - CS_ENTRY(0x0032, DHE,DSS,AES128,SHA,,,,), - CS_ENTRY(0x0034, TLS,DH,anon,WITH,AES,128,CBC,SHA), - CS_ENTRY(0x0034, ADH,AES128,SHA,,,,,), - CS_ENTRY(0x0036, TLS,DH,DSS,WITH,AES,256,CBC,SHA), - CS_ENTRY(0x0036, DH,DSS,AES256,SHA,,,,), - CS_ENTRY(0x0037, TLS,DH,RSA,WITH,AES,256,CBC,SHA), - CS_ENTRY(0x0037, DH,RSA,AES256,SHA,,,,), - CS_ENTRY(0x0038, TLS,DHE,DSS,WITH,AES,256,CBC,SHA), - CS_ENTRY(0x0038, DHE,DSS,AES256,SHA,,,,), - CS_ENTRY(0x003A, TLS,DH,anon,WITH,AES,256,CBC,SHA), - CS_ENTRY(0x003A, ADH,AES256,SHA,,,,,), - CS_ENTRY(0x003E, TLS,DH,DSS,WITH,AES,128,CBC,SHA256), - CS_ENTRY(0x003E, DH,DSS,AES128,SHA256,,,,), - CS_ENTRY(0x003F, TLS,DH,RSA,WITH,AES,128,CBC,SHA256), - CS_ENTRY(0x003F, DH,RSA,AES128,SHA256,,,,), - CS_ENTRY(0x0040, TLS,DHE,DSS,WITH,AES,128,CBC,SHA256), - CS_ENTRY(0x0040, DHE,DSS,AES128,SHA256,,,,), - CS_ENTRY(0x0068, TLS,DH,DSS,WITH,AES,256,CBC,SHA256), - CS_ENTRY(0x0068, DH,DSS,AES256,SHA256,,,,), - CS_ENTRY(0x0069, TLS,DH,RSA,WITH,AES,256,CBC,SHA256), - CS_ENTRY(0x0069, DH,RSA,AES256,SHA256,,,,), - CS_ENTRY(0x006A, TLS,DHE,DSS,WITH,AES,256,CBC,SHA256), - CS_ENTRY(0x006A, DHE,DSS,AES256,SHA256,,,,), - CS_ENTRY(0x006C, TLS,DH,anon,WITH,AES,128,CBC,SHA256), - CS_ENTRY(0x006C, ADH,AES128,SHA256,,,,,), - CS_ENTRY(0x006D, TLS,DH,anon,WITH,AES,256,CBC,SHA256), - CS_ENTRY(0x006D, ADH,AES256,SHA256,,,,,), - CS_ENTRY(0x008A, TLS,PSK,WITH,RC4,128,SHA,,), - CS_ENTRY(0x008A, PSK,RC4,SHA,,,,,), - CS_ENTRY(0x008B, TLS,PSK,WITH,3DES,EDE,CBC,SHA,), - CS_ENTRY(0x008B, PSK,3DES,EDE,CBC,SHA,,,), - CS_ENTRY(0x008E, TLS,DHE,PSK,WITH,RC4,128,SHA,), - CS_ENTRY(0x008E, DHE,PSK,RC4,SHA,,,,), - CS_ENTRY(0x008F, TLS,DHE,PSK,WITH,3DES,EDE,CBC,SHA), - CS_ENTRY(0x008F, DHE,PSK,3DES,EDE,CBC,SHA,,), - CS_ENTRY(0x0092, TLS,RSA,PSK,WITH,RC4,128,SHA,), - CS_ENTRY(0x0092, RSA,PSK,RC4,SHA,,,,), - CS_ENTRY(0x0093, TLS,RSA,PSK,WITH,3DES,EDE,CBC,SHA), - CS_ENTRY(0x0093, RSA,PSK,3DES,EDE,CBC,SHA,,), - CS_ENTRY(0x00A0, TLS,DH,RSA,WITH,AES,128,GCM,SHA256), - CS_ENTRY(0x00A0, DH,RSA,AES128,GCM,SHA256,,,), - CS_ENTRY(0x00A1, TLS,DH,RSA,WITH,AES,256,GCM,SHA384), - CS_ENTRY(0x00A1, DH,RSA,AES256,GCM,SHA384,,,), - CS_ENTRY(0x00A2, TLS,DHE,DSS,WITH,AES,128,GCM,SHA256), - CS_ENTRY(0x00A2, DHE,DSS,AES128,GCM,SHA256,,,), - CS_ENTRY(0x00A3, TLS,DHE,DSS,WITH,AES,256,GCM,SHA384), - CS_ENTRY(0x00A3, DHE,DSS,AES256,GCM,SHA384,,,), - CS_ENTRY(0x00A4, TLS,DH,DSS,WITH,AES,128,GCM,SHA256), - CS_ENTRY(0x00A4, DH,DSS,AES128,GCM,SHA256,,,), - CS_ENTRY(0x00A5, TLS,DH,DSS,WITH,AES,256,GCM,SHA384), - CS_ENTRY(0x00A5, DH,DSS,AES256,GCM,SHA384,,,), - CS_ENTRY(0x00A6, TLS,DH,anon,WITH,AES,128,GCM,SHA256), - CS_ENTRY(0x00A6, ADH,AES128,GCM,SHA256,,,,), - CS_ENTRY(0x00A7, TLS,DH,anon,WITH,AES,256,GCM,SHA384), - CS_ENTRY(0x00A7, ADH,AES256,GCM,SHA384,,,,), - CS_ENTRY(0xC002, TLS,ECDH,ECDSA,WITH,RC4,128,SHA,), - CS_ENTRY(0xC002, ECDH,ECDSA,RC4,SHA,,,,), - CS_ENTRY(0xC007, TLS,ECDHE,ECDSA,WITH,RC4,128,SHA,), - CS_ENTRY(0xC007, ECDHE,ECDSA,RC4,SHA,,,,), - CS_ENTRY(0xC00C, TLS,ECDH,RSA,WITH,RC4,128,SHA,), - CS_ENTRY(0xC00C, ECDH,RSA,RC4,SHA,,,,), - CS_ENTRY(0xC011, TLS,ECDHE,RSA,WITH,RC4,128,SHA,), - CS_ENTRY(0xC011, ECDHE,RSA,RC4,SHA,,,,), - CS_ENTRY(0xC015, TLS,ECDH,anon,WITH,NULL,SHA,,), - CS_ENTRY(0xC015, AECDH,NULL,SHA,,,,,), - CS_ENTRY(0xC016, TLS,ECDH,anon,WITH,RC4,128,SHA,), - CS_ENTRY(0xC016, AECDH,RC4,SHA,,,,,), - CS_ENTRY(0xC017, TLS,ECDH,anon,WITH,3DES,EDE,CBC,SHA), - CS_ENTRY(0xC017, AECDH,DES,CBC3,SHA,,,,), - CS_ENTRY(0xC018, TLS,ECDH,anon,WITH,AES,128,CBC,SHA), - CS_ENTRY(0xC018, AECDH,AES128,SHA,,,,,), - CS_ENTRY(0xC019, TLS,ECDH,anon,WITH,AES,256,CBC,SHA), - CS_ENTRY(0xC019, AECDH,AES256,SHA,,,,,), -#endif -#if defined(USE_MBEDTLS) +#ifdef USE_MBEDTLS /* entries marked ns are "non-standard", they are not in OpenSSL */ CS_ENTRY(0x0041, TLS,RSA,WITH,CAMELLIA,128,CBC,SHA,), CS_ENTRY(0x0041, CAMELLIA128,SHA,,,,,,), @@ -739,7 +560,7 @@ static int cs_str_to_zip(const char *cs_str, size_t cs_len, size_t len; /* split the cipher string by '-' or '_' */ - if(strncasecompare(cs_str, "TLS", 3)) + if(curl_strnequal(cs_str, "TLS", 3)) separator = '_'; do { @@ -754,7 +575,7 @@ static int cs_str_to_zip(const char *cs_str, size_t cs_len, /* lookup index for the part (skip empty string at 0) */ for(idx = 1, entry = cs_txt + 1; idx < CS_TXT_LEN; idx++) { size_t elen = strlen(entry); - if(elen == len && strncasecompare(entry, cur, len)) + if(elen == len && curl_strnequal(entry, cur, len)) break; entry += elen + 1; } @@ -887,5 +708,4 @@ int Curl_cipher_suite_get_str(uint16_t id, char *buf, size_t buf_size, return r; } -#endif /* defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || \ - defined(USE_BEARSSL) || defined(USE_RUSTLS) */ +#endif /* defined(USE_MBEDTLS) || defined(USE_RUSTLS) */ diff --git a/vendor/curl/lib/vtls/cipher_suite.h b/vendor/curl/lib/vtls/cipher_suite.h index cd556db10f6..a1dcbc524fe 100644 --- a/vendor/curl/lib/vtls/cipher_suite.h +++ b/vendor/curl/lib/vtls/cipher_suite.h @@ -26,8 +26,7 @@ #include "../curl_setup.h" -#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || \ - defined(USE_BEARSSL) || defined(USE_RUSTLS) +#if defined(USE_MBEDTLS) || defined(USE_RUSTLS) #include /* Lookup IANA id for cipher suite string, returns 0 if not recognized */ @@ -43,6 +42,5 @@ uint16_t Curl_cipher_suite_walk_str(const char **str, const char **end); int Curl_cipher_suite_get_str(uint16_t id, char *buf, size_t buf_size, bool prefer_rfc); -#endif /* defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || \ - defined(USE_BEARSSL) || defined(USE_RUSTLS) */ +#endif /* defined(USE_MBEDTLS) || defined(USE_RUSTLS) */ #endif /* HEADER_CURL_CIPHER_SUITE_H */ diff --git a/vendor/curl/lib/vtls/gtls.c b/vendor/curl/lib/vtls/gtls.c index 74c36fed943..7ecf0f05077 100644 --- a/vendor/curl/lib/vtls/gtls.c +++ b/vendor/curl/lib/vtls/gtls.c @@ -53,7 +53,6 @@ #include "../connect.h" /* for the connect timeout */ #include "../progress.h" #include "../select.h" -#include "../strcase.h" #include "../strdup.h" #include "../curlx/warnless.h" #include "x509asn1.h" @@ -91,21 +90,21 @@ static ssize_t gtls_push(void *s, const void *buf, size_t blen) struct gtls_ssl_backend_data *backend = (struct gtls_ssl_backend_data *)connssl->backend; struct Curl_easy *data = CF_DATA_CURRENT(cf); - ssize_t nwritten; + size_t nwritten; CURLcode result; DEBUGASSERT(data); - nwritten = Curl_conn_cf_send(cf->next, data, buf, blen, FALSE, &result); - CURL_TRC_CF(data, cf, "gtls_push(len=%zu) -> %zd, err=%d", - blen, nwritten, result); + result = Curl_conn_cf_send(cf->next, data, buf, blen, FALSE, &nwritten); + CURL_TRC_CF(data, cf, "gtls_push(len=%zu) -> %d, %zu", + blen, result, nwritten); backend->gtls.io_result = result; - if(nwritten < 0) { + if(result) { /* !checksrc! disable ERRNOVAR 1 */ gnutls_transport_set_errno(backend->gtls.session, (CURLE_AGAIN == result) ? EAGAIN : EINVAL); - nwritten = -1; + return -1; } - return nwritten; + return (ssize_t)nwritten; } static ssize_t gtls_pull(void *s, void *buf, size_t blen) @@ -115,7 +114,7 @@ static ssize_t gtls_pull(void *s, void *buf, size_t blen) struct gtls_ssl_backend_data *backend = (struct gtls_ssl_backend_data *)connssl->backend; struct Curl_easy *data = CF_DATA_CURRENT(cf); - ssize_t nread; + size_t nread; CURLcode result; DEBUGASSERT(data); @@ -129,19 +128,19 @@ static ssize_t gtls_pull(void *s, void *buf, size_t blen) } } - nread = Curl_conn_cf_recv(cf->next, data, buf, blen, &result); - CURL_TRC_CF(data, cf, "glts_pull(len=%zu) -> %zd, err=%d", - blen, nread, result); + result = Curl_conn_cf_recv(cf->next, data, buf, blen, &nread); + CURL_TRC_CF(data, cf, "glts_pull(len=%zu) -> %d, %zd", + blen, result, nread); backend->gtls.io_result = result; - if(nread < 0) { + if(result) { /* !checksrc! disable ERRNOVAR 1 */ gnutls_transport_set_errno(backend->gtls.session, (CURLE_AGAIN == result) ? EAGAIN : EINVAL); - nread = -1; + return -1; } else if(nread == 0) connssl->peer_closed = TRUE; - return nread; + return (ssize_t)nread; } /* gtls_init() @@ -303,9 +302,9 @@ static gnutls_x509_crt_fmt_t gnutls_do_file_type(const char *type) { if(!type || !type[0]) return GNUTLS_X509_FMT_PEM; - if(strcasecompare(type, "PEM")) + if(curl_strequal(type, "PEM")) return GNUTLS_X509_FMT_PEM; - if(strcasecompare(type, "DER")) + if(curl_strequal(type, "DER")) return GNUTLS_X509_FMT_DER; return GNUTLS_X509_FMT_PEM; /* default to PEM */ } @@ -335,12 +334,13 @@ gnutls_set_ssl_version_min_max(struct Curl_easy *data, if((ssl_version == CURL_SSLVERSION_DEFAULT) || (ssl_version == CURL_SSLVERSION_TLSv1)) ssl_version = CURL_SSLVERSION_TLSv1_0; - if(ssl_version_max == CURL_SSLVERSION_MAX_NONE) - ssl_version_max = CURL_SSLVERSION_MAX_DEFAULT; + if((ssl_version_max == CURL_SSLVERSION_MAX_NONE) || + (ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT)) + ssl_version_max = tls13support ? + CURL_SSLVERSION_MAX_TLSv1_3 : CURL_SSLVERSION_MAX_TLSv1_2; if(peer->transport == TRNSPRT_QUIC) { - if((ssl_version_max != CURL_SSLVERSION_MAX_DEFAULT) && - (ssl_version_max < CURL_SSLVERSION_MAX_TLSv1_3)) { + if(ssl_version_max < CURL_SSLVERSION_MAX_TLSv1_3) { failf(data, "QUIC needs at least TLS version 1.3"); return CURLE_SSL_CONNECT_ERROR; } @@ -348,19 +348,6 @@ gnutls_set_ssl_version_min_max(struct Curl_easy *data, return CURLE_OK; } - if(!tls13support) { - /* If the running GnuTLS does not support TLS 1.3, we must not specify a - prioritylist involving that since it will make GnuTLS return an en - error back at us */ - if((ssl_version_max == CURL_SSLVERSION_MAX_TLSv1_3) || - (ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT)) { - ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; - } - } - else if(ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT) { - ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_3; - } - switch(ssl_version | ssl_version_max) { case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0: *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" @@ -784,9 +771,9 @@ static int gtls_handshake_cb(gnutls_session_t session, unsigned int htype, } static CURLcode gtls_set_priority(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct gtls_ctx *gtls, - const char *priority) + struct Curl_easy *data, + struct gtls_ctx *gtls, + const char *priority) { struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); struct dynbuf buf; @@ -905,20 +892,15 @@ static CURLcode gtls_client_init(struct Curl_cfilter *cf, * on QUIC this is common. */ init_flags |= GNUTLS_ENABLE_EARLY_DATA; -#if defined(GNUTLS_FORCE_CLIENT_CERT) +#ifdef GNUTLS_FORCE_CLIENT_CERT init_flags |= GNUTLS_FORCE_CLIENT_CERT; #endif -#if defined(GNUTLS_NO_TICKETS_TLS12) +#ifdef GNUTLS_NO_TICKETS_TLS12 init_flags |= GNUTLS_NO_TICKETS_TLS12; -#elif defined(GNUTLS_NO_TICKETS) - /* Disable TLS session tickets for non 1.3 connections */ - if((config->version != CURL_SSLVERSION_TLSv1_3) && - (config->version != CURL_SSLVERSION_DEFAULT)) - init_flags |= GNUTLS_NO_TICKETS; #endif -#if defined(GNUTLS_NO_STATUS_REQUEST) +#ifdef GNUTLS_NO_STATUS_REQUEST if(!config->verifystatus) /* Disable the "status_request" TLS extension, enabled by default since GnuTLS 3.8.0. */ @@ -982,7 +964,7 @@ static CURLcode gtls_client_init(struct Curl_cfilter *cf, if(result) return result; } - if(ssl_config->cert_type && strcasecompare(ssl_config->cert_type, "P12")) { + if(ssl_config->cert_type && curl_strequal(ssl_config->cert_type, "P12")) { rc = gnutls_certificate_set_x509_simple_pkcs12_file( gtls->shared_creds->creds, config->clientcert, GNUTLS_X509_FMT_DER, ssl_config->key_passwd ? ssl_config->key_passwd : ""); @@ -1080,7 +1062,7 @@ static CURLcode gtls_on_session_reuse(struct Curl_cfilter *cf, connssl->earlydata_max = gnutls_record_get_max_early_data_size(backend->gtls.session); if((!connssl->earlydata_max || connssl->earlydata_max == 0xFFFFFFFFUL)) { - /* Seems to be GnuTLS way to signal no EarlyData in session */ + /* Seems to be no GnuTLS way to signal no EarlyData in session */ CURL_TRC_CF(data, cf, "SSL session does not allow earlydata"); } else if(!Curl_alpn_contains_proto(alpns, scs->alpn)) { @@ -1145,9 +1127,7 @@ CURLcode Curl_gtls_ctx_init(struct gtls_ctx *gctx, else { infof(data, "SSL reusing session with ALPN '%s'", scs->alpn ? scs->alpn : "-"); - if(ssl_config->earlydata && scs->alpn && - !cf->conn->connect_only && - (gnutls_protocol_get_version(gctx->session) == GNUTLS_TLS1_3)) { + if(ssl_config->earlydata && scs->alpn && !cf->conn->connect_only) { bool do_early_data = FALSE; if(sess_reuse_cb) { result = sess_reuse_cb(cf, data, &alpns, scs, &do_early_data); @@ -1308,6 +1288,212 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, return result; } +void Curl_gtls_report_handshake(struct Curl_easy *data, + struct gtls_ctx *gctx) +{ +#ifndef CURL_DISABLE_VERBOSE_STRINGS + if(Curl_trc_is_verbose(data)) { + const char *ptr; + gnutls_protocol_t version = gnutls_protocol_get_version(gctx->session); + + /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */ + ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(gctx->session), + gnutls_cipher_get(gctx->session), + gnutls_mac_get(gctx->session)); + + infof(data, "SSL connection using %s / %s", + gnutls_protocol_get_name(version), ptr); + } +#else + (void)data; + (void)gctx; +#endif +} + +static void gtls_msg_verify_result(struct Curl_easy *data, + struct ssl_peer *peer, + gnutls_x509_crt_t x509_cert, + bool was_verified, + bool needs_verified) +{ + char certname[65] = ""; /* limited to 64 chars by ASN.1 */ + size_t size = sizeof(certname); + int rc; + + rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME, + 0, /* the first and only one */ + FALSE, certname, &size); + if(rc) { + infof(data, "error fetching CN from cert:%s", gnutls_strerror(rc)); + certname[0] = 0; + } + + if(!was_verified) { + if(needs_verified) { + failf(data, "SSL: certificate subject name (%s) does not match " + "target hostname '%s'", certname, peer->dispname); + } + else + infof(data, " common name: %s (does not match '%s')", + certname, peer->dispname); + } + else + infof(data, " common name: %s (matched)", certname); +} + +static void gtls_infof_cert(struct Curl_easy *data, + gnutls_x509_crt_t x509_cert) +{ +#ifndef CURL_DISABLE_VERBOSE_STRINGS + if(Curl_trc_is_verbose(data)) { + gnutls_datum_t certfields; + int rc, algo; + time_t tstamp; + unsigned int bits; + + /* public key algorithm's parameters */ + algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits); + infof(data, " certificate public key: %s", + gnutls_pk_algorithm_get_name((gnutls_pk_algorithm_t)algo)); + + /* version of the X.509 certificate. */ + infof(data, " certificate version: #%d", + gnutls_x509_crt_get_version(x509_cert)); + + rc = gnutls_x509_crt_get_dn2(x509_cert, &certfields); + if(rc) + infof(data, "Failed to get certificate name"); + else { + infof(data, " subject: %s", certfields.data); + + tstamp = gnutls_x509_crt_get_activation_time(x509_cert); + showtime(data, "start date", tstamp); + + tstamp = gnutls_x509_crt_get_expiration_time(x509_cert); + showtime(data, "expire date", tstamp); + + gnutls_free(certfields.data); + } + + rc = gnutls_x509_crt_get_issuer_dn2(x509_cert, &certfields); + if(rc) + infof(data, "Failed to get certificate issuer"); + else { + infof(data, " issuer: %s", certfields.data); + + gnutls_free(certfields.data); + } + } +#else + (void)data; + (void)x509_cert; +#endif +} + +static CURLcode gtls_verify_ocsp_status(struct Curl_easy *data, + gnutls_session_t session) +{ + gnutls_ocsp_resp_t ocsp_resp = NULL; + gnutls_datum_t status_request; + gnutls_ocsp_cert_status_t status; + gnutls_x509_crl_reason_t reason; + CURLcode result = CURLE_OK; + int rc; + + rc = gnutls_ocsp_status_request_get(session, &status_request); + + if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { + failf(data, "No OCSP response received"); + result = CURLE_SSL_INVALIDCERTSTATUS; + goto out; + } + else if(rc < 0) { + failf(data, "Invalid OCSP response received"); + result = CURLE_SSL_INVALIDCERTSTATUS; + goto out; + } + + gnutls_ocsp_resp_init(&ocsp_resp); + + rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request); + if(rc < 0) { + failf(data, "Invalid OCSP response received"); + result = CURLE_SSL_INVALIDCERTSTATUS; + goto out; + } + + (void)gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL, + &status, NULL, NULL, NULL, &reason); + + switch(status) { + case GNUTLS_OCSP_CERT_GOOD: + break; + + case GNUTLS_OCSP_CERT_REVOKED: { + const char *crl_reason; + + switch(reason) { + default: + case GNUTLS_X509_CRLREASON_UNSPECIFIED: + crl_reason = "unspecified reason"; + break; + + case GNUTLS_X509_CRLREASON_KEYCOMPROMISE: + crl_reason = "private key compromised"; + break; + + case GNUTLS_X509_CRLREASON_CACOMPROMISE: + crl_reason = "CA compromised"; + break; + + case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED: + crl_reason = "affiliation has changed"; + break; + + case GNUTLS_X509_CRLREASON_SUPERSEDED: + crl_reason = "certificate superseded"; + break; + + case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION: + crl_reason = "operation has ceased"; + break; + + case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD: + crl_reason = "certificate is on hold"; + break; + + case GNUTLS_X509_CRLREASON_REMOVEFROMCRL: + crl_reason = "will be removed from delta CRL"; + break; + + case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN: + crl_reason = "privilege withdrawn"; + break; + + case GNUTLS_X509_CRLREASON_AACOMPROMISE: + crl_reason = "AA compromised"; + break; + } + + failf(data, "Server certificate was revoked: %s", crl_reason); + break; + } + + default: + case GNUTLS_OCSP_CERT_UNKNOWN: + failf(data, "Server certificate status is unknown"); + break; + } + + result = (status != GNUTLS_OCSP_CERT_GOOD) ? + CURLE_SSL_INVALIDCERTSTATUS : CURLE_OK; + +out: + if(ocsp_resp) + gnutls_ocsp_resp_deinit(ocsp_resp); + return result; +} + CURLcode Curl_gtls_verifyserver(struct Curl_easy *data, gnutls_session_t session, @@ -1319,32 +1505,12 @@ Curl_gtls_verifyserver(struct Curl_easy *data, unsigned int cert_list_size; const gnutls_datum_t *chainp; unsigned int verify_status = 0; - gnutls_x509_crt_t x509_cert, x509_issuer; - gnutls_datum_t issuerp; - gnutls_datum_t certfields; - char certname[65] = ""; /* limited to 64 chars by ASN.1 */ - size_t size; + gnutls_x509_crt_t x509_cert = NULL, x509_issuer = NULL; time_t certclock; int rc; CURLcode result = CURLE_OK; -#ifndef CURL_DISABLE_VERBOSE_STRINGS - const char *ptr; - int algo; - unsigned int bits; - gnutls_protocol_t version = gnutls_protocol_get_version(session); -#endif long * const certverifyresult = &ssl_config->certverifyresult; -#ifndef CURL_DISABLE_VERBOSE_STRINGS - /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */ - ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session), - gnutls_cipher_get(session), - gnutls_mac_get(session)); - - infof(data, "SSL connection using %s / %s", - gnutls_protocol_get_name(version), ptr); -#endif - /* This function will return the peer's raw certificate (chain) as sent by the peer. These certificates are in raw format (DER encoded for X.509). In case of a X.509 then a certificate list may be present. The @@ -1366,7 +1532,8 @@ Curl_gtls_verifyserver(struct Curl_easy *data, #endif failf(data, "failed to get server cert"); *certverifyresult = GNUTLS_E_NO_CERTIFICATE_FOUND; - return CURLE_PEER_FAILED_VERIFICATION; + result = CURLE_PEER_FAILED_VERIFICATION; + goto out; #ifdef USE_GNUTLS_SRP } #endif @@ -1379,7 +1546,7 @@ Curl_gtls_verifyserver(struct Curl_easy *data, result = Curl_ssl_init_certinfo(data, (int)cert_list_size); if(result) - return result; + goto out; for(i = 0; i < cert_list_size; i++) { const char *beg = (const char *) chainp[i].data; @@ -1387,7 +1554,7 @@ Curl_gtls_verifyserver(struct Curl_easy *data, result = Curl_extract_certinfo(data, (int)i, beg, end); if(result) - return result; + goto out; } } @@ -1403,7 +1570,8 @@ Curl_gtls_verifyserver(struct Curl_easy *data, if(rc < 0) { failf(data, "server cert verify failed: %d", rc); *certverifyresult = rc; - return CURLE_SSL_CONNECT_ERROR; + result = CURLE_SSL_CONNECT_ERROR; + goto out; } *certverifyresult = verify_status; @@ -1425,7 +1593,8 @@ Curl_gtls_verifyserver(struct Curl_easy *data, config->CAfile ? config->CAfile : "none", ssl_config->primary.CRLfile ? ssl_config->primary.CRLfile : "none"); - return CURLE_PEER_FAILED_VERIFICATION; + result = CURLE_PEER_FAILED_VERIFICATION; + goto out; } else infof(data, " server certificate verification FAILED"); @@ -1437,97 +1606,9 @@ Curl_gtls_verifyserver(struct Curl_easy *data, infof(data, " server certificate verification SKIPPED"); if(config->verifystatus) { - gnutls_datum_t status_request; - gnutls_ocsp_resp_t ocsp_resp; - gnutls_ocsp_cert_status_t status; - gnutls_x509_crl_reason_t reason; - - rc = gnutls_ocsp_status_request_get(session, &status_request); - - if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { - failf(data, "No OCSP response received"); - return CURLE_SSL_INVALIDCERTSTATUS; - } - - if(rc < 0) { - failf(data, "Invalid OCSP response received"); - return CURLE_SSL_INVALIDCERTSTATUS; - } - - gnutls_ocsp_resp_init(&ocsp_resp); - - rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request); - if(rc < 0) { - failf(data, "Invalid OCSP response received"); - return CURLE_SSL_INVALIDCERTSTATUS; - } - - (void)gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL, - &status, NULL, NULL, NULL, &reason); - - switch(status) { - case GNUTLS_OCSP_CERT_GOOD: - break; - - case GNUTLS_OCSP_CERT_REVOKED: { - const char *crl_reason; - - switch(reason) { - default: - case GNUTLS_X509_CRLREASON_UNSPECIFIED: - crl_reason = "unspecified reason"; - break; - - case GNUTLS_X509_CRLREASON_KEYCOMPROMISE: - crl_reason = "private key compromised"; - break; - - case GNUTLS_X509_CRLREASON_CACOMPROMISE: - crl_reason = "CA compromised"; - break; - - case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED: - crl_reason = "affiliation has changed"; - break; - - case GNUTLS_X509_CRLREASON_SUPERSEDED: - crl_reason = "certificate superseded"; - break; - - case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION: - crl_reason = "operation has ceased"; - break; - - case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD: - crl_reason = "certificate is on hold"; - break; - - case GNUTLS_X509_CRLREASON_REMOVEFROMCRL: - crl_reason = "will be removed from delta CRL"; - break; - - case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN: - crl_reason = "privilege withdrawn"; - break; - - case GNUTLS_X509_CRLREASON_AACOMPROMISE: - crl_reason = "AA compromised"; - break; - } - - failf(data, "Server certificate was revoked: %s", crl_reason); - break; - } - - default: - case GNUTLS_OCSP_CERT_UNKNOWN: - failf(data, "Server certificate status is unknown"); - break; - } - - gnutls_ocsp_resp_deinit(ocsp_resp); - if(status != GNUTLS_OCSP_CERT_GOOD) - return CURLE_SSL_INVALIDCERTSTATUS; + result = gtls_verify_ocsp_status(data, session); + if(result) + goto out; } else infof(data, " server certificate status verification SKIPPED"); @@ -1541,33 +1622,22 @@ Curl_gtls_verifyserver(struct Curl_easy *data, gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER); if(config->issuercert) { + gnutls_datum_t issuerp; gnutls_x509_crt_init(&x509_issuer); issuerp = load_file(config->issuercert); gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM); rc = (int)gnutls_x509_crt_check_issuer(x509_cert, x509_issuer); - gnutls_x509_crt_deinit(x509_issuer); unload_file(issuerp); if(rc <= 0) { failf(data, "server certificate issuer check failed (IssuerCert: %s)", config->issuercert ? config->issuercert : "none"); - gnutls_x509_crt_deinit(x509_cert); - return CURLE_SSL_ISSUER_ERROR; + result = CURLE_SSL_ISSUER_ERROR; + goto out; } infof(data, " server certificate issuer check OK (Issuer Cert: %s)", config->issuercert ? config->issuercert : "none"); } - size = sizeof(certname); - rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME, - 0, /* the first and only one */ - FALSE, - certname, - &size); - if(rc) { - infof(data, "error fetching CN from cert:%s", - gnutls_strerror(rc)); - } - /* This function will check if the given certificate's subject matches the given hostname. This is a basic implementation of the matching described in RFC2818 (HTTPS), which takes into account wildcards, and the subject @@ -1622,19 +1692,12 @@ Curl_gtls_verifyserver(struct Curl_easy *data, } } #endif - if(!rc) { - if(config->verifyhost) { - failf(data, "SSL: certificate subject name (%s) does not match " - "target hostname '%s'", certname, peer->dispname); - gnutls_x509_crt_deinit(x509_cert); - return CURLE_PEER_FAILED_VERIFICATION; - } - else - infof(data, " common name: %s (does not match '%s')", - certname, peer->dispname); - } - else - infof(data, " common name: %s (matched)", certname); + + result = (!rc && config->verifyhost) ? + CURLE_PEER_FAILED_VERIFICATION : CURLE_OK; + gtls_msg_verify_result(data, peer, x509_cert, rc, config->verifyhost); + if(result) + goto out; /* Check for time-based validity */ certclock = gnutls_x509_crt_get_expiration_time(x509_cert); @@ -1643,8 +1706,8 @@ Curl_gtls_verifyserver(struct Curl_easy *data, if(config->verifypeer) { failf(data, "server cert expiration date verify failed"); *certverifyresult = GNUTLS_CERT_EXPIRED; - gnutls_x509_crt_deinit(x509_cert); - return CURLE_SSL_CONNECT_ERROR; + result = CURLE_SSL_CONNECT_ERROR; + goto out; } else infof(data, " server certificate expiration date verify FAILED"); @@ -1654,8 +1717,8 @@ Curl_gtls_verifyserver(struct Curl_easy *data, if(config->verifypeer) { failf(data, "server certificate expiration date has passed."); *certverifyresult = GNUTLS_CERT_EXPIRED; - gnutls_x509_crt_deinit(x509_cert); - return CURLE_PEER_FAILED_VERIFICATION; + result = CURLE_PEER_FAILED_VERIFICATION; + goto out; } else infof(data, " server certificate expiration date FAILED"); @@ -1670,8 +1733,8 @@ Curl_gtls_verifyserver(struct Curl_easy *data, if(config->verifypeer) { failf(data, "server cert activation date verify failed"); *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED; - gnutls_x509_crt_deinit(x509_cert); - return CURLE_SSL_CONNECT_ERROR; + result = CURLE_SSL_CONNECT_ERROR; + goto out; } else infof(data, " server certificate activation date verify FAILED"); @@ -1681,8 +1744,8 @@ Curl_gtls_verifyserver(struct Curl_easy *data, if(config->verifypeer) { failf(data, "server certificate not activated yet."); *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED; - gnutls_x509_crt_deinit(x509_cert); - return CURLE_PEER_FAILED_VERIFICATION; + result = CURLE_PEER_FAILED_VERIFICATION; + goto out; } else infof(data, " server certificate activation date FAILED"); @@ -1695,59 +1758,17 @@ Curl_gtls_verifyserver(struct Curl_easy *data, result = pkp_pin_peer_pubkey(data, x509_cert, pinned_key); if(result != CURLE_OK) { failf(data, "SSL: public key does not match pinned public key"); - gnutls_x509_crt_deinit(x509_cert); - return result; + goto out; } } - /* Show: - - - subject - - start date - - expire date - - common name - - issuer - - */ - -#ifndef CURL_DISABLE_VERBOSE_STRINGS - /* public key algorithm's parameters */ - algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits); - infof(data, " certificate public key: %s", - gnutls_pk_algorithm_get_name((gnutls_pk_algorithm_t)algo)); - - /* version of the X.509 certificate. */ - infof(data, " certificate version: #%d", - gnutls_x509_crt_get_version(x509_cert)); - - - rc = gnutls_x509_crt_get_dn2(x509_cert, &certfields); - if(rc) - infof(data, "Failed to get certificate name"); - else { - infof(data, " subject: %s", certfields.data); - - certclock = gnutls_x509_crt_get_activation_time(x509_cert); - showtime(data, "start date", certclock); - - certclock = gnutls_x509_crt_get_expiration_time(x509_cert); - showtime(data, "expire date", certclock); - - gnutls_free(certfields.data); - } - - rc = gnutls_x509_crt_get_issuer_dn2(x509_cert, &certfields); - if(rc) - infof(data, "Failed to get certificate issuer"); - else { - infof(data, " issuer: %s", certfields.data); - - gnutls_free(certfields.data); - } -#endif - - gnutls_x509_crt_deinit(x509_cert); + gtls_infof_cert(data, x509_cert); +out: + if(x509_issuer) + gnutls_x509_crt_deinit(x509_issuer); + if(x509_cert) + gnutls_x509_crt_deinit(x509_cert); return result; } @@ -1877,6 +1898,9 @@ static CURLcode gtls_connect_common(struct Curl_cfilter *cf, if(connssl->connecting_state == ssl_connect_3) { gnutls_datum_t proto; int rc; + + Curl_gtls_report_handshake(data, &backend->gtls); + result = gtls_verifyserver(cf, data, backend->gtls.session); if(result) goto out; @@ -1943,53 +1967,54 @@ static bool gtls_data_pending(struct Curl_cfilter *cf, DEBUGASSERT(ctx && ctx->backend); backend = (struct gtls_ssl_backend_data *)ctx->backend; if(backend->gtls.session && - 0 != gnutls_record_check_pending(backend->gtls.session)) + gnutls_record_check_pending(backend->gtls.session) != 0) return TRUE; return FALSE; } -static ssize_t gtls_send(struct Curl_cfilter *cf, - struct Curl_easy *data, - const void *buf, - size_t blen, - CURLcode *curlcode) +static CURLcode gtls_send(struct Curl_cfilter *cf, + struct Curl_easy *data, + const void *buf, + size_t blen, + size_t *pnwritten) { struct ssl_connect_data *connssl = cf->ctx; struct gtls_ssl_backend_data *backend = (struct gtls_ssl_backend_data *)connssl->backend; - ssize_t rc; - size_t nwritten, total_written = 0; + CURLcode result = CURLE_OK; + ssize_t nwritten; + size_t remain = blen; (void)data; DEBUGASSERT(backend); + *pnwritten = 0; - while(blen) { + while(remain) { backend->gtls.io_result = CURLE_OK; - rc = gnutls_record_send(backend->gtls.session, buf, blen); + nwritten = gnutls_record_send(backend->gtls.session, buf, remain); - if(rc < 0) { - if(total_written && (rc == GNUTLS_E_AGAIN)) { - *curlcode = CURLE_OK; - rc = (ssize_t)total_written; + if(nwritten >= 0) { + *pnwritten += (size_t)nwritten; + DEBUGASSERT((size_t)nwritten <= remain); + buf = (char *)CURL_UNCONST(buf) + (size_t)nwritten; + remain -= (size_t)nwritten; + } + else { + if(*pnwritten && (nwritten == GNUTLS_E_AGAIN)) { + result = CURLE_OK; goto out; } - *curlcode = (rc == GNUTLS_E_AGAIN) ? + result = (nwritten == GNUTLS_E_AGAIN) ? CURLE_AGAIN : (backend->gtls.io_result ? backend->gtls.io_result : CURLE_SEND_ERROR); - - rc = -1; goto out; } - nwritten = (size_t)rc; - total_written += nwritten; - DEBUGASSERT(nwritten <= blen); - buf = (char *)CURL_UNCONST(buf) + nwritten; - blen -= nwritten; } - rc = total_written; out: - return rc; + CURL_TRC_CF(data, cf, "gtls_send(len=%zu) -> %d, %zu", + blen, result, *pnwritten); + return result; } /* @@ -2077,7 +2102,7 @@ static void gtls_close(struct Curl_cfilter *cf, struct gtls_ssl_backend_data *backend = (struct gtls_ssl_backend_data *)connssl->backend; - (void) data; + (void)data; DEBUGASSERT(backend); CURL_TRC_CF(data, cf, "close"); if(backend->gtls.session) { @@ -2095,50 +2120,49 @@ static void gtls_close(struct Curl_cfilter *cf, #endif } -static ssize_t gtls_recv(struct Curl_cfilter *cf, - struct Curl_easy *data, - char *buf, - size_t buffersize, - CURLcode *curlcode) +static CURLcode gtls_recv(struct Curl_cfilter *cf, + struct Curl_easy *data, + char *buf, size_t blen, + size_t *pnread) { struct ssl_connect_data *connssl = cf->ctx; struct gtls_ssl_backend_data *backend = (struct gtls_ssl_backend_data *)connssl->backend; - ssize_t ret; + CURLcode result = CURLE_OK; + ssize_t nread; (void)data; DEBUGASSERT(backend); - ret = gnutls_record_recv(backend->gtls.session, buf, buffersize); - if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) { - *curlcode = CURLE_AGAIN; - ret = -1; - goto out; - } + nread = gnutls_record_recv(backend->gtls.session, buf, blen); - if(ret == GNUTLS_E_REHANDSHAKE) { - /* BLOCKING call, this is bad but a work-around for now. Fixing this "the - proper way" takes a whole lot of work. */ - CURLcode result = handshake(cf, data); - if(result) - *curlcode = result; - else - *curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */ - ret = -1; - goto out; - } - - if(ret < 0) { - failf(data, "GnuTLS recv error (%d): %s", - (int)ret, gnutls_strerror((int)ret)); - *curlcode = backend->gtls.io_result ? - backend->gtls.io_result : CURLE_RECV_ERROR; - ret = -1; - goto out; + if(nread >= 0) + *pnread = (size_t)nread; + else { + if((nread == GNUTLS_E_AGAIN) || (nread == GNUTLS_E_INTERRUPTED)) { + result = CURLE_AGAIN; + goto out; + } + else if(nread == GNUTLS_E_REHANDSHAKE) { + /* BLOCKING call, this is bad but a work-around for now. Fixing this "the + proper way" takes a whole lot of work. */ + result = handshake(cf, data); + if(!result) + result = CURLE_AGAIN; /* then return as if this was a wouldblock */ + goto out; + } + else { + failf(data, "GnuTLS recv error (%d): %s", + (int)nread, gnutls_strerror((int)nread)); + result = backend->gtls.io_result ? + backend->gtls.io_result : CURLE_RECV_ERROR; + goto out; + } } out: - return ret; + CURL_TRC_CF(data, cf, "gtls_recv(len=%zu) -> 0, %zu", blen, *pnread); + return result; } size_t Curl_gtls_version(char *buffer, size_t size) @@ -2210,7 +2234,6 @@ const struct Curl_ssl Curl_ssl_gnutls = { NULL, /* set_engine */ NULL, /* set_engine_default */ NULL, /* engines_list */ - NULL, /* false_start */ gtls_sha256sum, /* sha256sum */ gtls_recv, /* recv decrypted data */ gtls_send, /* send data to encrypt */ diff --git a/vendor/curl/lib/vtls/gtls.h b/vendor/curl/lib/vtls/gtls.h index 35af9db1398..01f8b43ac8f 100644 --- a/vendor/curl/lib/vtls/gtls.h +++ b/vendor/curl/lib/vtls/gtls.h @@ -117,6 +117,10 @@ CURLcode Curl_gtls_cache_session(struct Curl_cfilter *cf, unsigned char *quic_tp, size_t quic_tp_len); +/* Report properties of a successful handshake */ +void Curl_gtls_report_handshake(struct Curl_easy *data, + struct gtls_ctx *gctx); + extern const struct Curl_ssl Curl_ssl_gnutls; #endif /* USE_GNUTLS */ diff --git a/vendor/curl/lib/vtls/hostcheck.c b/vendor/curl/lib/vtls/hostcheck.c index 8ca69941e82..23ba33951f1 100644 --- a/vendor/curl/lib/vtls/hostcheck.c +++ b/vendor/curl/lib/vtls/hostcheck.c @@ -24,8 +24,7 @@ #include "../curl_setup.h" -#if defined(USE_OPENSSL) \ - || defined(USE_SCHANNEL) +#if defined(USE_OPENSSL) || defined(USE_SCHANNEL) /* these backends use functions from this file */ #ifdef HAVE_NETINET_IN_H @@ -36,7 +35,6 @@ #endif #include "../curl_memrchr.h" #include "hostcheck.h" -#include "../strcase.h" #include "../hostip.h" #include "../curl_memory.h" @@ -50,7 +48,7 @@ static bool pmatch(const char *hostname, size_t hostlen, { if(hostlen != patternlen) return FALSE; - return strncasecompare(hostname, pattern, hostlen); + return curl_strnequal(hostname, pattern, hostlen); } /* diff --git a/vendor/curl/lib/vtls/hostcheck.h b/vendor/curl/lib/vtls/hostcheck.h index 6b4e3796443..b843d09c65e 100644 --- a/vendor/curl/lib/vtls/hostcheck.h +++ b/vendor/curl/lib/vtls/hostcheck.h @@ -26,8 +26,12 @@ #include +#if defined(USE_OPENSSL) || defined(USE_SCHANNEL) + /* returns TRUE if there is a match */ bool Curl_cert_hostcheck(const char *match_pattern, size_t matchlen, const char *hostname, size_t hostlen); +#endif + #endif /* HEADER_CURL_HOSTCHECK_H */ diff --git a/vendor/curl/lib/vtls/keylog.c b/vendor/curl/lib/vtls/keylog.c index 8487d43e8c6..2fd25089d97 100644 --- a/vendor/curl/lib/vtls/keylog.c +++ b/vendor/curl/lib/vtls/keylog.c @@ -134,14 +134,14 @@ Curl_tls_keylog_write(const char *label, /* Client Random */ for(i = 0; i < CLIENT_RANDOM_SIZE; i++) { - Curl_hexbyte(&line[pos], client_random[i], FALSE); + Curl_hexbyte(&line[pos], client_random[i]); pos += 2; } line[pos++] = ' '; /* Secret */ for(i = 0; i < secretlen; i++) { - Curl_hexbyte(&line[pos], secret[i], FALSE); + Curl_hexbyte(&line[pos], secret[i]); pos += 2; } line[pos++] = '\n'; diff --git a/vendor/curl/lib/vtls/mbedtls.c b/vendor/curl/lib/vtls/mbedtls.c index 7af207caa77..3280d9057c6 100644 --- a/vendor/curl/lib/vtls/mbedtls.c +++ b/vendor/curl/lib/vtls/mbedtls.c @@ -57,7 +57,6 @@ #endif /* MBEDTLS_VERSION_MAJOR >= 2 */ #include "cipher_suite.h" -#include "../strcase.h" #include "../urldata.h" #include "../sendf.h" #include "../curlx/inet_pton.h" @@ -105,8 +104,7 @@ struct mbed_ssl_backend_data { }; /* apply threading? */ -#if (defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \ - defined(_WIN32) +#if (defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || defined(_WIN32) #define HAS_THREADING_SUPPORT #endif @@ -172,9 +170,9 @@ static void mbed_debug(void *context, int level, const char *f_name, int line_nb, const char *line) { struct Curl_easy *data = (struct Curl_easy *)context; - (void) level; - (void) line_nb; - (void) f_name; + (void)level; + (void)line_nb; + (void)f_name; if(data) { size_t len = strlen(line); @@ -191,28 +189,27 @@ static int mbedtls_bio_cf_write(void *bio, { struct Curl_cfilter *cf = bio; struct Curl_easy *data = CF_DATA_CURRENT(cf); - ssize_t nwritten; + size_t nwritten; CURLcode result; DEBUGASSERT(data); if(!data) return 0; - nwritten = Curl_conn_cf_send(cf->next, data, (const char *)buf, blen, FALSE, - &result); - CURL_TRC_CF(data, cf, "mbedtls_bio_cf_out_write(len=%zu) -> %zd, err=%d", - blen, nwritten, result); - if(nwritten < 0 && CURLE_AGAIN == result) { - nwritten = MBEDTLS_ERR_SSL_WANT_WRITE; - } - return (int)nwritten; + result = Curl_conn_cf_send(cf->next, data, (const char *)buf, blen, FALSE, + &nwritten); + CURL_TRC_CF(data, cf, "mbedtls_bio_cf_out_write(len=%zu) -> %d, %zu", + blen, result, nwritten); + if(CURLE_AGAIN == result) + return MBEDTLS_ERR_SSL_WANT_WRITE; + return result ? -1 : (int)nwritten; } static int mbedtls_bio_cf_read(void *bio, unsigned char *buf, size_t blen) { struct Curl_cfilter *cf = bio; struct Curl_easy *data = CF_DATA_CURRENT(cf); - ssize_t nread; + size_t nread; CURLcode result; DEBUGASSERT(data); @@ -222,13 +219,12 @@ static int mbedtls_bio_cf_read(void *bio, unsigned char *buf, size_t blen) if(!buf) return 0; - nread = Curl_conn_cf_recv(cf->next, data, (char *)buf, blen, &result); - CURL_TRC_CF(data, cf, "mbedtls_bio_cf_in_read(len=%zu) -> %zd, err=%d", - blen, nread, result); - if(nread < 0 && CURLE_AGAIN == result) { - nread = MBEDTLS_ERR_SSL_WANT_READ; - } - return (int)nread; + result = Curl_conn_cf_recv(cf->next, data, (char *)buf, blen, &nread); + CURL_TRC_CF(data, cf, "mbedtls_bio_cf_in_read(len=%zu) -> %d, %zu", + blen, result, nread); + if(CURLE_AGAIN == result) + return MBEDTLS_ERR_SSL_WANT_READ; + return result ? -1 : (int)nread; } /* @@ -384,7 +380,7 @@ mbed_cipher_suite_walk_str(const char **str, const char **end) size_t len = *end - *str; if(!id) { - if(strncasecompare("TLS_ECJPAKE_WITH_AES_128_CCM_8", *str, len)) + if(curl_strnequal("TLS_ECJPAKE_WITH_AES_128_CCM_8", *str, len)) id = MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8; } return id; @@ -415,7 +411,7 @@ mbed_set_selected_ciphers(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; #ifndef HAS_TLS13_SUPPORT - (void) ciphers13, (void) j; + (void)ciphers13, (void)j; #else if(!ciphers13) { /* Add default TLSv1.3 ciphers to selection */ @@ -504,8 +500,8 @@ static void mbed_dump_cert_info(struct Curl_easy *data, const mbedtls_x509_crt *crt) { #if defined(CURL_DISABLE_VERBOSE_STRINGS) || \ - (MBEDTLS_VERSION_NUMBER >= 0x03000000 && defined(MBEDTLS_X509_REMOVE_INFO)) - (void) data, (void) crt; + (MBEDTLS_VERSION_NUMBER >= 0x03000000 && defined(MBEDTLS_X509_REMOVE_INFO)) + (void)data, (void)crt; #else const size_t bufsize = 16384; char *p, *buffer = malloc(bufsize); @@ -884,12 +880,12 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) } -#if defined(MBEDTLS_SSL_RENEGOTIATION) +#ifdef MBEDTLS_SSL_RENEGOTIATION mbedtls_ssl_conf_renegotiation(&backend->config, MBEDTLS_SSL_RENEGOTIATION_ENABLED); #endif -#if defined(MBEDTLS_SSL_SESSION_TICKETS) +#ifdef MBEDTLS_SSL_SESSION_TICKETS mbedtls_ssl_conf_session_tickets(&backend->config, MBEDTLS_SSL_SESSION_TICKETS_DISABLED); #endif @@ -1205,16 +1201,18 @@ mbed_new_session(struct Curl_cfilter *cf, struct Curl_easy *data) return result; } -static ssize_t mbed_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *mem, size_t len, - CURLcode *curlcode) +static CURLcode mbed_send(struct Curl_cfilter *cf, struct Curl_easy *data, + const void *mem, size_t len, + size_t *pnwritten) { struct ssl_connect_data *connssl = cf->ctx; struct mbed_ssl_backend_data *backend = (struct mbed_ssl_backend_data *)connssl->backend; - int ret = -1; + CURLcode result = CURLE_OK; + int nwritten; (void)data; + *pnwritten = 0; DEBUGASSERT(backend); /* mbedtls is picky when a mbedtls_ssl_write) was previously blocked. * It requires to be called with the same amount of bytes again, or it @@ -1227,28 +1225,29 @@ static ssize_t mbed_send(struct Curl_cfilter *cf, struct Curl_easy *data, len = backend->send_blocked_len; } - ret = mbedtls_ssl_write(&backend->ssl, (const unsigned char *)mem, len); + nwritten = mbedtls_ssl_write(&backend->ssl, (const unsigned char *)mem, len); - if(ret < 0) { + if(nwritten >= 0) { + *pnwritten = (size_t)nwritten; + backend->send_blocked = FALSE; + } + else { CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> -0x%04X", - len, -ret); - *curlcode = ((ret == MBEDTLS_ERR_SSL_WANT_WRITE) + len, -nwritten); + result = ((nwritten == MBEDTLS_ERR_SSL_WANT_WRITE) #ifdef HAS_TLS13_SUPPORT - || (ret == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) + || (nwritten == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) #endif ) ? CURLE_AGAIN : CURLE_SEND_ERROR; - ret = -1; - if((*curlcode == CURLE_AGAIN) && !backend->send_blocked) { + if((result == CURLE_AGAIN) && !backend->send_blocked) { backend->send_blocked = TRUE; backend->send_blocked_len = len; } } - else { - CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> %d", len, ret); - backend->send_blocked = FALSE; - } - return ret; + CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> %d, %zu", + len, result, *pnwritten); + return result; } static CURLcode mbedtls_shutdown(struct Curl_cfilter *cf, @@ -1367,48 +1366,48 @@ static void mbedtls_close(struct Curl_cfilter *cf, struct Curl_easy *data) } } -static ssize_t mbed_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t buffersize, - CURLcode *curlcode) +static CURLcode mbed_recv(struct Curl_cfilter *cf, struct Curl_easy *data, + char *buf, size_t buffersize, + size_t *pnread) { struct ssl_connect_data *connssl = cf->ctx; struct mbed_ssl_backend_data *backend = (struct mbed_ssl_backend_data *)connssl->backend; - int ret = -1; + CURLcode result = CURLE_OK; + int nread; (void)data; DEBUGASSERT(backend); + *pnread = 0; - ret = mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf, - buffersize); - if(ret <= 0) { + nread = mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf, buffersize); + if(nread > 0) + *pnread = (size_t)nread; + else { CURL_TRC_CF(data, cf, "mbedtls_ssl_read(len=%zu) -> -0x%04X", - buffersize, -ret); - switch(ret) { + buffersize, -nread); + switch(nread) { #ifdef HAS_SESSION_TICKETS case MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET: mbed_new_session(cf, data); FALLTHROUGH(); #endif case MBEDTLS_ERR_SSL_WANT_READ: - *curlcode = CURLE_AGAIN; - ret = -1; + result = CURLE_AGAIN; break; case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: - *curlcode = CURLE_OK; - ret = 0; + result = CURLE_OK; break; default: { char errorbuf[128]; - mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); - failf(data, "ssl_read returned: (-0x%04X) %s", -ret, errorbuf); - *curlcode = CURLE_RECV_ERROR; - ret = -1; + mbedtls_strerror(nread, errorbuf, sizeof(errorbuf)); + failf(data, "ssl_read returned: (-0x%04X) %s", -nread, errorbuf); + result = CURLE_RECV_ERROR; break; } } } - return (ssize_t)ret; + return result; } static size_t mbedtls_version(char *buffer, size_t size) @@ -1427,7 +1426,7 @@ static size_t mbedtls_version(char *buffer, size_t size) static CURLcode mbedtls_random(struct Curl_easy *data, unsigned char *entropy, size_t length) { -#if defined(MBEDTLS_CTR_DRBG_C) +#ifdef MBEDTLS_CTR_DRBG_C int ret; mbedtls_entropy_context ctr_entropy; mbedtls_ctr_drbg_context ctr_drbg; @@ -1620,7 +1619,6 @@ const struct Curl_ssl Curl_ssl_mbedtls = { NULL, /* set_engine */ NULL, /* set_engine_default */ NULL, /* engines_list */ - NULL, /* false_start */ mbedtls_sha256sum, /* sha256sum */ mbed_recv, /* recv decrypted data */ mbed_send, /* send data to encrypt */ diff --git a/vendor/curl/lib/vtls/openssl.c b/vendor/curl/lib/vtls/openssl.c index 0ce09ca06b7..dc4a6d122ce 100644 --- a/vendor/curl/lib/vtls/openssl.c +++ b/vendor/curl/lib/vtls/openssl.c @@ -54,12 +54,12 @@ #include "../connect.h" #include "../slist.h" #include "../select.h" +#include "../curlx/wait.h" #include "vtls.h" #include "vtls_int.h" #include "vtls_scache.h" #include "../vauth/vauth.h" #include "keylog.h" -#include "../strcase.h" #include "hostcheck.h" #include "../multiif.h" #include "../curlx/strparse.h" @@ -122,6 +122,12 @@ static void ossl_provider_cleanup(struct Curl_easy *data); #endif +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && \ + !defined(LIBRESSL_VERSION_NUMBER) && \ + !defined(OPENSSL_IS_BORINGSSL)) + #define HAVE_SSL_CTX_SET_DEFAULT_READ_BUFFER_LEN 1 +#endif + #include "../curlx/warnless.h" /* The last #include files should be: */ @@ -213,8 +219,8 @@ static void ossl_provider_cleanup(struct Curl_easy *data); #define OSSL_PACKAGE "BoringSSL" #elif defined(OPENSSL_IS_AWSLC) #define OSSL_PACKAGE "AWS-LC" -#elif (defined(USE_NGTCP2) && defined(USE_NGHTTP3) && \ - !defined(OPENSSL_QUIC_API2)) || defined(USE_MSH3) +#elif (defined(USE_NGTCP2) && defined(USE_NGHTTP3) && \ + !defined(OPENSSL_QUIC_API2)) #define OSSL_PACKAGE "quictls" #else #define OSSL_PACKAGE "OpenSSL" @@ -717,22 +723,23 @@ static int ossl_bio_cf_out_write(BIO *bio, const char *buf, int blen) struct ssl_connect_data *connssl = cf->ctx; struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend; struct Curl_easy *data = CF_DATA_CURRENT(cf); - ssize_t nwritten; - CURLcode result = CURLE_SEND_ERROR; + size_t nwritten; + CURLcode result; DEBUGASSERT(data); if(blen < 0) return 0; - nwritten = Curl_conn_cf_send(cf->next, data, buf, (size_t)blen, FALSE, - &result); - CURL_TRC_CF(data, cf, "ossl_bio_cf_out_write(len=%d) -> %d, err=%d", - blen, (int)nwritten, result); + result = Curl_conn_cf_send(cf->next, data, buf, (size_t)blen, FALSE, + &nwritten); + CURL_TRC_CF(data, cf, "ossl_bio_cf_out_write(len=%d) -> %d, %zu", + blen, result, nwritten); BIO_clear_retry_flags(bio); octx->io_result = result; - if(nwritten < 0) { + if(result) { if(CURLE_AGAIN == result) BIO_set_retry_write(bio); + return -1; } return (int)nwritten; } @@ -743,8 +750,8 @@ static int ossl_bio_cf_in_read(BIO *bio, char *buf, int blen) struct ssl_connect_data *connssl = cf->ctx; struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend; struct Curl_easy *data = CF_DATA_CURRENT(cf); - ssize_t nread; - CURLcode result = CURLE_RECV_ERROR; + size_t nread; + CURLcode result, r2; DEBUGASSERT(data); /* OpenSSL catches this case, so should we. */ @@ -753,31 +760,33 @@ static int ossl_bio_cf_in_read(BIO *bio, char *buf, int blen) if(blen < 0) return 0; - nread = Curl_conn_cf_recv(cf->next, data, buf, (size_t)blen, &result); - CURL_TRC_CF(data, cf, "ossl_bio_cf_in_read(len=%d) -> %d, err=%d", - blen, (int)nread, result); + result = Curl_conn_cf_recv(cf->next, data, buf, (size_t)blen, &nread); + CURL_TRC_CF(data, cf, "ossl_bio_cf_in_read(len=%d) -> %d, %zu", + blen, result, nread); BIO_clear_retry_flags(bio); octx->io_result = result; - if(nread < 0) { + if(result) { if(CURLE_AGAIN == result) BIO_set_retry_read(bio); } - else if(nread == 0) { - connssl->peer_closed = TRUE; + else { + /* feeding data to OpenSSL means SSL_read() might succeed */ + connssl->input_pending = TRUE; + if(nread == 0) + connssl->peer_closed = TRUE; } /* Before returning server replies to the SSL instance, we need * to have setup the x509 store or verification will fail. */ if(!octx->x509_store_setup) { - result = Curl_ssl_setup_x509_store(cf, data, octx->ssl_ctx); - if(result) { - octx->io_result = result; + r2 = Curl_ssl_setup_x509_store(cf, data, octx->ssl_ctx); + if(r2) { + octx->io_result = r2; return -1; } octx->x509_store_setup = TRUE; } - - return (int)nread; + return result ? -1 : (int)nread; } #if OPENSSL_VERSION_NUMBER < 0x10100000L @@ -949,7 +958,7 @@ static char *ossl_strerror(unsigned long error, char *buf, size_t size) static int passwd_callback(char *buf, int num, int encrypting, void *password) { - DEBUGASSERT(0 == encrypting); + DEBUGASSERT(encrypting == 0); if(!encrypting && num >= 0 && password) { int klen = curlx_uztosi(strlen((char *)password)); @@ -966,7 +975,7 @@ static int passwd_callback(char *buf, int num, int encrypting, */ static bool rand_enough(void) { - return 0 != RAND_status(); + return RAND_status() != 0; } static CURLcode ossl_seed(struct Curl_easy *data) @@ -995,7 +1004,7 @@ static CURLcode ossl_seed(struct Curl_easy *data) size_t i, i_max; for(i = 0, i_max = len / sizeof(struct curltime); i < i_max; ++i) { struct curltime tv = curlx_now(); - Curl_wait_ms(1); + curlx_wait_ms(1); tv.tv_sec *= (time_t)i + 1; tv.tv_usec *= (int)i + 2; tv.tv_sec ^= ((curlx_now().tv_sec + (time_t)curlx_now().tv_usec) * @@ -1048,15 +1057,15 @@ static int ossl_do_file_type(const char *type) { if(!type || !type[0]) return SSL_FILETYPE_PEM; - if(strcasecompare(type, "PEM")) + if(curl_strequal(type, "PEM")) return SSL_FILETYPE_PEM; - if(strcasecompare(type, "DER")) + if(curl_strequal(type, "DER")) return SSL_FILETYPE_ASN1; - if(strcasecompare(type, "PROV")) + if(curl_strequal(type, "PROV")) return SSL_FILETYPE_PROVIDER; - if(strcasecompare(type, "ENG")) + if(curl_strequal(type, "ENG")) return SSL_FILETYPE_ENGINE; - if(strcasecompare(type, "P12")) + if(curl_strequal(type, "P12")) return SSL_FILETYPE_PKCS12; return -1; } @@ -1109,13 +1118,13 @@ static int ssl_ui_writer(UI *ui, UI_STRING *uis) */ static bool is_pkcs11_uri(const char *string) { - return string && strncasecompare(string, "pkcs11:", 7); + return string && curl_strnequal(string, "pkcs11:", 7); } #endif static CURLcode ossl_set_engine(struct Curl_easy *data, const char *engine); -#if defined(OPENSSL_HAS_PROVIDERS) +#ifdef OPENSSL_HAS_PROVIDERS static CURLcode ossl_set_provider(struct Curl_easy *data, const char *provider); #endif @@ -1240,27 +1249,441 @@ use_certificate_chain_blob(SSL_CTX *ctx, const struct curl_blob *blob, return ret; } -static -int cert_stuff(struct Curl_easy *data, - SSL_CTX* ctx, - char *cert_file, - const struct curl_blob *cert_blob, - const char *cert_type, - char *key_file, - const struct curl_blob *key_blob, - const char *key_type, - char *key_passwd) +static int enginecheck(struct Curl_easy *data, + SSL_CTX* ctx, + const char *key_file, + const char *key_passwd) +#ifdef USE_OPENSSL_ENGINE +{ + EVP_PKEY *priv_key = NULL; + + /* Implicitly use pkcs11 engine if none was provided and the + * key_file is a PKCS#11 URI */ + if(!data->state.engine) { + if(is_pkcs11_uri(key_file)) { + if(ossl_set_engine(data, "pkcs11") != CURLE_OK) { + return 0; + } + } + } + + if(data->state.engine) { + UI_METHOD *ui_method = + UI_create_method(OSSL_UI_METHOD_CAST("curl user interface")); + if(!ui_method) { + failf(data, "unable do create " OSSL_PACKAGE + " user-interface method"); + return 0; + } + UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL())); + UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL())); + UI_method_set_reader(ui_method, ssl_ui_reader); + UI_method_set_writer(ui_method, ssl_ui_writer); + priv_key = ENGINE_load_private_key(data->state.engine, key_file, + ui_method, + CURL_UNCONST(key_passwd)); + UI_destroy_method(ui_method); + if(!priv_key) { + failf(data, "failed to load private key from crypto engine"); + return 0; + } + if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) { + failf(data, "unable to set private key"); + EVP_PKEY_free(priv_key); + return 0; + } + EVP_PKEY_free(priv_key); /* we do not need the handle any more... */ + } + else { + failf(data, "crypto engine not set, cannot load private key"); + return 0; + } + return 1; +} +#else +{ + (void)ctx; + (void)key_file; + (void)key_passwd; + failf(data, "SSL_FILETYPE_ENGINE not supported for private key"); + return 0; +} +#endif + +static int providercheck(struct Curl_easy *data, + SSL_CTX* ctx, + const char *key_file) +#ifdef OPENSSL_HAS_PROVIDERS { char error_buffer[256]; - bool check_privkey = TRUE; + /* Implicitly use pkcs11 provider if none was provided and the + * key_file is a PKCS#11 URI */ + if(!data->state.provider_loaded) { + if(is_pkcs11_uri(key_file)) { + if(ossl_set_provider(data, "pkcs11") != CURLE_OK) { + return 0; + } + } + } + + if(data->state.provider_loaded) { + /* Load the private key from the provider */ + EVP_PKEY *priv_key = NULL; + OSSL_STORE_CTX *store = NULL; + OSSL_STORE_INFO *info = NULL; + UI_METHOD *ui_method = + UI_create_method(OSSL_UI_METHOD_CAST("curl user interface")); + if(!ui_method) { + failf(data, "unable do create " OSSL_PACKAGE + " user-interface method"); + return 0; + } + UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL())); + UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL())); + UI_method_set_reader(ui_method, ssl_ui_reader); + UI_method_set_writer(ui_method, ssl_ui_writer); + + store = OSSL_STORE_open_ex(key_file, data->state.libctx, + data->state.propq, ui_method, NULL, NULL, + NULL, NULL); + if(!store) { + failf(data, "Failed to open OpenSSL store: %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer))); + return 0; + } + if(OSSL_STORE_expect(store, OSSL_STORE_INFO_PKEY) != 1) { + failf(data, "Failed to set store preference. Ignoring the error: %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer))); + } + + info = OSSL_STORE_load(store); + if(info) { + int ossl_type = OSSL_STORE_INFO_get_type(info); + + if(ossl_type == OSSL_STORE_INFO_PKEY) + priv_key = OSSL_STORE_INFO_get1_PKEY(info); + OSSL_STORE_INFO_free(info); + } + OSSL_STORE_close(store); + UI_destroy_method(ui_method); + if(!priv_key) { + failf(data, "No private key found in the openssl store: %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer))); + return 0; + } + + if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) { + failf(data, "unable to set private key [%s]", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer))); + EVP_PKEY_free(priv_key); + return 0; + } + EVP_PKEY_free(priv_key); /* we do not need the handle any more... */ + } + else { + failf(data, "crypto provider not set, cannot load private key"); + return 0; + } + return 1; +} +#else +{ + (void)ctx; + (void)key_file; + failf(data, "SSL_FILETYPE_PROVIDER not supported for private key"); + return 0; +} +#endif +static int engineload(struct Curl_easy *data, + SSL_CTX* ctx, + const char *cert_file) +#if defined(USE_OPENSSL_ENGINE) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME) +{ + char error_buffer[256]; + /* Implicitly use pkcs11 engine if none was provided and the + * cert_file is a PKCS#11 URI */ + if(!data->state.engine) { + if(is_pkcs11_uri(cert_file)) { + if(ossl_set_engine(data, "pkcs11") != CURLE_OK) { + return 0; + } + } + } + + if(data->state.engine) { + const char *cmd_name = "LOAD_CERT_CTRL"; + struct { + const char *cert_id; + X509 *cert; + } params; + + params.cert_id = cert_file; + params.cert = NULL; + + /* Does the engine supports LOAD_CERT_CTRL ? */ + if(!ENGINE_ctrl(data->state.engine, ENGINE_CTRL_GET_CMD_FROM_NAME, + 0, CURL_UNCONST(cmd_name), NULL)) { + failf(data, "ssl engine does not support loading certificates"); + return 0; + } + + /* Load the certificate from the engine */ + if(!ENGINE_ctrl_cmd(data->state.engine, cmd_name, + 0, ¶ms, NULL, 1)) { + failf(data, "ssl engine cannot load client cert with id" + " '%s' [%s]", cert_file, + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer))); + return 0; + } + + if(!params.cert) { + failf(data, "ssl engine did not initialized the certificate " + "properly."); + return 0; + } + + if(SSL_CTX_use_certificate(ctx, params.cert) != 1) { + failf(data, "unable to set client certificate [%s]", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer))); + return 0; + } + X509_free(params.cert); /* we do not need the handle any more... */ + } + else { + failf(data, "crypto engine not set, cannot load certificate"); + return 0; + } + return 1; +} +#else +{ + (void)ctx; + (void)cert_file; + failf(data, "SSL_FILETYPE_ENGINE not supported for certificate"); + return 0; +} +#endif + +static int providerload(struct Curl_easy *data, + SSL_CTX* ctx, + const char *cert_file) +#ifdef OPENSSL_HAS_PROVIDERS +{ + char error_buffer[256]; + /* Implicitly use pkcs11 provider if none was provided and the + * cert_file is a PKCS#11 URI */ + if(!data->state.provider_loaded) { + if(is_pkcs11_uri(cert_file)) { + if(ossl_set_provider(data, "pkcs11") != CURLE_OK) { + return 0; + } + } + } + + if(data->state.provider_loaded) { + /* Load the certificate from the provider */ + OSSL_STORE_INFO *info = NULL; + X509 *cert = NULL; + OSSL_STORE_CTX *store = + OSSL_STORE_open_ex(cert_file, data->state.libctx, + NULL, NULL, NULL, NULL, NULL, NULL); + if(!store) { + failf(data, "Failed to open OpenSSL store: %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer))); + return 0; + } + if(OSSL_STORE_expect(store, OSSL_STORE_INFO_CERT) != 1) { + failf(data, "Failed to set store preference. Ignoring the error: %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer))); + } + + info = OSSL_STORE_load(store); + if(info) { + int ossl_type = OSSL_STORE_INFO_get_type(info); + + if(ossl_type == OSSL_STORE_INFO_CERT) + cert = OSSL_STORE_INFO_get1_CERT(info); + OSSL_STORE_INFO_free(info); + } + OSSL_STORE_close(store); + if(!cert) { + failf(data, "No cert found in the openssl store: %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer))); + return 0; + } + + if(SSL_CTX_use_certificate(ctx, cert) != 1) { + failf(data, "unable to set client certificate [%s]", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer))); + return 0; + } + X509_free(cert); /* we do not need the handle any more... */ + } + else { + failf(data, "crypto provider not set, cannot load certificate"); + return 0; + } + return 1; +} +#else +{ + (void)ctx; + (void)cert_file; + failf(data, "SSL_FILETYPE_PROVIDER not supported for certificate"); + return 0; +} +#endif + +static int pkcs12load(struct Curl_easy *data, + SSL_CTX* ctx, + const struct curl_blob *cert_blob, + const char *cert_file, + const char *key_passwd) +{ + char error_buffer[256]; + BIO *cert_bio = NULL; + PKCS12 *p12 = NULL; + EVP_PKEY *pri; + X509 *x509; + int cert_done = 0; + STACK_OF(X509) *ca = NULL; + if(cert_blob) { + cert_bio = BIO_new_mem_buf(cert_blob->data, (int)(cert_blob->len)); + if(!cert_bio) { + failf(data, + "BIO_new_mem_buf NULL, " OSSL_PACKAGE + " error %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer)) ); + return 0; + } + } + else { + cert_bio = BIO_new(BIO_s_file()); + if(!cert_bio) { + failf(data, + "BIO_new return NULL, " OSSL_PACKAGE + " error %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer)) ); + return 0; + } + + if(BIO_read_filename(cert_bio, CURL_UNCONST(cert_file)) <= 0) { + failf(data, "could not open PKCS12 file '%s'", cert_file); + BIO_free(cert_bio); + return 0; + } + } + + p12 = d2i_PKCS12_bio(cert_bio, NULL); + BIO_free(cert_bio); + + if(!p12) { + failf(data, "error reading PKCS12 file '%s'", + cert_blob ? "(memory blob)" : cert_file); + return 0; + } + + PKCS12_PBE_add(); + + if(!PKCS12_parse(p12, key_passwd, &pri, &x509, &ca)) { + failf(data, + "could not parse PKCS12 file, check password, " OSSL_PACKAGE + " error %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer)) ); + PKCS12_free(p12); + return 0; + } + + PKCS12_free(p12); + + if(SSL_CTX_use_certificate(ctx, x509) != 1) { + failf(data, + "could not load PKCS12 client certificate, " OSSL_PACKAGE + " error %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer)) ); + goto fail; + } + + if(SSL_CTX_use_PrivateKey(ctx, pri) != 1) { + failf(data, "unable to use private key from PKCS12 file '%s'", + cert_file); + goto fail; + } + + if(!SSL_CTX_check_private_key(ctx)) { + failf(data, "private key from PKCS12 file '%s' " + "does not match certificate in same file", cert_file); + goto fail; + } + /* Set Certificate Verification chain */ + if(ca) { + while(sk_X509_num(ca)) { + /* + * Note that sk_X509_pop() is used below to make sure the cert is + * removed from the stack properly before getting passed to + * SSL_CTX_add_extra_chain_cert(), which takes ownership. Previously + * we used sk_X509_value() instead, but then we would clean it in the + * subsequent sk_X509_pop_free() call. + */ + X509 *x = sk_X509_pop(ca); + if(!SSL_CTX_add_client_CA(ctx, x)) { + X509_free(x); + failf(data, "cannot add certificate to client CA list"); + goto fail; + } + if(!SSL_CTX_add_extra_chain_cert(ctx, x)) { + X509_free(x); + failf(data, "cannot add certificate to certificate chain"); + goto fail; + } + } + } + + cert_done = 1; +fail: + EVP_PKEY_free(pri); + X509_free(x509); + sk_X509_pop_free(ca, X509_free); + if(!cert_done) + return 0; /* failure! */ + return 1; +} + + +static CURLcode client_cert(struct Curl_easy *data, + SSL_CTX* ctx, + char *cert_file, + const struct curl_blob *cert_blob, + const char *cert_type, + char *key_file, + const struct curl_blob *key_blob, + const char *key_type, + char *key_passwd) +{ + char error_buffer[256]; + bool check_privkey = TRUE; int file_type = ossl_do_file_type(cert_type); if(cert_file || cert_blob || (file_type == SSL_FILETYPE_ENGINE) || (file_type == SSL_FILETYPE_PROVIDER)) { SSL *ssl; X509 *x509; - int cert_done = 0; + bool pcks12_done = FALSE; int cert_use_result; if(key_passwd) { @@ -1270,7 +1693,6 @@ int cert_stuff(struct Curl_easy *data, SSL_CTX_set_default_passwd_cb(ctx, passwd_callback); } - switch(file_type) { case SSL_FILETYPE_PEM: /* SSL_CTX_use_certificate_chain_file() only works on PEM files */ @@ -1285,7 +1707,7 @@ int cert_stuff(struct Curl_easy *data, (cert_blob ? "CURLOPT_SSLCERT_BLOB" : cert_file), ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer)) ); - return 0; + return CURLE_SSL_CERTPROBLEM; } break; @@ -1305,249 +1727,29 @@ int cert_stuff(struct Curl_easy *data, (cert_blob ? "CURLOPT_SSLCERT_BLOB" : cert_file), ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer)) ); - return 0; + return CURLE_SSL_CERTPROBLEM; } break; - case SSL_FILETYPE_ENGINE: -#if defined(USE_OPENSSL_ENGINE) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME) - { - /* Implicitly use pkcs11 engine if none was provided and the - * cert_file is a PKCS#11 URI */ - if(!data->state.engine) { - if(is_pkcs11_uri(cert_file)) { - if(ossl_set_engine(data, "pkcs11") != CURLE_OK) { - return 0; - } - } - } - - if(data->state.engine) { - const char *cmd_name = "LOAD_CERT_CTRL"; - struct { - const char *cert_id; - X509 *cert; - } params; - - params.cert_id = cert_file; - params.cert = NULL; - - /* Does the engine supports LOAD_CERT_CTRL ? */ - if(!ENGINE_ctrl(data->state.engine, ENGINE_CTRL_GET_CMD_FROM_NAME, - 0, CURL_UNCONST(cmd_name), NULL)) { - failf(data, "ssl engine does not support loading certificates"); - return 0; - } - - /* Load the certificate from the engine */ - if(!ENGINE_ctrl_cmd(data->state.engine, cmd_name, - 0, ¶ms, NULL, 1)) { - failf(data, "ssl engine cannot load client cert with id" - " '%s' [%s]", cert_file, - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - return 0; - } - if(!params.cert) { - failf(data, "ssl engine did not initialized the certificate " - "properly."); - return 0; - } + case SSL_FILETYPE_ENGINE: + if(!engineload(data, ctx, cert_file)) + return CURLE_SSL_CERTPROBLEM; + break; - if(SSL_CTX_use_certificate(ctx, params.cert) != 1) { - failf(data, "unable to set client certificate [%s]", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - return 0; - } - X509_free(params.cert); /* we do not need the handle any more... */ - } - else { - failf(data, "crypto engine not set, cannot load certificate"); - return 0; - } - } - break; -#endif -#if defined(OPENSSL_HAS_PROVIDERS) - /* fall through to compatible provider */ case SSL_FILETYPE_PROVIDER: - { - /* Implicitly use pkcs11 provider if none was provided and the - * cert_file is a PKCS#11 URI */ - if(!data->state.provider) { - if(is_pkcs11_uri(cert_file)) { - if(ossl_set_provider(data, "pkcs11") != CURLE_OK) { - return 0; - } - } - } - - if(data->state.provider) { - /* Load the certificate from the provider */ - OSSL_STORE_INFO *info = NULL; - X509 *cert = NULL; - OSSL_STORE_CTX *store = - OSSL_STORE_open_ex(cert_file, data->state.libctx, - NULL, NULL, NULL, NULL, NULL, NULL); - if(!store) { - failf(data, "Failed to open OpenSSL store: %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - return 0; - } - if(OSSL_STORE_expect(store, OSSL_STORE_INFO_CERT) != 1) { - failf(data, "Failed to set store preference. Ignoring the error: %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - } - - info = OSSL_STORE_load(store); - if(info) { - int ossl_type = OSSL_STORE_INFO_get_type(info); - - if(ossl_type == OSSL_STORE_INFO_CERT) - cert = OSSL_STORE_INFO_get1_CERT(info); - OSSL_STORE_INFO_free(info); - } - OSSL_STORE_close(store); - if(!cert) { - failf(data, "No cert found in the openssl store: %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - return 0; - } - - if(SSL_CTX_use_certificate(ctx, cert) != 1) { - failf(data, "unable to set client certificate [%s]", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - return 0; - } - X509_free(cert); /* we do not need the handle any more... */ - } - else { - failf(data, "crypto provider not set, cannot load certificate"); - return 0; - } - } - break; -#endif + if(!providerload(data, ctx, cert_file)) + return CURLE_SSL_CERTPROBLEM; + break; case SSL_FILETYPE_PKCS12: - { - BIO *cert_bio = NULL; - PKCS12 *p12 = NULL; - EVP_PKEY *pri; - STACK_OF(X509) *ca = NULL; - if(cert_blob) { - cert_bio = BIO_new_mem_buf(cert_blob->data, (int)(cert_blob->len)); - if(!cert_bio) { - failf(data, - "BIO_new_mem_buf NULL, " OSSL_PACKAGE - " error %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer)) ); - return 0; - } - } - else { - cert_bio = BIO_new(BIO_s_file()); - if(!cert_bio) { - failf(data, - "BIO_new return NULL, " OSSL_PACKAGE - " error %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer)) ); - return 0; - } - - if(BIO_read_filename(cert_bio, cert_file) <= 0) { - failf(data, "could not open PKCS12 file '%s'", cert_file); - BIO_free(cert_bio); - return 0; - } - } - - p12 = d2i_PKCS12_bio(cert_bio, NULL); - BIO_free(cert_bio); - - if(!p12) { - failf(data, "error reading PKCS12 file '%s'", - cert_blob ? "(memory blob)" : cert_file); - return 0; - } - - PKCS12_PBE_add(); - - if(!PKCS12_parse(p12, key_passwd, &pri, &x509, &ca)) { - failf(data, - "could not parse PKCS12 file, check password, " OSSL_PACKAGE - " error %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer)) ); - PKCS12_free(p12); - return 0; - } - - PKCS12_free(p12); - - if(SSL_CTX_use_certificate(ctx, x509) != 1) { - failf(data, - "could not load PKCS12 client certificate, " OSSL_PACKAGE - " error %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer)) ); - goto fail; - } - - if(SSL_CTX_use_PrivateKey(ctx, pri) != 1) { - failf(data, "unable to use private key from PKCS12 file '%s'", - cert_file); - goto fail; - } - - if(!SSL_CTX_check_private_key (ctx)) { - failf(data, "private key from PKCS12 file '%s' " - "does not match certificate in same file", cert_file); - goto fail; - } - /* Set Certificate Verification chain */ - if(ca) { - while(sk_X509_num(ca)) { - /* - * Note that sk_X509_pop() is used below to make sure the cert is - * removed from the stack properly before getting passed to - * SSL_CTX_add_extra_chain_cert(), which takes ownership. Previously - * we used sk_X509_value() instead, but then we would clean it in the - * subsequent sk_X509_pop_free() call. - */ - X509 *x = sk_X509_pop(ca); - if(!SSL_CTX_add_client_CA(ctx, x)) { - X509_free(x); - failf(data, "cannot add certificate to client CA list"); - goto fail; - } - if(!SSL_CTX_add_extra_chain_cert(ctx, x)) { - X509_free(x); - failf(data, "cannot add certificate to certificate chain"); - goto fail; - } - } - } - - cert_done = 1; -fail: - EVP_PKEY_free(pri); - X509_free(x509); - sk_X509_pop_free(ca, X509_free); - if(!cert_done) - return 0; /* failure! */ + if(!pkcs12load(data, ctx, cert_blob, cert_file, key_passwd)) + return CURLE_SSL_CERTPROBLEM; + pcks12_done = TRUE; break; - } + default: failf(data, "not supported file type '%s' for certificate", cert_type); - return 0; + return CURLE_BAD_FUNCTION_ARGUMENT; } if((!key_file) && (!key_blob)) { @@ -1559,9 +1761,6 @@ int cert_stuff(struct Curl_easy *data, switch(file_type) { case SSL_FILETYPE_PEM: - if(cert_done) - break; - FALLTHROUGH(); case SSL_FILETYPE_ASN1: cert_use_result = key_blob ? use_privatekey_blob(ctx, key_blob, file_type, key_passwd) : @@ -1570,153 +1769,34 @@ int cert_stuff(struct Curl_easy *data, failf(data, "unable to set private key file: '%s' type %s", key_file ? key_file : "(memory blob)", key_type ? key_type : "PEM"); - return 0; + return CURLE_BAD_FUNCTION_ARGUMENT; } break; case SSL_FILETYPE_ENGINE: -#ifdef USE_OPENSSL_ENGINE - { - EVP_PKEY *priv_key = NULL; - - /* Implicitly use pkcs11 engine if none was provided and the - * key_file is a PKCS#11 URI */ - if(!data->state.engine) { - if(is_pkcs11_uri(key_file)) { - if(ossl_set_engine(data, "pkcs11") != CURLE_OK) { - return 0; - } - } - } + if(!enginecheck(data, ctx, key_file, key_passwd)) + return CURLE_SSL_CERTPROBLEM; + break; - if(data->state.engine) { - UI_METHOD *ui_method = - UI_create_method(OSSL_UI_METHOD_CAST("curl user interface")); - if(!ui_method) { - failf(data, "unable do create " OSSL_PACKAGE - " user-interface method"); - return 0; - } - UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL())); - UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL())); - UI_method_set_reader(ui_method, ssl_ui_reader); - UI_method_set_writer(ui_method, ssl_ui_writer); - priv_key = ENGINE_load_private_key(data->state.engine, key_file, - ui_method, - key_passwd); - UI_destroy_method(ui_method); - if(!priv_key) { - failf(data, "failed to load private key from crypto engine"); - return 0; - } - if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) { - failf(data, "unable to set private key"); - EVP_PKEY_free(priv_key); - return 0; - } - EVP_PKEY_free(priv_key); /* we do not need the handle any more... */ - } - else { - failf(data, "crypto engine not set, cannot load private key"); - return 0; - } - } - break; -#endif -#if defined(OPENSSL_HAS_PROVIDERS) - /* fall through to compatible provider */ case SSL_FILETYPE_PROVIDER: - { - /* Implicitly use pkcs11 provider if none was provided and the - * key_file is a PKCS#11 URI */ - if(!data->state.provider) { - if(is_pkcs11_uri(key_file)) { - if(ossl_set_provider(data, "pkcs11") != CURLE_OK) { - return 0; - } - } - } - - if(data->state.provider) { - /* Load the private key from the provider */ - EVP_PKEY *priv_key = NULL; - OSSL_STORE_CTX *store = NULL; - OSSL_STORE_INFO *info = NULL; - UI_METHOD *ui_method = - UI_create_method(OSSL_UI_METHOD_CAST("curl user interface")); - if(!ui_method) { - failf(data, "unable do create " OSSL_PACKAGE - " user-interface method"); - return 0; - } - UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL())); - UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL())); - UI_method_set_reader(ui_method, ssl_ui_reader); - UI_method_set_writer(ui_method, ssl_ui_writer); - - store = OSSL_STORE_open_ex(key_file, data->state.libctx, - data->state.propq, ui_method, NULL, NULL, - NULL, NULL); - if(!store) { - failf(data, "Failed to open OpenSSL store: %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - return 0; - } - if(OSSL_STORE_expect(store, OSSL_STORE_INFO_PKEY) != 1) { - failf(data, "Failed to set store preference. Ignoring the error: %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - } - - info = OSSL_STORE_load(store); - if(info) { - int ossl_type = OSSL_STORE_INFO_get_type(info); - - if(ossl_type == OSSL_STORE_INFO_PKEY) - priv_key = OSSL_STORE_INFO_get1_PKEY(info); - OSSL_STORE_INFO_free(info); - } - OSSL_STORE_close(store); - UI_destroy_method(ui_method); - if(!priv_key) { - failf(data, "No private key found in the openssl store: %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - return 0; - } - - if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) { - failf(data, "unable to set private key [%s]", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - EVP_PKEY_free(priv_key); - return 0; - } - EVP_PKEY_free(priv_key); /* we do not need the handle any more... */ - } - else { - failf(data, "crypto provider not set, cannot load private key"); - return 0; - } - } - break; -#endif + if(!providercheck(data, ctx, key_file)) + return CURLE_SSL_CERTPROBLEM; + break; case SSL_FILETYPE_PKCS12: - if(!cert_done) { + if(!pcks12_done) { failf(data, "file type P12 for private key not supported"); - return 0; + return CURLE_SSL_CERTPROBLEM; } break; default: failf(data, "not supported file type for private key"); - return 0; + return CURLE_BAD_FUNCTION_ARGUMENT; } ssl = SSL_new(ctx); if(!ssl) { failf(data, "unable to create an SSL structure"); - return 0; + return CURLE_OUT_OF_MEMORY; } x509 = SSL_get_certificate(ssl); @@ -1760,11 +1840,11 @@ int cert_stuff(struct Curl_easy *data, * the SSL context */ if(!SSL_CTX_check_private_key(ctx)) { failf(data, "Private key does not match the certificate public key"); - return 0; + return CURLE_SSL_CERTPROBLEM; } } } - return 1; + return CURLE_OK; } /* returns non-zero on failure */ @@ -1776,8 +1856,10 @@ static CURLcode x509_name_oneline(X509_NAME *a, struct dynbuf *d) CURLcode result = CURLE_OUT_OF_MEMORY; if(bio_out) { + unsigned long flags = XN_FLAG_SEP_SPLUS_SPC | + (XN_FLAG_ONELINE & ~ASN1_STRFLGS_ESC_MSB & ~XN_FLAG_SPC_EQ); curlx_dyn_reset(d); - rc = X509_NAME_print_ex(bio_out, a, 0, XN_FLAG_SEP_SPLUS_SPC); + rc = X509_NAME_print_ex(bio_out, a, 0, flags); if(rc != -1) { BIO_get_mem_ptr(bio_out, &biomem); result = curlx_dyn_addn(d, biomem->data, biomem->length); @@ -1898,6 +1980,9 @@ static CURLcode ossl_set_engine(struct Curl_easy *data, const char *name) result = CURLE_SSL_ENGINE_INITFAILED; e = NULL; } + else { + result = CURLE_OK; + } data->state.engine = e; return result; } @@ -1928,7 +2013,7 @@ static CURLcode ossl_set_engine_default(struct Curl_easy *data) } } #else - (void) data; + (void)data; #endif return CURLE_OK; } @@ -1951,11 +2036,11 @@ static struct curl_slist *ossl_engines_list(struct Curl_easy *data) list = beg; } #endif - (void) data; + (void)data; return list; } -#if defined(OPENSSL_HAS_PROVIDERS) +#ifdef OPENSSL_HAS_PROVIDERS static void ossl_provider_cleanup(struct Curl_easy *data) { @@ -2019,6 +2104,14 @@ static CURLcode ossl_set_provider(struct Curl_easy *data, const char *iname) data->state.libctx = libctx; } +#ifndef CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG + /* load the configuration file into the library context before checking the + * provider availability */ + if(!OSSL_LIB_CTX_load_config(data->state.libctx, NULL)) { + infof(data, "Failed to load default openssl config. Proceeding."); + } +#endif + if(OSSL_PROVIDER_available(data->state.libctx, name)) { /* already loaded through the configuration - no action needed */ data->state.provider_loaded = TRUE; @@ -2164,6 +2257,8 @@ static CURLcode ossl_shutdown(struct Curl_cfilter *cf, out: cf->shutdown = (result || *done); + if(cf->shutdown || (connssl->io_need != CURL_SSL_IO_NEED_NONE)) + connssl->input_pending = FALSE; return result; } @@ -2175,6 +2270,7 @@ static void ossl_close(struct Curl_cfilter *cf, struct Curl_easy *data) (void)data; DEBUGASSERT(octx); + connssl->input_pending = FALSE; if(octx->ssl) { SSL_free(octx->ssl); octx->ssl = NULL; @@ -2219,28 +2315,6 @@ static void ossl_close_all(struct Curl_easy *data) /* ====================================================== */ -/* - * Match subjectAltName against the hostname. - */ -static bool subj_alt_hostcheck(struct Curl_easy *data, - const char *match_pattern, - size_t matchlen, - const char *hostname, - size_t hostlen, - const char *dispname) -{ -#ifdef CURL_DISABLE_VERBOSE_STRINGS - (void)dispname; - (void)data; -#endif - if(Curl_cert_hostcheck(match_pattern, matchlen, hostname, hostlen)) { - infof(data, " subjectAltName: host \"%s\" matched cert's \"%s\"", - dispname, match_pattern); - return TRUE; - } - return FALSE; -} - /* Quote from RFC2818 section 3.1 "Server Identity" If a subjectAltName extension of type dNSName is present, that MUST @@ -2265,7 +2339,8 @@ static bool subj_alt_hostcheck(struct Curl_easy *data, */ static CURLcode ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn, - struct ssl_peer *peer, X509 *server_cert) + struct ssl_peer *peer, + X509 *server_cert) { bool matched = FALSE; int target; /* target type, GEN_DNS or GEN_IPADD */ @@ -2279,10 +2354,9 @@ static CURLcode ossl_verifyhost(struct Curl_easy *data, CURLcode result = CURLE_OK; bool dNSName = FALSE; /* if a dNSName field exists in the cert */ bool iPAddress = FALSE; /* if an iPAddress field exists in the cert */ - size_t hostlen; + size_t hostlen = strlen(peer->hostname); (void)conn; - hostlen = strlen(peer->hostname); switch(peer->type) { case CURL_SSL_PEER_IPV4: if(!curlx_inet_pton(AF_INET, peer->hostname, &addr)) @@ -2318,15 +2392,13 @@ static CURLcode ossl_verifyhost(struct Curl_easy *data, int numalts; int i; #endif - bool dnsmatched = FALSE; - bool ipmatched = FALSE; /* get amount of alternatives, RFC2459 claims there MUST be at least one, but we do not depend on it... */ numalts = sk_GENERAL_NAME_num(altnames); /* loop through all alternatives - until a dnsmatch */ - for(i = 0; (i < numalts) && !dnsmatched; i++) { + for(i = 0; (i < numalts) && !matched; i++) { /* get a handle to alternative name number i */ const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i); @@ -2355,10 +2427,10 @@ static CURLcode ossl_verifyhost(struct Curl_easy *data, if((altlen == strlen(altptr)) && /* if this is not true, there was an embedded zero in the name string and we cannot match it. */ - subj_alt_hostcheck(data, altptr, altlen, - peer->hostname, hostlen, - peer->dispname)) { - dnsmatched = TRUE; + Curl_cert_hostcheck(altptr, altlen, peer->hostname, hostlen)) { + matched = TRUE; + infof(data, " subjectAltName: host \"%s\" matched cert's \"%.*s\"", + peer->dispname, (int)altlen, altptr); } break; @@ -2366,7 +2438,7 @@ static CURLcode ossl_verifyhost(struct Curl_easy *data, /* compare alternative IP address if the data chunk is the same size our server IP address is */ if((altlen == addrlen) && !memcmp(altptr, &addr, altlen)) { - ipmatched = TRUE; + matched = TRUE; infof(data, " subjectAltName: host \"%s\" matched cert's IP address!", peer->dispname); @@ -2376,9 +2448,6 @@ static CURLcode ossl_verifyhost(struct Curl_easy *data, } } GENERAL_NAMES_free(altnames); - - if(dnsmatched || ipmatched) - matched = TRUE; } if(matched) @@ -2823,7 +2892,7 @@ static void ossl_trace(int direction, int ssl_ver, int content_type, Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT : CURLINFO_SSL_DATA_IN, (const char *)buf, len); - (void) ssl; + (void)ssl; } #endif @@ -2845,8 +2914,8 @@ ossl_set_ssl_version_min_max(struct Curl_cfilter *cf, SSL_CTX *ctx) long curl_ssl_version_max; /* convert curl min SSL version option to OpenSSL constant */ -#if (defined(OPENSSL_IS_BORINGSSL) || \ - defined(OPENSSL_IS_AWSLC) || \ +#if (defined(OPENSSL_IS_BORINGSSL) || \ + defined(OPENSSL_IS_AWSLC) || \ defined(LIBRESSL_VERSION_NUMBER)) uint16_t ossl_ssl_version_min = 0; uint16_t ossl_ssl_version_max = 0; @@ -2945,7 +3014,7 @@ ossl_set_ssl_version_min_max_legacy(ctx_option_t *ctx_options, long ssl_version = conn_config->version; long ssl_version_max = conn_config->version_max; - (void) data; /* In case it is unused. */ + (void)data; /* In case it is unused. */ switch(ssl_version) { case CURL_SSLVERSION_TLSv1_3: @@ -3258,8 +3327,10 @@ static CURLcode import_windows_cert_store(struct Curl_easy *data, continue; x509 = d2i_X509(NULL, &encoded_cert, (long)pContext->cbCertEncoded); - if(!x509) + if(!x509) { + ERR_clear_error(); continue; + } /* Try to import the certificate. This may fail for legitimate reasons such as duplicate certificate, which is allowed by MS but @@ -4102,7 +4173,7 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx, #else result = ossl_set_ssl_version_min_max_legacy(&ctx_options, cf, data); #endif - if(result != CURLE_OK) + if(result) return result; break; @@ -4112,6 +4183,21 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx, } SSL_CTX_set_options(octx->ssl_ctx, ctx_options); + SSL_CTX_set_read_ahead(octx->ssl_ctx, 1); + + /* Max TLS1.2 record size 0x4000 + 0x800. + OpenSSL supports processing "jumbo TLS record" (8 TLS records) in one go + for some algorithms, so match that here. + Experimentation shows that a slightly larger buffer is needed + to avoid short reads. + + However using a large buffer (8 packets) actually decreases performance. + 4 packets is better. + */ + +#ifdef HAVE_SSL_CTX_SET_DEFAULT_READ_BUFFER_LEN + SSL_CTX_set_default_read_buffer_len(octx->ssl_ctx, 0x401e * 4); +#endif #ifdef SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER /* We do retry writes sometimes from another buffer address */ @@ -4145,14 +4231,12 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx, #endif if(ssl_cert || ssl_cert_blob || ssl_cert_type) { - if(!result && - !cert_stuff(data, octx->ssl_ctx, - ssl_cert, ssl_cert_blob, ssl_cert_type, - ssl_config->key, ssl_config->key_blob, - ssl_config->key_type, ssl_config->key_passwd)) - result = CURLE_SSL_CERTPROBLEM; + result = client_cert(data, octx->ssl_ctx, + ssl_cert, ssl_cert_blob, ssl_cert_type, + ssl_config->key, ssl_config->key_blob, + ssl_config->key_type, ssl_config->key_passwd); if(result) - /* failf() is already done in cert_stuff() */ + /* failf() is already done in client_cert() */ return result; } @@ -4296,6 +4380,38 @@ static CURLcode ossl_on_session_reuse(struct Curl_cfilter *cf, return result; } +void Curl_ossl_report_handshake(struct Curl_easy *data, + struct ossl_ctx *octx) +{ +#ifndef CURL_DISABLE_VERBOSE_STRINGS + if(Curl_trc_is_verbose(data)) { + int psigtype_nid = NID_undef; + const char *negotiated_group_name = NULL; + +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + SSL_get_peer_signature_type_nid(octx->ssl, &psigtype_nid); +#if (OPENSSL_VERSION_NUMBER >= 0x30200000L) + negotiated_group_name = SSL_get0_group_name(octx->ssl); +#else + negotiated_group_name = + OBJ_nid2sn(SSL_get_negotiated_group(octx->ssl) & 0x0000FFFF); +#endif +#endif + + /* Informational message */ + infof(data, "SSL connection using %s / %s / %s / %s", + SSL_get_version(octx->ssl), + SSL_get_cipher(octx->ssl), + negotiated_group_name ? negotiated_group_name : "[blank]", + OBJ_nid2sn(psigtype_nid)); + } +#else + (void)data; + (void)octx; +#endif /* CURL_DISABLE_VERBOSE_STRINGS */ + +} + static CURLcode ossl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) { @@ -4444,7 +4560,7 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf, /* 1 is fine 0 is "not successful but was shut down controlled" <0 is "handshake was not successful, because a fatal error occurred" */ - if(1 != err) { + if(err != 1) { int detail = SSL_get_error(octx->ssl, err); CURL_TRC_CF(data, cf, "SSL_connect() -> err=%d, detail=%d", err, detail); @@ -4561,28 +4677,9 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf, } } else { - int psigtype_nid = NID_undef; - const char *negotiated_group_name = NULL; - /* we connected fine, we are not waiting for anything else. */ connssl->connecting_state = ssl_connect_3; - -#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) - SSL_get_peer_signature_type_nid(octx->ssl, &psigtype_nid); -#if (OPENSSL_VERSION_NUMBER >= 0x30200000L) - negotiated_group_name = SSL_get0_group_name(octx->ssl); -#else - negotiated_group_name = - OBJ_nid2sn(SSL_get_negotiated_group(octx->ssl) & 0x0000FFFF); -#endif -#endif - - /* Informational message */ - infof(data, "SSL connection using %s / %s / %s / %s", - SSL_get_version(octx->ssl), - SSL_get_cipher(octx->ssl), - negotiated_group_name ? negotiated_group_name : "[blank]", - OBJ_nid2sn(psigtype_nid)); + Curl_ossl_report_handshake(data, octx); #ifdef USE_ECH_OPENSSL # if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC) @@ -4639,10 +4736,10 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf, infof(data, "ECH: ech-hard failed"); return CURLE_SSL_CONNECT_ERROR; } - } - else { + } + else { infof(data, "ECH: result: status is not attempted"); - } + } # endif /* !OPENSSL_IS_BORINGSSL && !OPENSSL_IS_AWSLC */ #endif /* USE_ECH_OPENSSL */ @@ -4792,10 +4889,10 @@ static void infof_certstack(struct Curl_easy *data, const SSL *ssl) #define MAX_CERT_NAME_LENGTH 2048 -CURLcode Curl_oss_check_peer_cert(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ossl_ctx *octx, - struct ssl_peer *peer) +CURLcode Curl_ossl_check_peer_cert(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct ossl_ctx *octx, + struct ssl_peer *peer) { struct connectdata *conn = cf->conn; struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); @@ -5027,7 +5124,7 @@ static CURLcode ossl_connect_step3(struct Curl_cfilter *cf, * operations. */ - result = Curl_oss_check_peer_cert(cf, data, octx, &connssl->peer); + result = Curl_ossl_check_peer_cert(cf, data, octx, &connssl->peer); if(result) /* on error, remove sessions we might have in the pool */ Curl_ssl_scache_remove_all(cf, data, connssl->peer.scache_key); @@ -5195,20 +5292,15 @@ static bool ossl_data_pending(struct Curl_cfilter *cf, const struct Curl_easy *data) { struct ssl_connect_data *connssl = cf->ctx; - struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend; - (void)data; - DEBUGASSERT(connssl && octx); - if(octx->ssl && SSL_pending(octx->ssl)) - return TRUE; - return FALSE; + return connssl->input_pending; } -static ssize_t ossl_send(struct Curl_cfilter *cf, - struct Curl_easy *data, - const void *mem, - size_t len, - CURLcode *curlcode) +static CURLcode ossl_send(struct Curl_cfilter *cf, + struct Curl_easy *data, + const void *mem, + size_t len, + size_t *pnwritten) { /* SSL_write() is said to return 'int' while write() and send() returns 'size_t' */ @@ -5216,39 +5308,53 @@ static ssize_t ossl_send(struct Curl_cfilter *cf, char error_buffer[256]; sslerr_t sslerror; int memlen; - int rc; struct ssl_connect_data *connssl = cf->ctx; struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend; + CURLcode result = CURLE_OK; + int nwritten; (void)data; DEBUGASSERT(octx); - + *pnwritten = 0; ERR_clear_error(); connssl->io_need = CURL_SSL_IO_NEED_NONE; memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; - rc = SSL_write(octx->ssl, mem, memlen); + if(octx->blocked_ssl_write_len && (octx->blocked_ssl_write_len != memlen)) { + /* The previous SSL_write() call was blocked, using that length. + * We need to use that again or OpenSSL will freak out. A shorter + * length should not happen and is a bug in libcurl. */ + if(octx->blocked_ssl_write_len > memlen) { + DEBUGASSERT(0); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + memlen = octx->blocked_ssl_write_len; + } + octx->blocked_ssl_write_len = 0; + nwritten = SSL_write(octx->ssl, mem, memlen); - if(rc <= 0) { - err = SSL_get_error(octx->ssl, rc); + if(nwritten > 0) + *pnwritten = (size_t)nwritten; + else { + err = SSL_get_error(octx->ssl, nwritten); switch(err) { case SSL_ERROR_WANT_READ: connssl->io_need = CURL_SSL_IO_NEED_RECV; - *curlcode = CURLE_AGAIN; - rc = -1; + octx->blocked_ssl_write_len = memlen; + result = CURLE_AGAIN; goto out; case SSL_ERROR_WANT_WRITE: - *curlcode = CURLE_AGAIN; - rc = -1; + result = CURLE_AGAIN; + octx->blocked_ssl_write_len = memlen; goto out; case SSL_ERROR_SYSCALL: { int sockerr = SOCKERRNO; if(octx->io_result == CURLE_AGAIN) { - *curlcode = CURLE_AGAIN; - rc = -1; + octx->blocked_ssl_write_len = memlen; + result = CURLE_AGAIN; goto out; } sslerror = ERR_get_error(); @@ -5262,8 +5368,7 @@ static ssize_t ossl_send(struct Curl_cfilter *cf, failf(data, OSSL_PACKAGE " SSL_write: %s, errno %d", error_buffer, sockerr); - *curlcode = CURLE_SEND_ERROR; - rc = -1; + result = CURLE_SEND_ERROR; goto out; } case SSL_ERROR_SSL: { @@ -5272,49 +5377,50 @@ static ssize_t ossl_send(struct Curl_cfilter *cf, sslerror = ERR_get_error(); failf(data, "SSL_write() error: %s", ossl_strerror(sslerror, error_buffer, sizeof(error_buffer))); - *curlcode = CURLE_SEND_ERROR; - rc = -1; + result = CURLE_SEND_ERROR; goto out; } default: /* a true error */ failf(data, OSSL_PACKAGE " SSL_write: %s, errno %d", SSL_ERROR_to_str(err), SOCKERRNO); - *curlcode = CURLE_SEND_ERROR; - rc = -1; + result = CURLE_SEND_ERROR; goto out; } } - *curlcode = CURLE_OK; out: - return (ssize_t)rc; /* number of bytes */ + return result; } -static ssize_t ossl_recv(struct Curl_cfilter *cf, - struct Curl_easy *data, /* transfer */ - char *buf, /* store read data here */ - size_t buffersize, /* max amount to read */ - CURLcode *curlcode) +static CURLcode ossl_recv(struct Curl_cfilter *cf, + struct Curl_easy *data, /* transfer */ + char *buf, /* store read data here */ + size_t buffersize, /* max amount to read */ + size_t *pnread) { char error_buffer[256]; unsigned long sslerror; - ssize_t nread; int buffsize; struct connectdata *conn = cf->conn; struct ssl_connect_data *connssl = cf->ctx; struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend; + CURLcode result = CURLE_OK; + int nread; (void)data; DEBUGASSERT(octx); + *pnread = 0; ERR_clear_error(); connssl->io_need = CURL_SSL_IO_NEED_NONE; buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; - nread = (ssize_t)SSL_read(octx->ssl, buf, buffsize); + nread = SSL_read(octx->ssl, buf, buffsize); - if(nread <= 0) { + if(nread > 0) + *pnread = (size_t)nread; + else { /* failed SSL_read */ int err = SSL_get_error(octx->ssl, (int)nread); @@ -5329,21 +5435,18 @@ static ssize_t ossl_recv(struct Curl_cfilter *cf, connclose(conn, "TLS close_notify"); break; case SSL_ERROR_WANT_READ: - *curlcode = CURLE_AGAIN; - nread = -1; + result = CURLE_AGAIN; goto out; case SSL_ERROR_WANT_WRITE: connssl->io_need = CURL_SSL_IO_NEED_SEND; - *curlcode = CURLE_AGAIN; - nread = -1; + result = CURLE_AGAIN; goto out; default: /* openssl/ssl.h for SSL_ERROR_SYSCALL says "look at error stack/return value/errno" */ /* https://docs.openssl.org/master/man3/ERR_get_error/ */ if(octx->io_result == CURLE_AGAIN) { - *curlcode = CURLE_AGAIN; - nread = -1; + result = CURLE_AGAIN; goto out; } sslerror = ERR_get_error(); @@ -5360,40 +5463,50 @@ static ssize_t ossl_recv(struct Curl_cfilter *cf, SSL_ERROR_to_str(err)); failf(data, OSSL_PACKAGE " SSL_read: %s, errno %d", error_buffer, sockerr); - *curlcode = CURLE_RECV_ERROR; - nread = -1; + result = CURLE_RECV_ERROR; goto out; } - /* For debug builds be a little stricter and error on any - SSL_ERROR_SYSCALL. For example a server may have closed the connection - abruptly without a close_notify alert. For compatibility with older - peers we do not do this by default. #4624 - - We can use this to gauge how many users may be affected, and - if it goes ok eventually transition to allow in dev and release with - the newest OpenSSL: #if (OPENSSL_VERSION_NUMBER >= 0x10101000L) */ -#ifdef DEBUGBUILD - if(err == SSL_ERROR_SYSCALL) { - int sockerr = SOCKERRNO; - if(sockerr) - Curl_strerror(sockerr, error_buffer, sizeof(error_buffer)); + else if(err == SSL_ERROR_SYSCALL) { + if(octx->io_result) { + /* logging handling in underlying filter already */ + result = octx->io_result; + } + else if(connssl->peer_closed) { + failf(data, "Connection closed abruptly"); + result = CURLE_RECV_ERROR; + } else { - msnprintf(error_buffer, sizeof(error_buffer), - "Connection closed abruptly"); + /* We should no longer get here nowadays. But handle + * the error in case of some weirdness in the OSSL stack */ + int sockerr = SOCKERRNO; + if(sockerr) + Curl_strerror(sockerr, error_buffer, sizeof(error_buffer)); + else { + msnprintf(error_buffer, sizeof(error_buffer), + "Connection closed abruptly"); + } + failf(data, OSSL_PACKAGE " SSL_read: %s, errno %d", + error_buffer, sockerr); + result = CURLE_RECV_ERROR; } - failf(data, OSSL_PACKAGE " SSL_read: %s, errno %d" - " (Fatal because this is a curl debug build)", - error_buffer, sockerr); - *curlcode = CURLE_RECV_ERROR; - nread = -1; goto out; } -#endif } } out: - return nread; + if((!result && !*pnread) || (result == CURLE_AGAIN)) { + /* This happens when: + * - we read an EOF + * - OpenSSLs buffers are empty, there is no more data + * - OpenSSL read is blocked on writing something first + * - an incomplete TLS packet is buffered that cannot be read + * until more data arrives */ + connssl->input_pending = FALSE; + } + CURL_TRC_CF(data, cf, "ossl_recv(len=%zu) -> %d, %zu (in_pending=%d)", + buffersize, result, *pnread, connssl->input_pending); + return result; } static CURLcode ossl_get_channel_binding(struct Curl_easy *data, int sockindex, @@ -5487,7 +5600,7 @@ size_t Curl_ossl_version(char *buffer, size_t size) size_t count; const char *ver = OpenSSL_version(OPENSSL_VERSION); const char expected[] = OSSL_PACKAGE " "; /* ie "LibreSSL " */ - if(strncasecompare(ver, expected, sizeof(expected) - 1)) { + if(curl_strnequal(ver, expected, sizeof(expected) - 1)) { ver += sizeof(expected) - 1; } count = msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, ver); @@ -5572,7 +5685,7 @@ static CURLcode ossl_sha256sum(const unsigned char *tmp, /* input */ { EVP_MD_CTX *mdctx; unsigned int len = 0; - (void) unused; + (void)unused; mdctx = EVP_MD_CTX_create(); if(!mdctx) @@ -5645,7 +5758,6 @@ const struct Curl_ssl Curl_ssl_openssl = { ossl_set_engine, /* set_engine or provider */ ossl_set_engine_default, /* set_engine_default */ ossl_engines_list, /* engines_list */ - NULL, /* false_start */ #ifndef OPENSSL_NO_SHA256 ossl_sha256sum, /* sha256sum */ #else diff --git a/vendor/curl/lib/vtls/openssl.h b/vendor/curl/lib/vtls/openssl.h index 8d063e25acc..54cfc5d6632 100644 --- a/vendor/curl/lib/vtls/openssl.h +++ b/vendor/curl/lib/vtls/openssl.h @@ -68,6 +68,8 @@ struct ossl_ctx { X509* server_cert; BIO_METHOD *bio_method; CURLcode io_result; /* result of last BIO cfilter operation */ + /* blocked writes need to retry with same length, remember it */ + int blocked_ssl_write_len; #ifndef HAVE_KEYLOG_CALLBACK /* Set to true once a valid keylog entry has been created to avoid dupes. This is a bool and not a bitfield because it is passed by address. */ @@ -137,10 +139,14 @@ CURLcode Curl_ossl_add_session(struct Curl_cfilter *cf, * ssl config verifypeer or -host is set. Otherwise all this is for * informational purposes only! */ -CURLcode Curl_oss_check_peer_cert(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ossl_ctx *octx, - struct ssl_peer *peer); +CURLcode Curl_ossl_check_peer_cert(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct ossl_ctx *octx, + struct ssl_peer *peer); + +/* Report properties of a successful handshake */ +void Curl_ossl_report_handshake(struct Curl_easy *data, + struct ossl_ctx *octx); #endif /* USE_OPENSSL */ #endif /* HEADER_CURL_SSLUSE_H */ diff --git a/vendor/curl/lib/vtls/rustls.c b/vendor/curl/lib/vtls/rustls.c index cb9fd6230a5..7d0fddaa308 100644 --- a/vendor/curl/lib/vtls/rustls.c +++ b/vendor/curl/lib/vtls/rustls.c @@ -43,6 +43,10 @@ #include "cipher_suite.h" #include "x509asn1.h" +/* The last #include files should be: */ +#include "../curl_memory.h" +#include "../memdebug.h" + struct rustls_ssl_backend_data { const struct rustls_client_config *config; @@ -101,9 +105,11 @@ read_cb(void *userdata, uint8_t *buf, uintptr_t len, uintptr_t *out_n) struct ssl_connect_data *const connssl = io_ctx->cf->ctx; CURLcode result; int ret = 0; - ssize_t nread = Curl_conn_cf_recv(io_ctx->cf->next, io_ctx->data, - (char *)buf, len, &result); - if(nread < 0) { + size_t nread; + + result = Curl_conn_cf_recv(io_ctx->cf->next, io_ctx->data, + (char *)buf, len, &nread); + if(result) { nread = 0; /* !checksrc! disable ERRNOVAR 4 */ if(CURLE_AGAIN == result) @@ -114,8 +120,8 @@ read_cb(void *userdata, uint8_t *buf, uintptr_t len, uintptr_t *out_n) else if(nread == 0) connssl->peer_closed = TRUE; *out_n = (uintptr_t)nread; - CURL_TRC_CF(io_ctx->data, io_ctx->cf, "cf->next recv(len=%zu) -> %zd, %d", - len, nread, result); + CURL_TRC_CF(io_ctx->data, io_ctx->cf, "cf->next recv(len=%zu) -> %d, %zu", + len, result, nread); return ret; } @@ -125,10 +131,11 @@ write_cb(void *userdata, const uint8_t *buf, uintptr_t len, uintptr_t *out_n) const struct io_ctx *io_ctx = userdata; CURLcode result; int ret = 0; - ssize_t nwritten = Curl_conn_cf_send(io_ctx->cf->next, io_ctx->data, - (const char *)buf, len, FALSE, - &result); - if(nwritten < 0) { + size_t nwritten; + + result = Curl_conn_cf_send(io_ctx->cf->next, io_ctx->data, + (const char *)buf, len, FALSE, &nwritten); + if(result) { nwritten = 0; if(CURLE_AGAIN == result) ret = EAGAIN; @@ -136,8 +143,8 @@ write_cb(void *userdata, const uint8_t *buf, uintptr_t len, uintptr_t *out_n) ret = EINVAL; } *out_n = (uintptr_t)nwritten; - CURL_TRC_CF(io_ctx->data, io_ctx->cf, "cf->next send(len=%zu) -> %zd, %d", - len, nwritten, result); + CURL_TRC_CF(io_ctx->data, io_ctx->cf, "cf->next send(len=%zu) -> %d, %zu", + len, result, nwritten); return ret; } @@ -192,37 +199,37 @@ static ssize_t tls_recv_more(struct Curl_cfilter *cf, * buffer, and process packets, but will not consume bytes from Rustls' * plaintext output buffer. */ -static ssize_t +static CURLcode cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *plainbuf, size_t plainlen, CURLcode *err) + char *plainbuf, size_t plainlen, size_t *pnread) { const struct ssl_connect_data *const connssl = cf->ctx; struct rustls_ssl_backend_data *const backend = (struct rustls_ssl_backend_data *)connssl->backend; struct rustls_connection *rconn = NULL; + CURLcode result = CURLE_OK; size_t n = 0; - size_t plain_bytes_copied = 0; rustls_result rresult = 0; - ssize_t nread; bool eof = FALSE; DEBUGASSERT(backend); + *pnread = 0; rconn = backend->conn; - while(plain_bytes_copied < plainlen) { + while(*pnread < plainlen) { if(!backend->data_in_pending) { - if(tls_recv_more(cf, data, err) < 0) { - if(*err != CURLE_AGAIN) { - nread = -1; + if(tls_recv_more(cf, data, &result) < 0) { + if(result != CURLE_AGAIN) { goto out; } + result = CURLE_OK; break; } } rresult = rustls_connection_read(rconn, - (uint8_t *)plainbuf + plain_bytes_copied, - plainlen - plain_bytes_copied, + (uint8_t *)plainbuf + *pnread, + plainlen - *pnread, &n); if(rresult == RUSTLS_RESULT_PLAINTEXT_EMPTY) { backend->data_in_pending = FALSE; @@ -230,15 +237,13 @@ cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data, else if(rresult == RUSTLS_RESULT_UNEXPECTED_EOF) { failf(data, "rustls: peer closed TCP connection " "without first closing TLS connection"); - *err = CURLE_RECV_ERROR; - nread = -1; + result = CURLE_RECV_ERROR; goto out; } else if(rresult != RUSTLS_RESULT_OK) { /* n always equals 0 in this case, do not need to check it */ rustls_failf(data, rresult, "rustls_connection_read"); - *err = CURLE_RECV_ERROR; - nread = -1; + result = CURLE_RECV_ERROR; goto out; } else if(n == 0) { @@ -249,27 +254,18 @@ cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data, break; } else { - plain_bytes_copied += n; + *pnread += n; } } - if(plain_bytes_copied) { - *err = CURLE_OK; - nread = (ssize_t)plain_bytes_copied; - } - else if(eof) { - *err = CURLE_OK; - nread = 0; - } - else { - *err = CURLE_AGAIN; - nread = -1; + if(!eof && !*pnread) { + result = CURLE_AGAIN; } out: - CURL_TRC_CF(data, cf, "cf_recv(len=%zu) -> %zd, %d", - plainlen, nread, *err); - return nread; + CURL_TRC_CF(data, cf, "rustls_recv(len=%zu) -> %d, %zu", + plainlen, result, *pnread); + return result; } static CURLcode cr_flush_out(struct Curl_cfilter *cf, struct Curl_easy *data, @@ -317,9 +313,9 @@ static CURLcode cr_flush_out(struct Curl_cfilter *cf, struct Curl_easy *data, * In that case, it will not read anything into Rustls' plaintext input buffer. * It will only drain Rustls' plaintext output buffer into the socket. */ -static ssize_t +static CURLcode cr_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *plainbuf, size_t plainlen, CURLcode *err) + const void *plainbuf, size_t plainlen, size_t *pnwritten) { const struct ssl_connect_data *const connssl = cf->ctx; struct rustls_ssl_backend_data *const backend = @@ -327,10 +323,11 @@ cr_send(struct Curl_cfilter *cf, struct Curl_easy *data, struct rustls_connection *rconn = NULL; size_t plainwritten = 0; const unsigned char *buf = plainbuf; + CURLcode result = CURLE_OK; size_t blen = plainlen; - ssize_t nwritten = 0; DEBUGASSERT(backend); + *pnwritten = 0; rconn = backend->conn; DEBUGASSERT(rconn); @@ -341,18 +338,18 @@ cr_send(struct Curl_cfilter *cf, struct Curl_easy *data, * if successful, deduct the previous plain bytes from the current * send. */ if(backend->plain_out_buffered) { - *err = cr_flush_out(cf, data, rconn); + result = cr_flush_out(cf, data, rconn); CURL_TRC_CF(data, cf, "cf_send: flushing %zu previously added bytes -> %d", - backend->plain_out_buffered, *err); - if(*err) - return -1; + backend->plain_out_buffered, result); + if(result) + return result; if(blen > backend->plain_out_buffered) { blen -= backend->plain_out_buffered; buf += backend->plain_out_buffered; } else blen = 0; - nwritten += (ssize_t)backend->plain_out_buffered; + *pnwritten += (ssize_t)backend->plain_out_buffered; backend->plain_out_buffered = 0; } @@ -362,37 +359,35 @@ cr_send(struct Curl_cfilter *cf, struct Curl_easy *data, rresult = rustls_connection_write(rconn, buf, blen, &plainwritten); if(rresult != RUSTLS_RESULT_OK) { rustls_failf(data, rresult, "rustls_connection_write"); - *err = CURLE_WRITE_ERROR; - return -1; + result = CURLE_WRITE_ERROR; + goto out; } else if(plainwritten == 0) { failf(data, "rustls_connection_write: EOF"); - *err = CURLE_WRITE_ERROR; - return -1; + result = CURLE_WRITE_ERROR; + goto out; } } - *err = cr_flush_out(cf, data, rconn); - if(*err) { - if(CURLE_AGAIN == *err) { + result = cr_flush_out(cf, data, rconn); + if(result) { + if(CURLE_AGAIN == result) { /* The TLS bytes may have been partially written, but we fail the * complete send() and remember how much we already added to Rustls. */ - CURL_TRC_CF(data, cf, "cf_send: EAGAIN, remember we added %zu plain" - " bytes already to Rustls", blen); backend->plain_out_buffered = plainwritten; - if(nwritten) { - *err = CURLE_OK; - return (ssize_t)nwritten; + if(*pnwritten) { + result = CURLE_OK; } } - return -1; + goto out; } else - nwritten += (ssize_t)plainwritten; + *pnwritten += (ssize_t)plainwritten; - CURL_TRC_CF(data, cf, "cf_send(len=%zu) -> %d, %zd", - plainlen, *err, nwritten); - return nwritten; +out: + CURL_TRC_CF(data, cf, "rustls_send(len=%zu) -> %d, %zd", + plainlen, result, *pnwritten); + return result; } /* A server certificate verify callback for Rustls that always returns @@ -588,7 +583,7 @@ init_config_builder(struct Curl_easy *data, goto cleanup; } -#if defined(USE_ECH) +#ifdef USE_ECH if(ECH_ENABLED(data)) { tls_versions[0] = RUSTLS_TLS_VERSION_TLSV1_3; tls_versions_len = 1; @@ -864,7 +859,7 @@ init_config_builder_client_auth(struct Curl_easy *data, } else if(!conn_config->clientcert && ssl_config->key) { failf(data, "rustls: must provide certificate with key '%s'", - conn_config->clientcert); + ssl_config->key); return CURLE_SSL_CERTPROBLEM; } @@ -923,7 +918,7 @@ init_config_builder_client_auth(struct Curl_easy *data, return result; } -#if defined(USE_ECH) +#ifdef USE_ECH static CURLcode init_config_builder_ech(struct Curl_easy *data, const struct ssl_connect_data *connssl, @@ -1082,7 +1077,7 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data, } } -#if defined(USE_ECH) +#ifdef USE_ECH if(ECH_ENABLED(data)) { result = init_config_builder_ech(data, connssl, config_builder); if(result != CURLE_OK && data->set.tls_ech & CURLECH_HARD) { @@ -1181,8 +1176,9 @@ cr_connect(struct Curl_cfilter *cf, * send its FINISHED message off. We attempt to let it write * one more time. Oh my. */ + size_t nwritten; cr_set_negotiated_alpn(cf, data, rconn); - cr_send(cf, data, NULL, 0, &tmperr); + tmperr = cr_send(cf, data, NULL, 0, &nwritten); if(tmperr == CURLE_AGAIN) { connssl->io_need = CURL_SSL_IO_NEED_SEND; return CURLE_OK; @@ -1194,17 +1190,23 @@ cr_connect(struct Curl_cfilter *cf, { const uint16_t proto = rustls_connection_get_protocol_version(rconn); - const uint16_t cipher = - rustls_connection_get_negotiated_ciphersuite(rconn); - char buf[64] = ""; + const rustls_str ciphersuite_name = + rustls_connection_get_negotiated_ciphersuite_name(rconn); + const rustls_str kex_group_name = + rustls_connection_get_negotiated_key_exchange_group_name(rconn); const char *ver = "TLS version unknown"; if(proto == RUSTLS_TLS_VERSION_TLSV1_3) ver = "TLSv1.3"; if(proto == RUSTLS_TLS_VERSION_TLSV1_2) ver = "TLSv1.2"; - Curl_cipher_suite_get_str(cipher, buf, sizeof(buf), TRUE); - infof(data, "rustls: handshake complete, %s, cipher: %s", - ver, buf); + infof(data, + "rustls: handshake complete, %s, ciphersuite: %.*s, " + "key exchange group: %.*s", + ver, + (int) ciphersuite_name.len, + ciphersuite_name.data, + (int) kex_group_name.len, + kex_group_name.data); } if(data->set.ssl.certinfo) { size_t num_certs = 0; @@ -1255,8 +1257,9 @@ cr_connect(struct Curl_cfilter *cf, DEBUGASSERT(wants_read || wants_write); if(wants_write) { + size_t nwritten; CURL_TRC_CF(data, cf, "rustls_connection wants us to write_tls."); - cr_send(cf, data, NULL, 0, &tmperr); + tmperr = cr_send(cf, data, NULL, 0, &nwritten); if(tmperr == CURLE_AGAIN) { CURL_TRC_CF(data, cf, "writing would block"); connssl->io_need = CURL_SSL_IO_NEED_SEND; @@ -1297,7 +1300,7 @@ cr_get_internals(struct ssl_connect_data *connssl, struct rustls_ssl_backend_data *backend = (struct rustls_ssl_backend_data *)connssl->backend; DEBUGASSERT(backend); - return &backend->conn; + return backend->conn; } static CURLcode @@ -1309,8 +1312,7 @@ cr_shutdown(struct Curl_cfilter *cf, struct rustls_ssl_backend_data *backend = (struct rustls_ssl_backend_data *)connssl->backend; CURLcode result = CURLE_OK; - ssize_t nwritten, nread; - size_t i; + size_t i, nread, nwritten; DEBUGASSERT(backend); if(!backend->conn || cf->shutdown) { @@ -1329,8 +1331,8 @@ cr_shutdown(struct Curl_cfilter *cf, } } - nwritten = cr_send(cf, data, NULL, 0, &result); - if(nwritten < 0) { + result = cr_send(cf, data, NULL, 0, &nwritten); + if(result) { if(result == CURLE_AGAIN) { connssl->io_need = CURL_SSL_IO_NEED_SEND; result = CURLE_OK; @@ -1343,26 +1345,23 @@ cr_shutdown(struct Curl_cfilter *cf, for(i = 0; i < 10; ++i) { char buf[1024]; - nread = cr_recv(cf, data, buf, (int)sizeof(buf), &result); - if(nread <= 0) + result = cr_recv(cf, data, buf, (int)sizeof(buf), &nread); + if(result) break; } - if(nread > 0) { - /* still data coming in? */ - } - else if(nread == 0) { - /* We got the close notify alert and are done. */ - *done = TRUE; - } - else if(result == CURLE_AGAIN) { + if(result == CURLE_AGAIN) { connssl->io_need = CURL_SSL_IO_NEED_RECV; result = CURLE_OK; } - else { + else if(result) { DEBUGASSERT(result); CURL_TRC_CF(data, cf, "shutdown, error: %d", result); } + else if(nread == 0) { + /* We got the close notify alert and are done. */ + *done = TRUE; + } out: cf->shutdown = (result || *done); @@ -1434,7 +1433,6 @@ const struct Curl_ssl Curl_ssl_rustls = { NULL, /* set_engine */ NULL, /* set_engine_default */ NULL, /* engines_list */ - NULL, /* false_start */ NULL, /* sha256sum */ cr_recv, /* recv decrypted data */ cr_send, /* send data to encrypt */ diff --git a/vendor/curl/lib/vtls/schannel.c b/vendor/curl/lib/vtls/schannel.c index bea8eef8c0d..0b3ec8cc25c 100644 --- a/vendor/curl/lib/vtls/schannel.c +++ b/vendor/curl/lib/vtls/schannel.c @@ -42,9 +42,9 @@ #include "vtls.h" #include "vtls_int.h" #include "vtls_scache.h" -#include "../strcase.h" #include "../sendf.h" #include "../connect.h" /* for the connect timeout */ +#include "../strdup.h" #include "../strerror.h" #include "../select.h" /* for the socket readiness */ #include "../curlx/inet_pton.h" /* for IP addr SNI check */ @@ -73,54 +73,26 @@ #define SCH_DEV(x) do { } while(0) #endif -#ifndef BCRYPT_CHAIN_MODE_CCM -#define BCRYPT_CHAIN_MODE_CCM L"ChainingModeCCM" -#endif - -#ifndef BCRYPT_CHAIN_MODE_GCM -#define BCRYPT_CHAIN_MODE_GCM L"ChainingModeGCM" -#endif - -#ifndef BCRYPT_AES_ALGORITHM -#define BCRYPT_AES_ALGORITHM L"AES" -#endif - -#ifndef BCRYPT_SHA256_ALGORITHM -#define BCRYPT_SHA256_ALGORITHM L"SHA256" -#endif - -#ifndef BCRYPT_SHA384_ALGORITHM -#define BCRYPT_SHA384_ALGORITHM L"SHA384" -#endif - -#ifdef HAS_CLIENT_CERT_PATH -#ifdef UNICODE -#define CURL_CERT_STORE_PROV_SYSTEM CERT_STORE_PROV_SYSTEM_W -#else -#define CURL_CERT_STORE_PROV_SYSTEM CERT_STORE_PROV_SYSTEM_A -#endif -#endif - +/* Offered by mingw-w64 v8+. MS SDK 7.0A+. */ #ifndef SP_PROT_TLS1_0_CLIENT #define SP_PROT_TLS1_0_CLIENT SP_PROT_TLS1_CLIENT #endif - #ifndef SP_PROT_TLS1_1_CLIENT #define SP_PROT_TLS1_1_CLIENT 0x00000200 #endif - #ifndef SP_PROT_TLS1_2_CLIENT #define SP_PROT_TLS1_2_CLIENT 0x00000800 #endif +/* Offered by mingw-w64 v8+. MS SDK ~10+/~VS2017+. */ #ifndef SP_PROT_TLS1_3_CLIENT #define SP_PROT_TLS1_3_CLIENT 0x00002000 #endif - #ifndef SCH_USE_STRONG_CRYPTO #define SCH_USE_STRONG_CRYPTO 0x00400000 #endif +/* Offered by mingw-w64 v10+. MS SDK 7.0A+. */ #ifndef SECBUFFER_ALERT #define SECBUFFER_ALERT 17 #endif @@ -137,6 +109,7 @@ * #define failf(x, y, ...) printf(y, __VA_ARGS__) */ +/* Offered when targeting Vista (XP SP2+) */ #ifndef CALG_SHA_256 #define CALG_SHA_256 0x0000800c #endif @@ -147,14 +120,19 @@ #define ALG_CLASS_DHASH ALG_CLASS_HASH #endif +/* Offered by mingw-w64 v4+. MS SDK 6.0A+. */ #ifndef PKCS12_NO_PERSIST_KEY #define PKCS12_NO_PERSIST_KEY 0x00008000 #endif +/* Offered by mingw-w64 v4+. MS SDK ~10+/~VS2017+. */ #ifndef CERT_FIND_HAS_PRIVATE_KEY #define CERT_FIND_HAS_PRIVATE_KEY (21 << CERT_COMPARE_SHIFT) #endif +/* key to use at `multi->proto_hash` */ +#define MPROTO_SCHANNEL_CERT_SHARE_KEY "tls:schannel:cert:share" + /* ALPN requires version 8.1 of the Windows SDK, which was shipped with Visual Studio 2013, aka _MSC_VER 1800: https://technet.microsoft.com/en-us/library/hh831771%28v=ws.11%29.aspx @@ -286,7 +264,7 @@ static const struct algo algs[]= { #ifdef CALG_TEK CIPHEROPTION(CALG_TEK), #endif - CIPHEROPTION(CALG_CYLINK_MEK), + CIPHEROPTION(CALG_CYLINK_MEK), /* spellchecker:disable-line */ CIPHEROPTION(CALG_SSL3_SHAMD5), #ifdef CALG_SSL3_MASTER CIPHEROPTION(CALG_SSL3_MASTER), @@ -379,7 +357,7 @@ set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers, { const char *startCur = ciphers; int algCount = 0; - while(startCur && (0 != *startCur) && (algCount < NUM_CIPHERS)) { + while(startCur && *startCur && (algCount < NUM_CIPHERS)) { curl_off_t alg; if(curlx_str_number(&startCur, &alg, INT_MAX) || !alg) alg = get_alg_id_by_name(startCur); @@ -402,8 +380,7 @@ set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers, return CURLE_OK; } -#ifdef HAS_CLIENT_CERT_PATH - +#ifndef UNDER_CE /* Function allocates memory for store_path only if CURLE_OK is returned */ static CURLcode get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, @@ -469,10 +446,8 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf, struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); -#ifdef HAS_CLIENT_CERT_PATH PCCERT_CONTEXT client_certs[1] = { NULL }; HCERTSTORE client_cert_store = NULL; -#endif SECURITY_STATUS sspi_status = SEC_E_OK; CURLcode result; @@ -486,11 +461,9 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf, DEBUGASSERT(backend); if(conn_config->verifypeer) { -#ifdef HAS_MANUAL_VERIFY_API if(backend->use_manual_cred_validation) flags = SCH_CRED_MANUAL_CRED_VALIDATION; else -#endif flags = SCH_CRED_AUTO_CRED_VALIDATION; if(ssl_config->no_revoke) { @@ -545,7 +518,7 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf, case CURL_SSLVERSION_TLSv1_3: { result = schannel_set_ssl_version_min_max(&enabled_protocols, cf, data); - if(result != CURLE_OK) + if(result) return result; break; } @@ -558,7 +531,7 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf, return CURLE_SSL_CONNECT_ERROR; } -#ifdef HAS_CLIENT_CERT_PATH +#ifndef UNDER_CE /* client certificate */ if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) { DWORD cert_store_name = 0; @@ -598,7 +571,7 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf, } if((fInCert || blob) && (data->set.ssl.cert_type) && - (!strcasecompare(data->set.ssl.cert_type, "P12"))) { + (!curl_strequal(data->set.ssl.cert_type, "P12"))) { failf(data, "schannel: certificate format compatibility error " " for %s", blob ? "(memory blob)" : data->set.ssl.primary.clientcert); @@ -709,7 +682,13 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf, } else { cert_store = - CertOpenStore(CURL_CERT_STORE_PROV_SYSTEM, 0, + CertOpenStore( +#ifdef UNICODE + CERT_STORE_PROV_SYSTEM_W, +#else + CERT_STORE_PROV_SYSTEM_A, +#endif + 0, (HCRYPTPROV)NULL, CERT_STORE_OPEN_EXISTING_FLAG | cert_store_name, cert_store_path); @@ -751,16 +730,12 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf, if(!client_certs[0]) { /* CRYPT_E_NOT_FOUND / E_INVALIDARG */ CertCloseStore(cert_store, 0); + failf(data, "schannel: client cert not found in cert store"); return CURLE_SSL_CERTPROBLEM; } } client_cert_store = cert_store; } -#else - if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) { - failf(data, "schannel: client cert support not built in"); - return CURLE_NOT_BUILT_IN; - } #endif /* allocate memory for the reusable credential handle */ @@ -769,23 +744,19 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf, if(!backend->cred) { failf(data, "schannel: unable to allocate memory"); -#ifdef HAS_CLIENT_CERT_PATH if(client_certs[0]) CertFreeCertificateContext(client_certs[0]); if(client_cert_store) CertCloseStore(client_cert_store, 0); -#endif return CURLE_OUT_OF_MEMORY; } backend->cred->refcount = 1; -#ifdef HAS_CLIENT_CERT_PATH /* Since we did not persist the key, we need to extend the store's * lifetime until the end of the connection */ backend->cred->client_cert_store = client_cert_store; -#endif /* We support TLS 1.3 starting in Windows 10 version 1809 (OS build 17763) as long as the user did not set a legacy algorithm list @@ -811,12 +782,10 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf, credentials.pTlsParameters->grbitDisabledProtocols = (DWORD)~enabled_protocols; -#ifdef HAS_CLIENT_CERT_PATH if(client_certs[0]) { credentials.cCreds = 1; credentials.paCred = client_certs; } -#endif sspi_status = Curl_pSecFn->AcquireCredentialsHandle(NULL, @@ -843,7 +812,7 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf, "user set an algorithm cipher list."); } result = set_ssl_ciphers(&schannel_cred, ciphers, algIds); - if(CURLE_OK != result) { + if(result) { failf(data, "schannel: Failed setting algorithm cipher list"); return result; } @@ -852,12 +821,10 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf, schannel_cred.dwFlags = flags | SCH_USE_STRONG_CRYPTO; } -#ifdef HAS_CLIENT_CERT_PATH if(client_certs[0]) { schannel_cred.cCreds = 1; schannel_cred.paCred = client_certs; } -#endif sspi_status = Curl_pSecFn->AcquireCredentialsHandle(NULL, @@ -868,10 +835,8 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf, &backend->cred->time_stamp); } -#ifdef HAS_CLIENT_CERT_PATH if(client_certs[0]) CertFreeCertificateContext(client_certs[0]); -#endif if(sspi_status != SEC_E_OK) { char buffer[STRERROR_LEN]; @@ -897,7 +862,7 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf, static CURLcode schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) { - ssize_t written = -1; + size_t written = 0; struct ssl_connect_data *connssl = cf->ctx; struct schannel_ssl_backend_data *backend = (struct schannel_ssl_backend_data *)connssl->backend; @@ -935,15 +900,10 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) #endif #ifdef UNDER_CE -#ifdef HAS_MANUAL_VERIFY_API /* certificate validation on Windows CE does not seem to work right; we will * do it following a more manual process. */ backend->use_manual_cred_validation = TRUE; #else -#error "compiler too old to support Windows CE requisite manual cert verify" -#endif -#else -#ifdef HAS_MANUAL_VERIFY_API if(conn_config->CAfile || conn_config->ca_info_blob) { if(curlx_verify_windows_version(6, 1, 0, PLATFORM_WINNT, VERSION_GREATER_THAN_EQUAL)) { @@ -957,12 +917,6 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) } else backend->use_manual_cred_validation = FALSE; -#else - if(conn_config->CAfile || conn_config->ca_info_blob) { - failf(data, "schannel: CA cert support not built in"); - return CURLE_NOT_BUILT_IN; - } -#endif #endif backend->cred = NULL; @@ -1106,17 +1060,17 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) failf(data, "schannel: SNI or certificate check failed: %s", Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); return CURLE_PEER_FAILED_VERIFICATION; - /* - case SEC_E_INVALID_HANDLE: - case SEC_E_INVALID_TOKEN: - case SEC_E_LOGON_DENIED: - case SEC_E_TARGET_UNKNOWN: - case SEC_E_NO_AUTHENTICATING_AUTHORITY: - case SEC_E_INTERNAL_ERROR: - case SEC_E_NO_CREDENTIALS: - case SEC_E_UNSUPPORTED_FUNCTION: - case SEC_E_APPLICATION_PROTOCOL_MISMATCH: - */ +#if 0 + case SEC_E_INVALID_HANDLE: + case SEC_E_INVALID_TOKEN: + case SEC_E_LOGON_DENIED: + case SEC_E_TARGET_UNKNOWN: + case SEC_E_NO_AUTHENTICATING_AUTHORITY: + case SEC_E_INTERNAL_ERROR: + case SEC_E_NO_CREDENTIALS: + case SEC_E_UNSUPPORTED_FUNCTION: + case SEC_E_APPLICATION_PROTOCOL_MISMATCH: +#endif default: failf(data, "schannel: initial InitializeSecurityContext failed: %s", Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); @@ -1128,18 +1082,18 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) "sending %lu bytes.", outbuf.cbBuffer)); /* send initial handshake data which is now stored in output buffer */ - written = Curl_conn_cf_send(cf->next, data, - outbuf.pvBuffer, outbuf.cbBuffer, FALSE, - &result); + result = Curl_conn_cf_send(cf->next, data, + outbuf.pvBuffer, outbuf.cbBuffer, FALSE, + &written); Curl_pSecFn->FreeContextBuffer(outbuf.pvBuffer); - if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) { + if(result || (outbuf.cbBuffer != written)) { failf(data, "schannel: failed to send initial handshake data: " - "sent %zd of %lu bytes", written, outbuf.cbBuffer); + "sent %zu of %lu bytes", written, outbuf.cbBuffer); return CURLE_SSL_CONNECT_ERROR; } DEBUGF(infof(data, "schannel: sent initial handshake data: " - "sent %zd bytes", written)); + "sent %zu bytes", written)); backend->recv_unrecoverable_err = CURLE_OK; backend->recv_sspi_close_notify = FALSE; @@ -1161,7 +1115,7 @@ schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) (struct schannel_ssl_backend_data *)connssl->backend; struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); int i; - ssize_t nread = -1, written = -1; + size_t nread = 0, written = 0; unsigned char *reallocated_buffer; SecBuffer outbuf[3]; SecBufferDesc outbuf_desc; @@ -1229,19 +1183,19 @@ schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) for(;;) { if(doread) { /* read encrypted handshake data from socket */ - nread = Curl_conn_cf_recv(cf->next, data, - (char *) (backend->encdata_buffer + - backend->encdata_offset), - backend->encdata_length - - backend->encdata_offset, - &result); + result = Curl_conn_cf_recv(cf->next, data, + (char *) (backend->encdata_buffer + + backend->encdata_offset), + backend->encdata_length - + backend->encdata_offset, + &nread); if(result == CURLE_AGAIN) { connssl->io_need = CURL_SSL_IO_NEED_RECV; DEBUGF(infof(data, "schannel: failed to receive handshake, " "need more data")); return CURLE_OK; } - else if((result != CURLE_OK) || (nread == 0)) { + else if(result || (nread == 0)) { failf(data, "schannel: failed to receive handshake, " "SSL/TLS connection failed"); return CURLE_SSL_CONNECT_ERROR; @@ -1250,7 +1204,7 @@ schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) /* increase encrypted data buffer offset */ backend->encdata_offset += nread; backend->encdata_is_incomplete = FALSE; - SCH_DEV(infof(data, "schannel: encrypted data got %zd", nread)); + SCH_DEV(infof(data, "schannel: encrypted data got %zu", nread)); } SCH_DEV(infof(data, @@ -1317,13 +1271,12 @@ schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) "sending %lu bytes.", outbuf[i].cbBuffer)); /* send handshake token to server */ - written = Curl_conn_cf_send(cf->next, data, - outbuf[i].pvBuffer, outbuf[i].cbBuffer, - FALSE, &result); - if((result != CURLE_OK) || - (outbuf[i].cbBuffer != (size_t) written)) { + result = Curl_conn_cf_send(cf->next, data, + outbuf[i].pvBuffer, outbuf[i].cbBuffer, + FALSE, &written); + if(result || (outbuf[i].cbBuffer != written)) { failf(data, "schannel: failed to send next handshake data: " - "sent %zd of %lu bytes", written, outbuf[i].cbBuffer); + "sent %zu of %lu bytes", written, outbuf[i].cbBuffer); return CURLE_SSL_CONNECT_ERROR; } } @@ -1349,17 +1302,17 @@ schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) failf(data, "schannel: %s", Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); return CURLE_PEER_FAILED_VERIFICATION; - /* - case SEC_E_INVALID_HANDLE: - case SEC_E_INVALID_TOKEN: - case SEC_E_LOGON_DENIED: - case SEC_E_TARGET_UNKNOWN: - case SEC_E_NO_AUTHENTICATING_AUTHORITY: - case SEC_E_INTERNAL_ERROR: - case SEC_E_NO_CREDENTIALS: - case SEC_E_UNSUPPORTED_FUNCTION: - case SEC_E_APPLICATION_PROTOCOL_MISMATCH: - */ +#if 0 + case SEC_E_INVALID_HANDLE: + case SEC_E_INVALID_TOKEN: + case SEC_E_LOGON_DENIED: + case SEC_E_TARGET_UNKNOWN: + case SEC_E_NO_AUTHENTICATING_AUTHORITY: + case SEC_E_INTERNAL_ERROR: + case SEC_E_NO_CREDENTIALS: + case SEC_E_UNSUPPORTED_FUNCTION: + case SEC_E_APPLICATION_PROTOCOL_MISMATCH: +#endif default: failf(data, "schannel: next InitializeSecurityContext failed: %s", Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); @@ -1427,12 +1380,10 @@ schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) } } -#ifdef HAS_MANUAL_VERIFY_API if(conn_config->verifypeer && backend->use_manual_cred_validation) { /* Certificate verification also verifies the hostname if verifyhost */ return Curl_verify_certificate(cf, data); } -#endif /* Verify the hostname manually when certificate verification is disabled, because in that case Schannel will not verify it. */ @@ -1527,12 +1478,10 @@ static void schannel_session_free(void *sessionid) if(cred->refcount == 0) { Curl_pSecFn->FreeCredentialsHandle(&cred->cred_handle); curlx_unicodefree(cred->sni_hostname); -#ifdef HAS_CLIENT_CERT_PATH if(cred->client_cert_store) { CertCloseStore(cred->client_cert_store, 0); cred->client_cert_store = NULL; } -#endif Curl_safefree(cred); } } @@ -1591,19 +1540,18 @@ schannel_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data) if(alpn_result.ProtoNegoStatus == SecApplicationProtocolNegotiationStatus_Success) { - unsigned char prev_alpn = cf->conn->alpn; - + if(backend->recv_renegotiating && + connssl->negotiated.alpn && + strncmp(connssl->negotiated.alpn, + (const char *)alpn_result.ProtocolId, + alpn_result.ProtocolIdSize)) { + /* Renegotiation selected a different protocol now, we cannot + * deal with this */ + failf(data, "schannel: server selected an ALPN protocol too late"); + return CURLE_SSL_CONNECT_ERROR; + } Curl_alpn_set_negotiated(cf, data, connssl, alpn_result.ProtocolId, alpn_result.ProtocolIdSize); - if(backend->recv_renegotiating) { - if(prev_alpn != cf->conn->alpn && - prev_alpn != CURL_HTTP_VERSION_NONE) { - /* Renegotiation selected a different protocol now, we cannot - * deal with this */ - failf(data, "schannel: server selected an ALPN protocol too late"); - return CURLE_SSL_CONNECT_ERROR; - } - } } else { if(!backend->recv_renegotiating) @@ -1694,7 +1642,7 @@ static CURLcode schannel_connect(struct Curl_cfilter *cf, if(ssl_connect_done == connssl->connecting_state) { connssl->state = ssl_connection_complete; -#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS +#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS /* mingw-w64 v9+. MS SDK 7.0A+. */ /* When SSPI is used in combination with Schannel * we need the Schannel context to create the Schannel * binding to pass the IIS extended protection checks. @@ -1714,22 +1662,22 @@ static CURLcode schannel_connect(struct Curl_cfilter *cf, return CURLE_OK; } -static ssize_t +static CURLcode schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, CURLcode *err) + const void *buf, size_t len, size_t *pnwritten) { - ssize_t written = -1; size_t data_len = 0; unsigned char *ptr = NULL; struct ssl_connect_data *connssl = cf->ctx; SecBuffer outbuf[4]; SecBufferDesc outbuf_desc; SECURITY_STATUS sspi_status = SEC_E_OK; - CURLcode result; + CURLcode result = CURLE_OK; struct schannel_ssl_backend_data *backend = (struct schannel_ssl_backend_data *)connssl->backend; DEBUGASSERT(backend); + *pnwritten = 0; /* check if the maximum stream sizes were queried */ if(backend->stream_sizes.cbMaximumMessage == 0) { @@ -1738,8 +1686,7 @@ schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data, SECPKG_ATTR_STREAM_SIZES, &backend->stream_sizes); if(sspi_status != SEC_E_OK) { - *err = CURLE_SEND_ERROR; - return -1; + return CURLE_SEND_ERROR; } } @@ -1753,8 +1700,7 @@ schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data, backend->stream_sizes.cbTrailer; ptr = (unsigned char *) malloc(data_len); if(!ptr) { - *err = CURLE_OUT_OF_MEMORY; - return -1; + return CURLE_OUT_OF_MEMORY; } /* setup output buffers (header, data, trailer, empty) */ @@ -1777,7 +1723,6 @@ schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data, /* check if the message was encrypted */ if(sspi_status == SEC_E_OK) { - written = 0; /* send the encrypted message including header, data and trailer */ len = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer; @@ -1799,16 +1744,15 @@ schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data, */ /* send entire message or fail */ - while(len > (size_t)written) { - ssize_t this_write = 0; + while(len > *pnwritten) { + size_t this_write = 0; int what; timediff_t timeout_ms = Curl_timeleft(data, NULL, FALSE); if(timeout_ms < 0) { /* we already got the timeout */ failf(data, "schannel: timed out sending data " - "(bytes sent: %zd)", written); - *err = CURLE_OPERATION_TIMEDOUT; - written = -1; + "(bytes sent: %zu)", *pnwritten); + result = CURLE_OPERATION_TIMEDOUT; break; } else if(!timeout_ms) @@ -1817,56 +1761,52 @@ schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data, if(what < 0) { /* fatal error */ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); - *err = CURLE_SEND_ERROR; - written = -1; + result = CURLE_SEND_ERROR; break; } - else if(0 == what) { + else if(what == 0) { failf(data, "schannel: timed out sending data " - "(bytes sent: %zd)", written); - *err = CURLE_OPERATION_TIMEDOUT; - written = -1; + "(bytes sent: %zu)", *pnwritten); + result = CURLE_OPERATION_TIMEDOUT; break; } /* socket is writable */ - this_write = Curl_conn_cf_send(cf->next, data, - ptr + written, len - written, - FALSE, &result); + result = Curl_conn_cf_send(cf->next, data, + ptr + *pnwritten, len - *pnwritten, + FALSE, &this_write); if(result == CURLE_AGAIN) continue; - else if(result != CURLE_OK) { - *err = result; - written = -1; + else if(result) { break; } - written += this_write; + *pnwritten += this_write; } } else if(sspi_status == SEC_E_INSUFFICIENT_MEMORY) { - *err = CURLE_OUT_OF_MEMORY; + result = CURLE_OUT_OF_MEMORY; } else{ - *err = CURLE_SEND_ERROR; + result = CURLE_SEND_ERROR; } Curl_safefree(ptr); - if(len == (size_t)written) + if(len == *pnwritten) /* Encrypted message including header, data and trailer entirely sent. The return value is the number of unencrypted bytes that were sent. */ - written = outbuf[1].cbBuffer; + *pnwritten = outbuf[1].cbBuffer; - return written; + return result; } -static ssize_t +static CURLcode schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t len, CURLcode *err) + char *buf, size_t len, size_t *pnread) { size_t size = 0; - ssize_t nread = -1; + size_t nread = 0; struct ssl_connect_data *connssl = cf->ctx; unsigned char *reallocated_buffer; size_t reallocated_length; @@ -1879,8 +1819,10 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE; struct schannel_ssl_backend_data *backend = (struct schannel_ssl_backend_data *)connssl->backend; + CURLcode result = CURLE_OK; DEBUGASSERT(backend); + *pnread = 0; /**************************************************************************** * Do not return or set backend->recv_unrecoverable_err unless in the @@ -1899,7 +1841,6 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, */ SCH_DEV(infof(data, "schannel: client wants to read %zu bytes", len)); - *err = CURLE_OK; if(len && len <= backend->decdata_offset) { SCH_DEV(infof(data, @@ -1907,7 +1848,7 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, goto cleanup; } else if(backend->recv_unrecoverable_err) { - *err = backend->recv_unrecoverable_err; + result = backend->recv_unrecoverable_err; infof(data, "schannel: an unrecoverable error occurred in a prior call"); goto cleanup; } @@ -1933,7 +1874,7 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, reallocated_buffer = realloc(backend->encdata_buffer, reallocated_length); if(!reallocated_buffer) { - *err = CURLE_OUT_OF_MEMORY; + result = CURLE_OUT_OF_MEMORY; failf(data, "schannel: unable to re-allocate memory"); goto cleanup; } @@ -1950,26 +1891,26 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, backend->encdata_offset, backend->encdata_length)); /* read encrypted data from socket */ - nread = Curl_conn_cf_recv(cf->next, data, - (char *)(backend->encdata_buffer + - backend->encdata_offset), - size, err); - if(*err) { - if(*err == CURLE_AGAIN) + result = Curl_conn_cf_recv(cf->next, data, + (char *)(backend->encdata_buffer + + backend->encdata_offset), + size, &nread); + if(result) { + if(result == CURLE_AGAIN) SCH_DEV(infof(data, "schannel: recv returned CURLE_AGAIN")); - else if(*err == CURLE_RECV_ERROR) + else if(result == CURLE_RECV_ERROR) infof(data, "schannel: recv returned CURLE_RECV_ERROR"); else - infof(data, "schannel: recv returned error %d", *err); + infof(data, "schannel: recv returned error %d", result); } else if(nread == 0) { backend->recv_connection_closed = TRUE; DEBUGF(infof(data, "schannel: server closed the connection")); } - else if(nread > 0) { - backend->encdata_offset += (size_t)nread; + else { + backend->encdata_offset += nread; backend->encdata_is_incomplete = FALSE; - SCH_DEV(infof(data, "schannel: encrypted data got %zd", nread)); + SCH_DEV(infof(data, "schannel: encrypted data got %zu", nread)); } } @@ -2019,7 +1960,7 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, reallocated_buffer = realloc(backend->decdata_buffer, reallocated_length); if(!reallocated_buffer) { - *err = CURLE_OUT_OF_MEMORY; + result = CURLE_OUT_OF_MEMORY; failf(data, "schannel: unable to re-allocate memory"); goto cleanup; } @@ -2070,7 +2011,7 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, /* check if server wants to renegotiate the connection context */ if(sspi_status == SEC_I_RENEGOTIATE) { infof(data, "schannel: remote party requests renegotiation"); - if(*err && *err != CURLE_AGAIN) { + if(result && result != CURLE_AGAIN) { infof(data, "schannel: cannot renegotiate, an error is pending"); goto cleanup; } @@ -2081,9 +2022,9 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, connssl->connecting_state = ssl_connect_2; connssl->io_need = CURL_SSL_IO_NEED_SEND; backend->recv_renegotiating = TRUE; - *err = schannel_connect(cf, data, &done); + result = schannel_connect(cf, data, &done); backend->recv_renegotiating = FALSE; - if(*err) { + if(result) { infof(data, "schannel: renegotiation failed"); goto cleanup; } @@ -2102,8 +2043,8 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, /* We received the close notify just fine, any error we got * from the lower filters afterwards (e.g. the socket), is not * an error on the TLS data stream. That one ended here. */ - if(*err == CURLE_RECV_ERROR) - *err = CURLE_OK; + if(result == CURLE_RECV_ERROR) + result = CURLE_OK; infof(data, "schannel: server close notification received (close_notify)"); goto cleanup; @@ -2111,8 +2052,8 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, } else if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) { backend->encdata_is_incomplete = TRUE; - if(!*err) - *err = CURLE_AGAIN; + if(!result) + result = CURLE_AGAIN; SCH_DEV(infof(data, "schannel: failed to decrypt data, need more data")); goto cleanup; } @@ -2122,7 +2063,7 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, failf(data, "schannel: failed to read data from server: %s", Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); #endif - *err = CURLE_RECV_ERROR; + result = CURLE_RECV_ERROR; goto cleanup; } } @@ -2142,28 +2083,16 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, The behavior here is a matter of debate. We do not want to be vulnerable to a truncation attack however there is some browser precedent for ignoring the close_notify for compatibility reasons. - - Additionally, Windows 2000 (v5.0) is a special case since it seems it - does not return close_notify. In that case if the connection was closed we - assume it was graceful (close_notify) since there does not seem to be a - way to tell. */ if(len && !backend->decdata_offset && backend->recv_connection_closed && !backend->recv_sspi_close_notify) { - bool isWin2k = curlx_verify_windows_version(5, 0, 0, PLATFORM_WINNT, - VERSION_EQUAL); - - if(isWin2k && sspi_status == SEC_E_OK) - backend->recv_sspi_close_notify = TRUE; - else { - *err = CURLE_RECV_ERROR; - failf(data, "schannel: server closed abruptly (missing close_notify)"); - } + result = CURLE_RECV_ERROR; + failf(data, "schannel: server closed abruptly (missing close_notify)"); } /* Any error other than CURLE_AGAIN is an unrecoverable error. */ - if(*err && *err != CURLE_AGAIN) - backend->recv_unrecoverable_err = *err; + if(result && result != CURLE_AGAIN) + backend->recv_unrecoverable_err = result; size = len < backend->decdata_offset ? len : backend->decdata_offset; if(size) { @@ -2175,21 +2104,21 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, SCH_DEV(infof(data, "schannel: decrypted data buffer: offset %zu length %zu", backend->decdata_offset, backend->decdata_length)); - *err = CURLE_OK; - return (ssize_t)size; + *pnread = size; + return CURLE_OK; } - if(!*err && !backend->recv_connection_closed) - *err = CURLE_AGAIN; + if(!result && !backend->recv_connection_closed) + result = CURLE_AGAIN; /* it is debatable what to return when !len. We could return whatever error we got from decryption but instead we override here so the return is consistent. */ if(!len) - *err = CURLE_OK; + return CURLE_OK; - return *err ? -1 : 0; + return result; } static bool schannel_data_pending(struct Curl_cfilter *cf, @@ -2291,14 +2220,16 @@ static CURLcode schannel_shutdown(struct Curl_cfilter *cf, if((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) { /* send close message which is in output buffer */ - ssize_t written = Curl_conn_cf_send(cf->next, data, - outbuf.pvBuffer, outbuf.cbBuffer, - FALSE, &result); + size_t written; + + result = Curl_conn_cf_send(cf->next, data, + outbuf.pvBuffer, outbuf.cbBuffer, + FALSE, &written); Curl_pSecFn->FreeContextBuffer(outbuf.pvBuffer); if(!result) { - if(written < (ssize_t)outbuf.cbBuffer) { + if(written < outbuf.cbBuffer) { failf(data, "schannel: failed to send close msg: %s" - " (bytes written: %zd)", curl_easy_strerror(result), written); + " (bytes written: %zu)", curl_easy_strerror(result), written); result = CURLE_SEND_ERROR; goto out; } @@ -2329,23 +2260,23 @@ static CURLcode schannel_shutdown(struct Curl_cfilter *cf, if(backend->cred && backend->ctxt && !backend->recv_sspi_close_notify && !backend->recv_connection_closed) { char buffer[1024]; - ssize_t nread; + size_t nread; - nread = schannel_recv(cf, data, buffer, sizeof(buffer), &result); - if(nread > 0) { - /* still data coming in? */ + result = schannel_recv(cf, data, buffer, sizeof(buffer), &nread); + if(result == CURLE_AGAIN) { + connssl->io_need = CURL_SSL_IO_NEED_RECV; + } + else if(result) { + CURL_TRC_CF(data, cf, "SSL shutdown, error %d", result); + result = CURLE_RECV_ERROR; } else if(nread == 0) { /* We got the close notify alert and are done. */ backend->recv_connection_closed = TRUE; *done = TRUE; } - else if(nread < 0 && result == CURLE_AGAIN) { - connssl->io_need = CURL_SSL_IO_NEED_RECV; - } else { - CURL_TRC_CF(data, cf, "SSL shutdown, error %d", result); - result = CURLE_RECV_ERROR; + /* still data coming in? */ } } @@ -2397,26 +2328,16 @@ static void schannel_close(struct Curl_cfilter *cf, struct Curl_easy *data) static int schannel_init(void) { #if defined(HAS_ALPN_SCHANNEL) && !defined(UNDER_CE) - bool wine = FALSE; - bool wine_has_alpn = FALSE; - -#ifndef CURL_WINDOWS_UWP typedef const char *(APIENTRY *WINE_GET_VERSION_FN)(void); - /* GetModuleHandle() not available for UWP. - Assume no WINE because WINE has no UWP support. */ WINE_GET_VERSION_FN p_wine_get_version = CURLX_FUNCTION_CAST(WINE_GET_VERSION_FN, (GetProcAddress(GetModuleHandleA("ntdll"), "wine_get_version"))); - wine = !!p_wine_get_version; - if(wine) { + if(p_wine_get_version) { /* WINE detected */ const char *wine_version = p_wine_get_version(); /* e.g. "6.0.2" */ /* Assume ALPN support with WINE 6.0 or upper */ - wine_has_alpn = wine_version && atoi(wine_version) >= 6; + s_win_has_alpn = wine_version && atoi(wine_version) >= 6; } -#endif - if(wine) - s_win_has_alpn = wine_has_alpn; else { /* ALPN is supported on Windows 8.1 / Server 2012 R2 and above. */ s_win_has_alpn = curlx_verify_windows_version(6, 3, 0, PLATFORM_WINNT, @@ -2521,13 +2442,6 @@ static void schannel_checksum(const unsigned char *input, DWORD provType, const unsigned int algId) { -#ifdef CURL_WINDOWS_UWP - (void)input; - (void)inputlen; - (void)provType; - (void)algId; - memset(checksum, 0, checksumlen); -#else HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; DWORD cbHashSize = 0; @@ -2573,7 +2487,6 @@ static void schannel_checksum(const unsigned char *input, if(hProv) CryptReleaseContext(hProv, 0); -#endif } static CURLcode schannel_sha256sum(const unsigned char *input, @@ -2743,12 +2656,8 @@ const struct Curl_ssl Curl_ssl_schannel = { { CURLSSLBACKEND_SCHANNEL, "schannel" }, /* info */ SSLSUPP_CERTINFO | -#ifdef HAS_MANUAL_VERIFY_API SSLSUPP_CAINFO_BLOB | -#endif -#ifndef CURL_WINDOWS_UWP SSLSUPP_PINNEDPUBKEY | -#endif SSLSUPP_CA_CACHE | SSLSUPP_HTTPS_PROXY | SSLSUPP_CIPHER_LIST, @@ -2770,7 +2679,6 @@ const struct Curl_ssl Curl_ssl_schannel = { NULL, /* set_engine */ NULL, /* set_engine_default */ NULL, /* engines_list */ - NULL, /* false_start */ schannel_sha256sum, /* sha256sum */ schannel_recv, /* recv decrypted data */ schannel_send, /* send data to encrypt */ diff --git a/vendor/curl/lib/vtls/schannel.h b/vendor/curl/lib/vtls/schannel.h index c3512dd1323..4c87524a211 100644 --- a/vendor/curl/lib/vtls/schannel.h +++ b/vendor/curl/lib/vtls/schannel.h @@ -37,7 +37,7 @@ #pragma warning(pop) #endif /* Wincrypt must be included before anything that could include OpenSSL. */ -#if defined(USE_WIN32_CRYPTO) +#ifdef USE_WIN32_CRYPTO #include /* Undefine wincrypt conflicting symbols for BoringSSL. */ #undef X509_NAME @@ -68,7 +68,7 @@ * BoringSSL's : So just undefine those defines here * (and only here). */ -#if defined(OPENSSL_IS_BORINGSSL) +#ifdef OPENSSL_IS_BORINGSSL # undef X509_NAME # undef X509_CERT_PAIR # undef X509_EXTENSIONS diff --git a/vendor/curl/lib/vtls/schannel_int.h b/vendor/curl/lib/vtls/schannel_int.h index fe101254567..83be77e0f32 100644 --- a/vendor/curl/lib/vtls/schannel_int.h +++ b/vendor/curl/lib/vtls/schannel_int.h @@ -30,32 +30,6 @@ #include "vtls.h" -#if (defined(__MINGW32__) || defined(CERT_CHAIN_REVOCATION_CHECK_CHAIN)) \ - && !defined(CURL_WINDOWS_UWP) -#define HAS_MANUAL_VERIFY_API -#endif - -#if defined(CryptStringToBinary) && defined(CRYPT_STRING_HEX) \ - && !defined(DISABLE_SCHANNEL_CLIENT_CERT) -#define HAS_CLIENT_CERT_PATH -#endif - -#ifndef CRYPT_DECODE_NOCOPY_FLAG -#define CRYPT_DECODE_NOCOPY_FLAG 0x1 -#endif - -#ifndef CRYPT_DECODE_ALLOC_FLAG -#define CRYPT_DECODE_ALLOC_FLAG 0x8000 -#endif - -#ifndef CERT_ALT_NAME_DNS_NAME -#define CERT_ALT_NAME_DNS_NAME 3 -#endif - -#ifndef CERT_ALT_NAME_IP_ADDRESS -#define CERT_ALT_NAME_IP_ADDRESS 8 -#endif - #if defined(_MSC_VER) && (_MSC_VER <= 1600) /* Workaround for warning: 'type cast' : conversion from 'int' to 'LPCSTR' of greater size */ @@ -67,54 +41,53 @@ #define CERT_STORE_PROV_SYSTEM_W ((LPCSTR)(size_t)10) #endif +/* Offered by mingw-w64 v8+, MS SDK ~10+/~VS2022+ */ #ifndef SCH_CREDENTIALS_VERSION - #define SCH_CREDENTIALS_VERSION 0x00000005 -typedef enum _eTlsAlgorithmUsage -{ - TlsParametersCngAlgUsageKeyExchange, - TlsParametersCngAlgUsageSignature, - TlsParametersCngAlgUsageCipher, - TlsParametersCngAlgUsageDigest, - TlsParametersCngAlgUsageCertSig +typedef enum _eTlsAlgorithmUsage { + TlsParametersCngAlgUsageKeyExchange, + TlsParametersCngAlgUsageSignature, + TlsParametersCngAlgUsageCipher, + TlsParametersCngAlgUsageDigest, + TlsParametersCngAlgUsageCertSig } eTlsAlgorithmUsage; -typedef struct _CRYPTO_SETTINGS -{ - eTlsAlgorithmUsage eAlgorithmUsage; - UNICODE_STRING strCngAlgId; - DWORD cChainingModes; - PUNICODE_STRING rgstrChainingModes; - DWORD dwMinBitLength; - DWORD dwMaxBitLength; +/* !checksrc! disable TYPEDEFSTRUCT 1 */ +typedef struct _CRYPTO_SETTINGS { + eTlsAlgorithmUsage eAlgorithmUsage; + UNICODE_STRING strCngAlgId; + DWORD cChainingModes; + PUNICODE_STRING rgstrChainingModes; /* spellchecker:disable-line */ + DWORD dwMinBitLength; + DWORD dwMaxBitLength; } CRYPTO_SETTINGS, * PCRYPTO_SETTINGS; -typedef struct _TLS_PARAMETERS -{ - DWORD cAlpnIds; - PUNICODE_STRING rgstrAlpnIds; - DWORD grbitDisabledProtocols; - DWORD cDisabledCrypto; - PCRYPTO_SETTINGS pDisabledCrypto; - DWORD dwFlags; +/* !checksrc! disable TYPEDEFSTRUCT 1 */ +typedef struct _TLS_PARAMETERS { + DWORD cAlpnIds; + PUNICODE_STRING rgstrAlpnIds; /* spellchecker:disable-line */ + DWORD grbitDisabledProtocols; + DWORD cDisabledCrypto; + PCRYPTO_SETTINGS pDisabledCrypto; + DWORD dwFlags; } TLS_PARAMETERS, * PTLS_PARAMETERS; -typedef struct _SCH_CREDENTIALS -{ - DWORD dwVersion; - DWORD dwCredFormat; - DWORD cCreds; - PCCERT_CONTEXT* paCred; - HCERTSTORE hRootStore; - - DWORD cMappers; - struct _HMAPPER **aphMappers; - - DWORD dwSessionLifespan; - DWORD dwFlags; - DWORD cTlsParameters; - PTLS_PARAMETERS pTlsParameters; +/* !checksrc! disable TYPEDEFSTRUCT 1 */ +typedef struct _SCH_CREDENTIALS { + DWORD dwVersion; + DWORD dwCredFormat; + DWORD cCreds; + PCCERT_CONTEXT* paCred; + HCERTSTORE hRootStore; + + DWORD cMappers; + struct _HMAPPER **aphMappers; + + DWORD dwSessionLifespan; + DWORD dwFlags; + DWORD cTlsParameters; + PTLS_PARAMETERS pTlsParameters; } SCH_CREDENTIALS, * PSCH_CREDENTIALS; #define SCH_CRED_MAX_SUPPORTED_PARAMETERS 16 @@ -128,9 +101,7 @@ struct Curl_schannel_cred { CredHandle cred_handle; TimeStamp time_stamp; TCHAR *sni_hostname; -#ifdef HAS_CLIENT_CERT_PATH HCERTSTORE client_cert_store; -#endif int refcount; }; @@ -156,16 +127,11 @@ struct schannel_ssl_backend_data { BIT(recv_connection_closed); /* true if connection closed, regardless how */ BIT(recv_renegotiating); /* true if recv is doing renegotiation */ BIT(use_alpn); /* true if ALPN is used for this connection */ -#ifdef HAS_MANUAL_VERIFY_API BIT(use_manual_cred_validation); /* true if manual cred validation is used */ -#endif BIT(sent_shutdown); BIT(encdata_is_incomplete); }; -/* key to use at `multi->proto_hash` */ -#define MPROTO_SCHANNEL_CERT_SHARE_KEY "tls:schannel:cert:share" - struct schannel_cert_share { unsigned char CAinfo_blob_digest[CURL_SHA256_DIGEST_LENGTH]; size_t CAinfo_blob_size; /* CA info blob size */ diff --git a/vendor/curl/lib/vtls/schannel_verify.c b/vendor/curl/lib/vtls/schannel_verify.c index f843342b9ce..17e42707631 100644 --- a/vendor/curl/lib/vtls/schannel_verify.c +++ b/vendor/curl/lib/vtls/schannel_verify.c @@ -56,8 +56,6 @@ #define BACKEND ((struct schannel_ssl_backend_data *)connssl->backend) -#ifdef HAS_MANUAL_VERIFY_API - #ifdef __MINGW32CE__ #define CERT_QUERY_OBJECT_BLOB 0x00000002 #define CERT_QUERY_CONTENT_CERT 1 @@ -78,6 +76,28 @@ #define BEGIN_CERT "-----BEGIN CERTIFICATE-----" #define END_CERT "\n-----END CERTIFICATE-----" +struct cert_chain_engine_config_win8 { + DWORD cbSize; + HCERTSTORE hRestrictedRoot; + HCERTSTORE hRestrictedTrust; + HCERTSTORE hRestrictedOther; + DWORD cAdditionalStore; + HCERTSTORE *rghAdditionalStore; + DWORD dwFlags; + DWORD dwUrlRetrievalTimeout; + DWORD MaximumCachedCertificates; + DWORD CycleDetectionModulus; + HCERTSTORE hExclusiveRoot; + HCERTSTORE hExclusiveTrustedPeople; + DWORD dwExclusiveFlags; +}; + +/* Offered by mingw-w64 v4+. MS SDK ~10+/~VS2017+. */ +#ifndef CERT_CHAIN_EXCLUSIVE_ENABLE_CA_FLAG +#define CERT_CHAIN_EXCLUSIVE_ENABLE_CA_FLAG 0x00000001 +#endif + +/* Legacy structure to supply size to Win7 clients */ struct cert_chain_engine_config_win7 { DWORD cbSize; HCERTSTORE hRestrictedRoot; @@ -348,11 +368,7 @@ static CURLcode add_certs_file_to_store(HCERTSTORE trust_store, return result; } -#endif -#endif /* HAS_MANUAL_VERIFY_API */ - -#ifndef UNDER_CE /* * Returns the number of characters necessary to populate all the host_names. * If host_names is not NULL, populate it with all the hostnames. Each string @@ -368,18 +384,11 @@ static DWORD cert_get_name_string(struct Curl_easy *data, BOOL Win8_compat) { DWORD actual_length = 0; -#if defined(CURL_WINDOWS_UWP) - (void)data; - (void)cert_context; - (void)host_names; - (void)length; - (void)alt_name_info; - (void)Win8_compat; -#else BOOL compute_content = FALSE; LPTSTR current_pos = NULL; DWORD i; +/* Offered by mingw-w64 v4+. MS SDK ~10+/~VS2017+. */ #ifdef CERT_NAME_SEARCH_ALL_NAMES_FLAG /* CERT_NAME_SEARCH_ALL_NAMES_FLAG is available from Windows 8 onwards. */ if(Win8_compat) { @@ -449,7 +458,6 @@ static DWORD cert_get_name_string(struct Curl_easy *data, /* Last string has double null-terminator. */ *current_pos = '\0'; } -#endif return actual_length; } @@ -488,12 +496,6 @@ static bool get_alt_name_info(struct Curl_easy *data, LPDWORD alt_name_info_size) { bool result = FALSE; -#if defined(CURL_WINDOWS_UWP) - (void)data; - (void)ctx; - (void)alt_name_info; - (void)alt_name_info_size; -#else PCERT_INFO cert_info = NULL; PCERT_EXTENSION extension = NULL; CRYPT_DECODE_PARA decode_para = { sizeof(CRYPT_DECODE_PARA), NULL, NULL }; @@ -531,7 +533,6 @@ static bool get_alt_name_info(struct Curl_easy *data, return result; } result = TRUE; -#endif return result; } #endif /* !UNDER_CE */ @@ -745,7 +746,6 @@ CURLcode Curl_verify_host(struct Curl_cfilter *cf, return result; } -#ifdef HAS_MANUAL_VERIFY_API /* Verify the server's certificate and hostname */ CURLcode Curl_verify_certificate(struct Curl_cfilter *cf, struct Curl_easy *data) @@ -779,8 +779,8 @@ CURLcode Curl_verify_certificate(struct Curl_cfilter *cf, #ifndef UNDER_CE if(result == CURLE_OK && - (conn_config->CAfile || conn_config->ca_info_blob) && - BACKEND->use_manual_cred_validation) { + (conn_config->CAfile || conn_config->ca_info_blob) && + BACKEND->use_manual_cred_validation) { /* * Create a chain engine that uses the certificates in the CA file as * trusted certificates. This is only supported on Windows 7+. @@ -838,13 +838,22 @@ CURLcode Curl_verify_certificate(struct Curl_cfilter *cf, } if(result == CURLE_OK) { - struct cert_chain_engine_config_win7 engine_config; + struct cert_chain_engine_config_win8 engine_config; BOOL create_engine_result; memset(&engine_config, 0, sizeof(engine_config)); - engine_config.cbSize = sizeof(engine_config); engine_config.hExclusiveRoot = trust_store; + /* Win8/Server2012 allows us to match partial chains */ + if(curlx_verify_windows_version(6, 2, 0, PLATFORM_WINNT, + VERSION_GREATER_THAN_EQUAL) && + !ssl_config->no_partialchain) { + engine_config.cbSize = sizeof(engine_config); + engine_config.dwExclusiveFlags = CERT_CHAIN_EXCLUSIVE_ENABLE_CA_FLAG; + } + else + engine_config.cbSize = sizeof(struct cert_chain_engine_config_win7); + /* CertCreateCertificateChainEngine will check the expected size of the * CERT_CHAIN_ENGINE_CONFIG structure and fail if the specified size * does not match the expected size. When this occurs, it indicates that @@ -948,5 +957,4 @@ CURLcode Curl_verify_certificate(struct Curl_cfilter *cf, return result; } -#endif /* HAS_MANUAL_VERIFY_API */ #endif /* USE_SCHANNEL */ diff --git a/vendor/curl/lib/vtls/vtls.c b/vendor/curl/lib/vtls/vtls.c index c6fb60d0a4f..f17f9142bed 100644 --- a/vendor/curl/lib/vtls/vtls.c +++ b/vendor/curl/lib/vtls/vtls.c @@ -43,9 +43,6 @@ #ifdef HAVE_SYS_TYPES_H #include #endif -#ifdef HAVE_SYS_STAT_H -#include -#endif #ifdef HAVE_FCNTL_H #include #endif @@ -61,9 +58,7 @@ #include "gtls.h" /* GnuTLS versions */ #include "wolfssl.h" /* wolfSSL versions */ #include "schannel.h" /* Schannel SSPI version */ -#include "sectransp.h" /* Secure Transport (Darwin) version */ #include "mbedtls.h" /* mbedTLS versions */ -#include "bearssl.h" /* BearSSL versions */ #include "rustls.h" /* Rustls versions */ #include "../slist.h" @@ -142,9 +137,11 @@ static bool blobcmp(struct curl_blob *first, struct curl_blob *second) } #ifdef USE_SSL +#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_PROXY) static const struct alpn_spec ALPN_SPEC_H11 = { { ALPN_HTTP_1_1 }, 1 }; +#endif /* !CURL_DISABLE_HTTP || !CURL_DISABLE_PROXY */ #ifdef USE_HTTP2 static const struct alpn_spec ALPN_SPEC_H2 = { { ALPN_H2 }, 1 @@ -154,6 +151,7 @@ static const struct alpn_spec ALPN_SPEC_H2_H11 = { }; #endif +#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_PROXY) static const struct alpn_spec * alpn_get_spec(http_majors allowed, bool use_alpn) { @@ -172,6 +170,7 @@ alpn_get_spec(http_majors allowed, bool use_alpn) Avoid "http/1.0" because some servers do not support it. */ return &ALPN_SPEC_H11; } +#endif /* !CURL_DISABLE_HTTP || !CURL_DISABLE_PROXY */ #endif /* USE_SSL */ @@ -212,12 +211,12 @@ match_ssl_primary_config(struct Curl_easy *data, !Curl_timestrcmp(c1->username, c2->username) && !Curl_timestrcmp(c1->password, c2->password) && #endif - strcasecompare(c1->cipher_list, c2->cipher_list) && - strcasecompare(c1->cipher_list13, c2->cipher_list13) && - strcasecompare(c1->curves, c2->curves) && - strcasecompare(c1->signature_algorithms, c2->signature_algorithms) && - strcasecompare(c1->CRLfile, c2->CRLfile) && - strcasecompare(c1->pinned_key, c2->pinned_key)) + curl_strequal(c1->cipher_list, c2->cipher_list) && + curl_strequal(c1->cipher_list13, c2->cipher_list13) && + curl_strequal(c1->curves, c2->curves) && + curl_strequal(c1->signature_algorithms, c2->signature_algorithms) && + curl_strequal(c1->CRLfile, c2->CRLfile) && + curl_strequal(c1->pinned_key, c2->pinned_key)) return TRUE; return FALSE; @@ -491,7 +490,7 @@ static void cf_ctx_free(struct ssl_connect_data *ctx) } CURLcode Curl_ssl_get_channel_binding(struct Curl_easy *data, int sockindex, - struct dynbuf *binding) + struct dynbuf *binding) { if(Curl_ssl->get_channel_binding) return Curl_ssl->get_channel_binding(data, sockindex, binding); @@ -504,26 +503,30 @@ void Curl_ssl_close_all(struct Curl_easy *data) Curl_ssl->close_all(data); } -void Curl_ssl_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data, - struct easy_pollset *ps) +CURLcode Curl_ssl_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { struct ssl_connect_data *connssl = cf->ctx; if(connssl->io_need) { curl_socket_t sock = Curl_conn_cf_get_socket(cf->next, data); + CURLcode result = CURLE_OK; if(sock != CURL_SOCKET_BAD) { if(connssl->io_need & CURL_SSL_IO_NEED_SEND) { - Curl_pollset_set_out_only(data, ps, sock); + result = Curl_pollset_set_out_only(data, ps, sock); CURL_TRC_CF(data, cf, "adjust_pollset, POLLOUT fd=%" FMT_SOCKET_T, sock); } else { - Curl_pollset_set_in_only(data, ps, sock); + result = Curl_pollset_set_in_only(data, ps, sock); CURL_TRC_CF(data, cf, "adjust_pollset, POLLIN fd=%" FMT_SOCKET_T, sock); } } + return result; } + return CURLE_OK; } /* Selects an SSL crypto engine @@ -671,7 +674,7 @@ static CURLcode pubkey_pem_to_der(const char *pem, pem_count = begin_pos - pem; /* Invalid if not at beginning AND not directly following \n */ - if(0 != pem_count && '\n' != pem[pem_count - 1]) + if(pem_count && '\n' != pem[pem_count - 1]) return CURLE_BAD_CONTENT_ENCODING; /* 26 is length of "-----BEGIN PUBLIC KEY-----" */ @@ -878,16 +881,6 @@ bool Curl_ssl_cert_status_request(void) return FALSE; } -/* - * Check whether the SSL backend supports false start. - */ -bool Curl_ssl_false_start(void) -{ - if(Curl_ssl->false_start) - return Curl_ssl->false_start(); - return FALSE; -} - static int multissl_init(void) { if(multissl_setup(NULL)) @@ -897,6 +890,14 @@ static int multissl_init(void) return 1; } +static CURLcode multissl_random(struct Curl_easy *data, + unsigned char *entropy, size_t length) +{ + if(multissl_setup(NULL)) + return CURLE_FAILED_INIT; + return Curl_ssl->random(data, entropy, length); +} + static CURLcode multissl_connect(struct Curl_cfilter *cf, struct Curl_easy *data, bool *done) { @@ -905,13 +906,13 @@ static CURLcode multissl_connect(struct Curl_cfilter *cf, return Curl_ssl->do_connect(cf, data, done); } -static void multissl_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) +static CURLcode multissl_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { if(multissl_setup(NULL)) - return; - Curl_ssl->adjust_pollset(cf, data, ps); + return CURLE_OK; + return Curl_ssl->adjust_pollset(cf, data, ps); } static void *multissl_get_internals(struct ssl_connect_data *connssl, @@ -929,23 +930,23 @@ static void multissl_close(struct Curl_cfilter *cf, struct Curl_easy *data) Curl_ssl->close(cf, data); } -static ssize_t multissl_recv_plain(struct Curl_cfilter *cf, - struct Curl_easy *data, - char *buf, size_t len, CURLcode *code) +static CURLcode multissl_recv_plain(struct Curl_cfilter *cf, + struct Curl_easy *data, + char *buf, size_t len, size_t *pnread) { if(multissl_setup(NULL)) return CURLE_FAILED_INIT; - return Curl_ssl->recv_plain(cf, data, buf, len, code); + return Curl_ssl->recv_plain(cf, data, buf, len, pnread); } -static ssize_t multissl_send_plain(struct Curl_cfilter *cf, - struct Curl_easy *data, - const void *mem, size_t len, - CURLcode *code) +static CURLcode multissl_send_plain(struct Curl_cfilter *cf, + struct Curl_easy *data, + const void *mem, size_t len, + size_t *pnwritten) { if(multissl_setup(NULL)) return CURLE_FAILED_INIT; - return Curl_ssl->send_plain(cf, data, mem, len, code); + return Curl_ssl->send_plain(cf, data, mem, len, pnwritten); } static const struct Curl_ssl Curl_ssl_multi = { @@ -958,7 +959,7 @@ static const struct Curl_ssl Curl_ssl_multi = { multissl_version, /* version */ NULL, /* shutdown */ NULL, /* data_pending */ - NULL, /* random */ + multissl_random, /* random */ NULL, /* cert_status_request */ multissl_connect, /* connect */ multissl_adjust_pollset, /* adjust_pollset */ @@ -968,7 +969,6 @@ static const struct Curl_ssl Curl_ssl_multi = { NULL, /* set_engine */ NULL, /* set_engine_default */ NULL, /* engines_list */ - NULL, /* false_start */ NULL, /* sha256sum */ multissl_recv_plain, /* recv decrypted data */ multissl_send_plain, /* send data to encrypt */ @@ -976,7 +976,7 @@ static const struct Curl_ssl Curl_ssl_multi = { }; const struct Curl_ssl *Curl_ssl = -#if defined(CURL_WITH_MULTI_SSL) +#ifdef CURL_WITH_MULTI_SSL &Curl_ssl_multi; #elif defined(USE_WOLFSSL) &Curl_ssl_wolfssl; @@ -988,39 +988,29 @@ const struct Curl_ssl *Curl_ssl = &Curl_ssl_rustls; #elif defined(USE_OPENSSL) &Curl_ssl_openssl; -#elif defined(USE_SECTRANSP) - &Curl_ssl_sectransp; #elif defined(USE_SCHANNEL) &Curl_ssl_schannel; -#elif defined(USE_BEARSSL) - &Curl_ssl_bearssl; #else #error "Missing struct Curl_ssl for selected SSL backend" #endif static const struct Curl_ssl *available_backends[] = { -#if defined(USE_WOLFSSL) +#ifdef USE_WOLFSSL &Curl_ssl_wolfssl, #endif -#if defined(USE_GNUTLS) +#ifdef USE_GNUTLS &Curl_ssl_gnutls, #endif -#if defined(USE_MBEDTLS) +#ifdef USE_MBEDTLS &Curl_ssl_mbedtls, #endif -#if defined(USE_OPENSSL) +#ifdef USE_OPENSSL &Curl_ssl_openssl, #endif -#if defined(USE_SECTRANSP) - &Curl_ssl_sectransp, -#endif -#if defined(USE_SCHANNEL) +#ifdef USE_SCHANNEL &Curl_ssl_schannel, #endif -#if defined(USE_BEARSSL) - &Curl_ssl_bearssl, -#endif -#if defined(USE_RUSTLS) +#ifdef USE_RUSTLS &Curl_ssl_rustls, #endif NULL @@ -1033,7 +1023,7 @@ void Curl_ssl_cleanup(void) /* only cleanup if we did a previous init */ if(Curl_ssl->cleanup) Curl_ssl->cleanup(); -#if defined(CURL_WITH_MULTI_SSL) +#ifdef CURL_WITH_MULTI_SSL Curl_ssl = &Curl_ssl_multi; #endif init_ssl = FALSE; @@ -1099,7 +1089,7 @@ static int multissl_setup(const struct Curl_ssl *backend) env = curl_getenv("CURL_SSL_BACKEND"); if(env) { for(i = 0; available_backends[i]; i++) { - if(strcasecompare(env, available_backends[i]->info.name)) { + if(curl_strequal(env, available_backends[i]->info.name)) { Curl_ssl = available_backends[i]; free(env); return 0; @@ -1109,8 +1099,8 @@ static int multissl_setup(const struct Curl_ssl *backend) #ifdef CURL_DEFAULT_SSL_BACKEND for(i = 0; available_backends[i]; i++) { - if(strcasecompare(CURL_DEFAULT_SSL_BACKEND, - available_backends[i]->info.name)) { + if(curl_strequal(CURL_DEFAULT_SSL_BACKEND, + available_backends[i]->info.name)) { Curl_ssl = available_backends[i]; free(env); return 0; @@ -1136,9 +1126,9 @@ CURLsslset Curl_init_sslset_nolock(curl_sslbackend id, const char *name, if(Curl_ssl != &Curl_ssl_multi) return id == Curl_ssl->info.id || - (name && strcasecompare(name, Curl_ssl->info.name)) ? + (name && curl_strequal(name, Curl_ssl->info.name)) ? CURLSSLSET_OK : -#if defined(CURL_WITH_MULTI_SSL) +#ifdef CURL_WITH_MULTI_SSL CURLSSLSET_TOO_LATE; #else CURLSSLSET_UNKNOWN_BACKEND; @@ -1146,7 +1136,7 @@ CURLsslset Curl_init_sslset_nolock(curl_sslbackend id, const char *name, for(i = 0; available_backends[i]; i++) { if(available_backends[i]->info.id == id || - (name && strcasecompare(available_backends[i]->info.name, name))) { + (name && curl_strequal(available_backends[i]->info.name, name))) { multissl_setup(available_backends[i]); return CURLSSLSET_OK; } @@ -1372,7 +1362,7 @@ static CURLcode ssl_cf_set_earlydata(struct Curl_cfilter *cf, const void *buf, size_t blen) { struct ssl_connect_data *connssl = cf->ctx; - ssize_t nwritten = 0; + size_t nwritten = 0; CURLcode result = CURLE_OK; DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_await); @@ -1380,10 +1370,10 @@ static CURLcode ssl_cf_set_earlydata(struct Curl_cfilter *cf, if(blen) { if(blen > connssl->earlydata_max) blen = connssl->earlydata_max; - nwritten = Curl_bufq_write(&connssl->earlydata, buf, blen, &result); + result = Curl_bufq_write(&connssl->earlydata, buf, blen, &nwritten); CURL_TRC_CF(data, cf, "ssl_cf_set_earlydata(len=%zu) -> %zd", blen, nwritten); - if(nwritten < 0) + if(result) return result; } return CURLE_OK; @@ -1455,29 +1445,26 @@ static bool ssl_cf_data_pending(struct Curl_cfilter *cf, return result; } -static ssize_t ssl_cf_send(struct Curl_cfilter *cf, - struct Curl_easy *data, - const void *buf, size_t blen, - bool eos, CURLcode *err) +static CURLcode ssl_cf_send(struct Curl_cfilter *cf, + struct Curl_easy *data, + const void *buf, size_t blen, + bool eos, size_t *pnwritten) { struct ssl_connect_data *connssl = cf->ctx; struct cf_call_data save; - ssize_t nwritten = 0, early_written = 0; + CURLcode result = CURLE_OK; (void)eos; - *err = CURLE_OK; + *pnwritten = 0; CF_DATA_SAVE(save, cf, data); if(connssl->state == ssl_connection_deferred) { bool done = FALSE; - *err = ssl_cf_connect_deferred(cf, data, buf, blen, &done); - if(*err) { - nwritten = -1; + result = ssl_cf_connect_deferred(cf, data, buf, blen, &done); + if(result) goto out; - } else if(!done) { - *err = CURLE_AGAIN; - nwritten = -1; + result = CURLE_AGAIN; goto out; } DEBUGASSERT(connssl->state == ssl_connection_complete); @@ -1486,12 +1473,12 @@ static ssize_t ssl_cf_send(struct Curl_cfilter *cf, if(connssl->earlydata_skip) { if(connssl->earlydata_skip >= blen) { connssl->earlydata_skip -= blen; - *err = CURLE_OK; - nwritten = (ssize_t)blen; + result = CURLE_OK; + *pnwritten = blen; goto out; } else { - early_written = connssl->earlydata_skip; + *pnwritten = connssl->earlydata_skip; buf = ((const char *)buf) + connssl->earlydata_skip; blen -= connssl->earlydata_skip; connssl->earlydata_skip = 0; @@ -1499,56 +1486,45 @@ static ssize_t ssl_cf_send(struct Curl_cfilter *cf, } /* OpenSSL and maybe other TLS libs do not like 0-length writes. Skip. */ - if(blen > 0) - nwritten = connssl->ssl_impl->send_plain(cf, data, buf, blen, err); - - if(nwritten >= 0) - nwritten += early_written; + if(blen > 0) { + size_t nwritten; + result = connssl->ssl_impl->send_plain(cf, data, buf, blen, &nwritten); + if(!result) + *pnwritten += nwritten; + } out: CF_DATA_RESTORE(cf, save); - return nwritten; + return result; } -static ssize_t ssl_cf_recv(struct Curl_cfilter *cf, - struct Curl_easy *data, char *buf, size_t len, - CURLcode *err) +static CURLcode ssl_cf_recv(struct Curl_cfilter *cf, + struct Curl_easy *data, char *buf, size_t len, + size_t *pnread) { struct ssl_connect_data *connssl = cf->ctx; struct cf_call_data save; - ssize_t nread; + CURLcode result = CURLE_OK; CF_DATA_SAVE(save, cf, data); - *err = CURLE_OK; + *pnread = 0; if(connssl->state == ssl_connection_deferred) { bool done = FALSE; - *err = ssl_cf_connect_deferred(cf, data, NULL, 0, &done); - if(*err) { - nread = -1; + result = ssl_cf_connect_deferred(cf, data, NULL, 0, &done); + if(result) goto out; - } else if(!done) { - *err = CURLE_AGAIN; - nread = -1; + result = CURLE_AGAIN; goto out; } DEBUGASSERT(connssl->state == ssl_connection_complete); } - nread = connssl->ssl_impl->recv_plain(cf, data, buf, len, err); - if(nread > 0) { - DEBUGASSERT((size_t)nread <= len); - } - else if(nread == 0) { - /* eof */ - *err = CURLE_OK; - } + result = connssl->ssl_impl->recv_plain(cf, data, buf, len, pnread); out: - CURL_TRC_CF(data, cf, "cf_recv(len=%zu) -> %zd, %d", len, - nread, *err); CF_DATA_RESTORE(cf, save); - return nread; + return result; } static CURLcode ssl_cf_shutdown(struct Curl_cfilter *cf, @@ -1573,16 +1549,18 @@ static CURLcode ssl_cf_shutdown(struct Curl_cfilter *cf, return result; } -static void ssl_cf_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) +static CURLcode ssl_cf_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { struct ssl_connect_data *connssl = cf->ctx; struct cf_call_data save; + CURLcode result; CF_DATA_SAVE(save, cf, data); - connssl->ssl_impl->adjust_pollset(cf, data, ps); + result = connssl->ssl_impl->adjust_pollset(cf, data, ps); CF_DATA_RESTORE(cf, save); + return result; } static CURLcode ssl_cf_query(struct Curl_cfilter *cf, @@ -1598,6 +1576,27 @@ static CURLcode ssl_cf_query(struct Curl_cfilter *cf, *when = connssl->handshake_done; return CURLE_OK; } + case CF_QUERY_SSL_INFO: + case CF_QUERY_SSL_CTX_INFO: + if(!Curl_ssl_cf_is_proxy(cf)) { + struct curl_tlssessioninfo *info = pres2; + struct cf_call_data save; + CF_DATA_SAVE(save, cf, data); + info->backend = Curl_ssl_backend(); + info->internals = connssl->ssl_impl->get_internals( + cf->ctx, (query == CF_QUERY_SSL_INFO) ? + CURLINFO_TLS_SSL_PTR : CURLINFO_TLS_SESSION); + CF_DATA_RESTORE(cf, save); + return CURLE_OK; + } + break; + case CF_QUERY_ALPN_NEGOTIATED: { + const char **palpn = pres2; + DEBUGASSERT(palpn); + *palpn = connssl->negotiated.alpn; + CURL_TRC_CF(data, cf, "query ALPN: returning '%s'", *palpn); + return CURLE_OK; + } default: break; } @@ -1606,6 +1605,30 @@ static CURLcode ssl_cf_query(struct Curl_cfilter *cf, CURLE_UNKNOWN_OPTION; } +static CURLcode ssl_cf_cntrl(struct Curl_cfilter *cf, + struct Curl_easy *data, + int event, int arg1, void *arg2) +{ + struct ssl_connect_data *connssl = cf->ctx; + + (void)arg1; + (void)arg2; + (void)data; + switch(event) { + case CF_CTRL_CONN_INFO_UPDATE: + if(connssl->negotiated.alpn && !cf->sockindex) { + if(!strcmp("http/1.1", connssl->negotiated.alpn)) + cf->conn->httpversion_seen = 11; + else if(!strcmp("h2", connssl->negotiated.alpn)) + cf->conn->httpversion_seen = 20; + else if(!strcmp("h3", connssl->negotiated.alpn)) + cf->conn->httpversion_seen = 30; + } + break; + } + return CURLE_OK; +} + static bool cf_ssl_is_alive(struct Curl_cfilter *cf, struct Curl_easy *data, bool *input_pending) { @@ -1625,12 +1648,11 @@ struct Curl_cftype Curl_cft_ssl = { ssl_cf_connect, ssl_cf_close, ssl_cf_shutdown, - Curl_cf_def_get_host, ssl_cf_adjust_pollset, ssl_cf_data_pending, ssl_cf_send, ssl_cf_recv, - Curl_cf_def_cntrl, + ssl_cf_cntrl, cf_ssl_is_alive, Curl_cf_def_conn_keep_alive, ssl_cf_query, @@ -1646,7 +1668,6 @@ struct Curl_cftype Curl_cft_ssl_proxy = { ssl_cf_connect, ssl_cf_close, ssl_cf_shutdown, - Curl_cf_def_get_host, ssl_cf_adjust_pollset, ssl_cf_data_pending, ssl_cf_send, @@ -1654,7 +1675,7 @@ struct Curl_cftype Curl_cft_ssl_proxy = { Curl_cf_def_cntrl, cf_ssl_is_alive, Curl_cf_def_conn_keep_alive, - Curl_cf_def_query, + ssl_cf_query, }; #endif /* !CURL_DISABLE_PROXY */ @@ -1670,6 +1691,7 @@ static CURLcode cf_ssl_create(struct Curl_cfilter **pcf, DEBUGASSERT(data->conn); #ifdef CURL_DISABLE_HTTP + (void)conn; /* We only support ALPN for HTTP so far. */ DEBUGASSERT(!conn->bits.tls_enable_alpn); ctx = cf_ctx_new(data, NULL); @@ -1725,9 +1747,11 @@ static CURLcode cf_ssl_proxy_create(struct Curl_cfilter **pcf, struct Curl_cfilter *cf = NULL; struct ssl_connect_data *ctx; CURLcode result; - bool use_alpn = conn->bits.tls_enable_alpn; + /* ALPN is default, but if user explicitly disables it, obey */ + bool use_alpn = data->set.ssl_enable_alpn; http_majors allowed = CURL_HTTP_V1x; + (void)conn; #ifdef USE_HTTP2 if(conn->http_proxy.proxytype == CURLPROXY_HTTPS2) { use_alpn = TRUE; @@ -1769,40 +1793,6 @@ bool Curl_ssl_supports(struct Curl_easy *data, unsigned int ssl_option) return (Curl_ssl->supports & ssl_option); } -static struct Curl_cfilter *get_ssl_filter(struct Curl_cfilter *cf) -{ - for(; cf; cf = cf->next) { - if(cf->cft == &Curl_cft_ssl) - return cf; -#ifndef CURL_DISABLE_PROXY - if(cf->cft == &Curl_cft_ssl_proxy) - return cf; -#endif - } - return NULL; -} - - -void *Curl_ssl_get_internals(struct Curl_easy *data, int sockindex, - CURLINFO info, int n) -{ - void *result = NULL; - (void)n; - if(data->conn) { - struct Curl_cfilter *cf; - /* get first SSL filter in chain, if any is present */ - cf = get_ssl_filter(data->conn->cfilter[sockindex]); - if(cf) { - struct ssl_connect_data *connssl = cf->ctx; - struct cf_call_data save; - CF_DATA_SAVE(save, cf, data); - result = connssl->ssl_impl->get_internals(cf->ctx, info); - CF_DATA_RESTORE(cf, save); - } - } - return result; -} - static CURLcode vtls_shutdown_blocking(struct Curl_cfilter *cf, struct Curl_easy *data, bool send_shutdown, bool *done) @@ -1841,7 +1831,7 @@ static CURLcode vtls_shutdown_blocking(struct Curl_cfilter *cf, result = CURLE_RECV_ERROR; goto out; } - else if(0 == what) { + else if(what == 0) { /* timeout */ failf(data, "SSL shutdown timeout"); result = CURLE_OPERATION_TIMEDOUT; @@ -1990,14 +1980,7 @@ CURLcode Curl_alpn_set_negotiated(struct Curl_cfilter *cf, size_t proto_len) { CURLcode result = CURLE_OK; - unsigned char *palpn = -#ifndef CURL_DISABLE_PROXY - (cf->conn->bits.tunnel_proxy && Curl_ssl_cf_is_proxy(cf)) ? - &cf->conn->proxy_alpn : &cf->conn->alpn -#else - &cf->conn->alpn -#endif - ; + (void)cf; if(connssl->negotiated.alpn) { /* When we ask for a specific ALPN protocol, we need the confirmation @@ -2039,38 +2022,12 @@ CURLcode Curl_alpn_set_negotiated(struct Curl_cfilter *cf, } if(proto && proto_len) { - if(proto_len == ALPN_HTTP_1_1_LENGTH && - !memcmp(ALPN_HTTP_1_1, proto, ALPN_HTTP_1_1_LENGTH)) { - *palpn = CURL_HTTP_VERSION_1_1; - } -#ifdef USE_HTTP2 - else if(proto_len == ALPN_H2_LENGTH && - !memcmp(ALPN_H2, proto, ALPN_H2_LENGTH)) { - *palpn = CURL_HTTP_VERSION_2; - } -#endif -#ifdef USE_HTTP3 - else if(proto_len == ALPN_H3_LENGTH && - !memcmp(ALPN_H3, proto, ALPN_H3_LENGTH)) { - *palpn = CURL_HTTP_VERSION_3; - } -#endif - else { - *palpn = CURL_HTTP_VERSION_NONE; - failf(data, "unsupported ALPN protocol: '%.*s'", (int)proto_len, proto); - /* Previous code just ignored it and some vtls backends even ignore the - * return code of this function. */ - /* return CURLE_NOT_BUILT_IN; */ - goto out; - } - if(connssl->state == ssl_connection_deferred) infof(data, VTLS_INFOF_ALPN_DEFERRED, (int)proto_len, proto); else infof(data, VTLS_INFOF_ALPN_ACCEPTED, (int)proto_len, proto); } else { - *palpn = CURL_HTTP_VERSION_NONE; if(connssl->state == ssl_connection_deferred) infof(data, VTLS_INFOF_NO_ALPN_DEFERRED); else diff --git a/vendor/curl/lib/vtls/vtls.h b/vendor/curl/lib/vtls/vtls.h index 0bb333b987a..c62b8ae2584 100644 --- a/vendor/curl/lib/vtls/vtls.h +++ b/vendor/curl/lib/vtls/vtls.h @@ -190,8 +190,6 @@ CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data, bool Curl_ssl_cert_status_request(void); -bool Curl_ssl_false_start(void); - /* The maximum size of the SSL channel binding is 85 bytes, as defined in * RFC 5929, Section 4.1. The 'tls-server-end-point:' prefix is 21 bytes long, * and SHA-512 is the longest supported hash algorithm, with a digest length of @@ -209,7 +207,7 @@ bool Curl_ssl_false_start(void); * returned. */ CURLcode Curl_ssl_get_channel_binding(struct Curl_easy *data, int sockindex, - struct dynbuf *binding); + struct dynbuf *binding); #define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */ @@ -235,16 +233,6 @@ CURLcode Curl_cf_ssl_proxy_insert_after(struct Curl_cfilter *cf_at, */ bool Curl_ssl_supports(struct Curl_easy *data, unsigned int ssl_option); -/** - * Get the internal ssl instance (like OpenSSL's SSL*) from the filter - * chain at `sockindex` of type specified by `info`. - * For `n` == 0, the first active (top down) instance is returned. - * 1 gives the second active, etc. - * NULL is returned when no active SSL filter is present. - */ -void *Curl_ssl_get_internals(struct Curl_easy *data, int sockindex, - CURLINFO info, int n); - /** * Get the ssl_config_data in `data` that is relevant for cfilter `cf`. */ @@ -274,8 +262,6 @@ extern struct Curl_cftype Curl_cft_ssl_proxy; #define Curl_ssl_free_certinfo(x) Curl_nop_stmt #define Curl_ssl_random(x,y,z) ((void)x, CURLE_NOT_BUILT_IN) #define Curl_ssl_cert_status_request() FALSE -#define Curl_ssl_false_start() FALSE -#define Curl_ssl_get_internals(a,b,c,d) NULL #define Curl_ssl_supports(a,b) FALSE #define Curl_ssl_cfilter_add(a,b,c) CURLE_NOT_BUILT_IN #define Curl_ssl_cfilter_remove(a,b,c) CURLE_OK diff --git a/vendor/curl/lib/vtls/vtls_int.h b/vendor/curl/lib/vtls/vtls_int.h index 0632a07657d..de0b735e22b 100644 --- a/vendor/curl/lib/vtls/vtls_int.h +++ b/vendor/curl/lib/vtls/vtls_int.h @@ -127,6 +127,7 @@ struct ssl_connect_data { BIT(use_alpn); /* if ALPN shall be used in handshake */ BIT(peer_closed); /* peer has closed connection */ BIT(prefs_checked); /* SSL preferences have been checked */ + BIT(input_pending); /* data for SSL_read() may be available */ }; @@ -165,8 +166,8 @@ struct Curl_ssl { /* During handshake/shutdown, adjust the pollset to include the socket * for POLLOUT or POLLIN as needed. Mandatory. */ - void (*adjust_pollset)(struct Curl_cfilter *cf, struct Curl_easy *data, - struct easy_pollset *ps); + CURLcode (*adjust_pollset)(struct Curl_cfilter *cf, struct Curl_easy *data, + struct easy_pollset *ps); void *(*get_internals)(struct ssl_connect_data *connssl, CURLINFO info); void (*close)(struct Curl_cfilter *cf, struct Curl_easy *data); void (*close_all)(struct Curl_easy *data); @@ -175,13 +176,12 @@ struct Curl_ssl { CURLcode (*set_engine_default)(struct Curl_easy *data); struct curl_slist *(*engines_list)(struct Curl_easy *data); - bool (*false_start)(void); CURLcode (*sha256sum)(const unsigned char *input, size_t inputlen, unsigned char *sha256sum, size_t sha256sumlen); - ssize_t (*recv_plain)(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t len, CURLcode *code); - ssize_t (*send_plain)(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *mem, size_t len, CURLcode *code); + CURLcode (*recv_plain)(struct Curl_cfilter *cf, struct Curl_easy *data, + char *buf, size_t len, size_t *pnread); + CURLcode (*send_plain)(struct Curl_cfilter *cf, struct Curl_easy *data, + const void *mem, size_t len, size_t *pnwritten); CURLcode (*get_channel_binding)(struct Curl_easy *data, int sockindex, struct dynbuf *binding); @@ -190,8 +190,9 @@ struct Curl_ssl { extern const struct Curl_ssl *Curl_ssl; -void Curl_ssl_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data, - struct easy_pollset *ps); +CURLcode Curl_ssl_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps); /** * Get the SSL filter below the given one or NULL if there is none. diff --git a/vendor/curl/lib/vtls/vtls_scache.c b/vendor/curl/lib/vtls/vtls_scache.c index 1fe4b5bbdee..662539cd896 100644 --- a/vendor/curl/lib/vtls/vtls_scache.c +++ b/vendor/curl/lib/vtls/vtls_scache.c @@ -29,9 +29,6 @@ #ifdef HAVE_SYS_TYPES_H #include #endif -#ifdef HAVE_SYS_STAT_H -#include -#endif #ifdef HAVE_FCNTL_H #include #endif @@ -376,9 +373,9 @@ void Curl_ssl_scache_unlock(struct Curl_easy *data) } static CURLcode cf_ssl_peer_key_add_path(struct dynbuf *buf, - const char *name, - char *path, - bool *is_local) + const char *name, + char *path, + bool *is_local) { if(path && path[0]) { /* We try to add absolute paths, so that the session key can stay @@ -410,8 +407,8 @@ static CURLcode cf_ssl_peer_key_add_path(struct dynbuf *buf, } static CURLcode cf_ssl_peer_key_add_hash(struct dynbuf *buf, - const char *name, - struct curl_blob *blob) + const char *name, + struct curl_blob *blob) { CURLcode r = CURLE_OK; if(blob && blob->len) { @@ -649,7 +646,7 @@ cf_ssl_find_peer_by_key(struct Curl_easy *data, /* check for entries with known peer_key */ for(i = 0; scache && i < scache->peer_count; i++) { if(scache->peers[i].ssl_peer_key && - strcasecompare(ssl_peer_key, scache->peers[i].ssl_peer_key) && + curl_strequal(ssl_peer_key, scache->peers[i].ssl_peer_key) && cf_ssl_scache_match_auth(&scache->peers[i], conn_config)) { /* yes, we have a cached session for this! */ *ppeer = &scache->peers[i]; @@ -868,9 +865,9 @@ CURLcode Curl_ssl_scache_put(struct Curl_cfilter *cf, } void Curl_ssl_scache_return(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *ssl_peer_key, - struct Curl_ssl_session *s) + struct Curl_easy *data, + const char *ssl_peer_key, + struct Curl_ssl_session *s) { /* See RFC 8446 C.4: * "Clients SHOULD NOT reuse a ticket for multiple connections." */ diff --git a/vendor/curl/lib/vtls/vtls_scache.h b/vendor/curl/lib/vtls/vtls_scache.h index eef50805e4e..deedccfe8c6 100644 --- a/vendor/curl/lib/vtls/vtls_scache.h +++ b/vendor/curl/lib/vtls/vtls_scache.h @@ -206,12 +206,6 @@ CURLcode Curl_ssl_session_export(struct Curl_easy *data, void *userptr); #endif /* USE_SSLS_EXPORT */ - -#else /* USE_SSL */ - -#define Curl_ssl_scache_create(x,y,z) ((void)x, CURLE_OK) -#define Curl_ssl_scache_destroy(x) do {} while(0) - -#endif /* USE_SSL (else) */ +#endif /* USE_SSL */ #endif /* HEADER_CURL_VTLS_SCACHE_H */ diff --git a/vendor/curl/lib/vtls/vtls_spack.c b/vendor/curl/lib/vtls/vtls_spack.c index 152fad7eb30..10d16f213d4 100644 --- a/vendor/curl/lib/vtls/vtls_spack.c +++ b/vendor/curl/lib/vtls/vtls_spack.c @@ -24,7 +24,7 @@ #include "../curl_setup.h" -#ifdef USE_SSLS_EXPORT +#if defined(USE_SSL) && defined(USE_SSLS_EXPORT) #include "../urldata.h" #include "../curl_trc.h" @@ -343,4 +343,4 @@ CURLcode Curl_ssl_session_unpack(struct Curl_easy *data, return r; } -#endif /* USE_SSLS_EXPORT */ +#endif /* USE_SSL && USE_SSLS_EXPORT */ diff --git a/vendor/curl/lib/vtls/vtls_spack.h b/vendor/curl/lib/vtls/vtls_spack.h index 4cdabae30e6..86796ee62ed 100644 --- a/vendor/curl/lib/vtls/vtls_spack.h +++ b/vendor/curl/lib/vtls/vtls_spack.h @@ -25,7 +25,7 @@ ***************************************************************************/ #include "../curl_setup.h" -#ifdef USE_SSLS_EXPORT +#if defined(USE_SSL) && defined(USE_SSLS_EXPORT) struct dynbuf; struct Curl_ssl_session; @@ -38,6 +38,6 @@ CURLcode Curl_ssl_session_unpack(struct Curl_easy *data, const void *bufv, size_t buflen, struct Curl_ssl_session **ps); -#endif /* USE_SSLS_EXPORT */ +#endif /* USE_SSL && USE_SSLS_EXPORT */ #endif /* HEADER_CURL_VTLS_SPACK_H */ diff --git a/vendor/curl/lib/vtls/wolfssl.c b/vendor/curl/lib/vtls/wolfssl.c index 9c6f5182605..9a84b3384c8 100644 --- a/vendor/curl/lib/vtls/wolfssl.c +++ b/vendor/curl/lib/vtls/wolfssl.c @@ -67,7 +67,6 @@ #include "../connect.h" /* for the connect timeout */ #include "../progress.h" #include "../select.h" -#include "../strcase.h" #include "../strdup.h" #include "x509asn1.h" #include "../curl_printf.h" @@ -179,7 +178,7 @@ wssl_tls13_secret_callback(SSL *ssl, int id, const unsigned char *secret, Curl_tls_keylog_write(label, client_random, secret, secretSz); return 0; } -#endif /* defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13) */ +#endif /* HAVE_SECRET_CALLBACK && WOLFSSL_TLS13 */ static void wssl_log_tls12_secret(WOLFSSL *ssl) { @@ -227,9 +226,9 @@ static int wssl_do_file_type(const char *type) { if(!type || !type[0]) return WOLFSSL_FILETYPE_PEM; - if(strcasecompare(type, "PEM")) + if(curl_strequal(type, "PEM")) return WOLFSSL_FILETYPE_PEM; - if(strcasecompare(type, "DER")) + if(curl_strequal(type, "DER")) return WOLFSSL_FILETYPE_ASN1; return -1; } @@ -244,9 +243,12 @@ static const struct group_name_map gnm[] = { { WOLFSSL_ML_KEM_512, "ML_KEM_512" }, { WOLFSSL_ML_KEM_768, "ML_KEM_768" }, { WOLFSSL_ML_KEM_1024, "ML_KEM_1024" }, - { WOLFSSL_P256_ML_KEM_512, "P256_ML_KEM_512" }, - { WOLFSSL_P384_ML_KEM_768, "P384_ML_KEM_768" }, - { WOLFSSL_P521_ML_KEM_1024, "P521_ML_KEM_1024" }, + { WOLFSSL_SECP256R1MLKEM512, "SecP256r1MLKEM512" }, + { WOLFSSL_SECP384R1MLKEM768, "SecP384r1MLKEM768" }, + { WOLFSSL_SECP521R1MLKEM1024, "SecP521r1MLKEM1024" }, + { WOLFSSL_SECP256R1MLKEM768, "SecP256r1MLKEM768" }, + { WOLFSSL_SECP384R1MLKEM1024, "SecP384r1MLKEM1024" }, + { WOLFSSL_X25519MLKEM768, "X25519MLKEM768" }, { 0, NULL } }; #endif @@ -319,7 +321,7 @@ static int wssl_bio_cf_out_write(WOLFSSL_BIO *bio, struct ssl_connect_data *connssl = cf->ctx; struct wssl_ctx *wssl = (struct wssl_ctx *)connssl->backend; struct Curl_easy *data = CF_DATA_CURRENT(cf); - ssize_t nwritten, skiplen = 0; + size_t nwritten, skiplen = 0; CURLcode result = CURLE_OK; DEBUGASSERT(data); @@ -333,21 +335,21 @@ static int wssl_bio_cf_out_write(WOLFSSL_BIO *bio, skiplen = (ssize_t)(blen - wssl->io_send_blocked_len); blen = wssl->io_send_blocked_len; } - nwritten = Curl_conn_cf_send(cf->next, data, buf, blen, FALSE, &result); + result = Curl_conn_cf_send(cf->next, data, buf, blen, FALSE, &nwritten); wssl->io_result = result; - CURL_TRC_CF(data, cf, "bio_write(len=%d) -> %zd, %d", - blen, nwritten, result); + CURL_TRC_CF(data, cf, "bio_write(len=%d) -> %d, %zu", + blen, result, nwritten); #ifdef USE_FULL_BIO wolfSSL_BIO_clear_retry_flags(bio); #endif - if(nwritten < 0 && CURLE_AGAIN == result) { + if(CURLE_AGAIN == result) { wolfSSL_BIO_set_retry_write(bio); if(wssl->shutting_down && !wssl->io_send_blocked_len) wssl->io_send_blocked_len = blen; } else if(!result && skiplen) nwritten += skiplen; - return (int)nwritten; + return result ? -1 : (int)nwritten; } static int wssl_bio_cf_in_read(WOLFSSL_BIO *bio, char *buf, int blen) @@ -356,7 +358,7 @@ static int wssl_bio_cf_in_read(WOLFSSL_BIO *bio, char *buf, int blen) struct ssl_connect_data *connssl = cf->ctx; struct wssl_ctx *wssl = (struct wssl_ctx *)connssl->backend; struct Curl_easy *data = CF_DATA_CURRENT(cf); - ssize_t nread; + size_t nread; CURLcode result = CURLE_OK; DEBUGASSERT(data); @@ -376,17 +378,17 @@ static int wssl_bio_cf_in_read(WOLFSSL_BIO *bio, char *buf, int blen) } } - nread = Curl_conn_cf_recv(cf->next, data, buf, blen, &result); + result = Curl_conn_cf_recv(cf->next, data, buf, blen, &nread); wssl->io_result = result; - CURL_TRC_CF(data, cf, "bio_read(len=%d) -> %zd, %d", blen, nread, result); + CURL_TRC_CF(data, cf, "bio_read(len=%d) -> %d, %zu", blen, result, nread); #ifdef USE_FULL_BIO wolfSSL_BIO_clear_retry_flags(bio); #endif - if(nread < 0 && CURLE_AGAIN == result) + if(CURLE_AGAIN == result) wolfSSL_BIO_set_retry_read(bio); else if(nread == 0) connssl->peer_closed = TRUE; - return (int)nread; + return result ? -1 : (int)nread; } static WOLFSSL_BIO_METHOD *wssl_bio_cf_method = NULL; @@ -518,7 +520,7 @@ static CURLcode wssl_on_session_reuse(struct Curl_cfilter *cf, #endif if(!connssl->earlydata_max) { - /* Seems to be GnuTLS way to signal no EarlyData in session */ + /* Seems to be no WolfSSL way to signal no EarlyData in session */ CURL_TRC_CF(data, cf, "SSL session does not allow earlydata"); } else if(!Curl_alpn_contains_proto(alpns, scs->alpn)) { @@ -929,7 +931,7 @@ wssl_legacy_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) static int wssl_legacy_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int version) { - (void) ctx, (void) version; + (void)ctx, (void)version; return WOLFSSL_NOT_IMPLEMENTED; } #define wolfSSL_CTX_set_min_proto_version wssl_legacy_CTX_set_min_proto_version @@ -962,6 +964,7 @@ CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx, size_t idx = 0; #endif CURLcode result = CURLE_FAILED_INIT; + unsigned char transport; DEBUGASSERT(!wctx->ssl_ctx); DEBUGASSERT(!wctx->ssl); @@ -971,6 +974,8 @@ CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx, goto out; } Curl_alpn_copy(&alpns, alpns_requested); + DEBUGASSERT(cf->next); + transport = Curl_conn_cf_get_transport(cf->next, data); #if LIBWOLFSSL_VERSION_HEX < 0x04002000 /* 4.2.0 (2019) */ req_method = wolfSSLv23_client_method(); @@ -1101,7 +1106,7 @@ CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx, #endif curves = conn_config->curves; - if(!curves && cf->conn->transport == TRNSPRT_QUIC) + if(!curves && (transport == TRNSPRT_QUIC)) curves = (char *)CURL_UNCONST(QUIC_GROUPS); if(curves) { @@ -1242,8 +1247,7 @@ CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx, } #endif - if(ssl_config->primary.cache_session && - cf->conn->transport != TRNSPRT_QUIC) { + if(ssl_config->primary.cache_session && (transport != TRNSPRT_QUIC)) { /* Register to get notified when a new session is received */ wolfSSL_CTX_sess_set_new_cb(wctx->ssl_ctx, wssl_vtls_new_session_cb); } @@ -1289,7 +1293,7 @@ CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx, wolfSSL_set_app_data(wctx->ssl, ssl_user_data); #ifdef WOLFSSL_QUIC - if(cf->conn->transport == TRNSPRT_QUIC) + if(transport == TRNSPRT_QUIC) wolfSSL_set_quic_use_legacy_codepoint(wctx->ssl, 0); #endif @@ -1538,6 +1542,7 @@ CURLcode Curl_wssl_verify_pinned(struct Curl_cfilter *cf, data->set.str[STRING_SSL_PINNEDPUBLICKEY]; #else const char * const pinnedpubkey = data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + (void)cf; #endif if(pinnedpubkey) { @@ -1754,7 +1759,7 @@ static CURLcode wssl_handshake(struct Curl_cfilter *cf, } } #ifdef USE_ECH_WOLFSSL - else if(-1 == detail) { + else if(detail == -1) { /* try access a retry_config ECHConfigList for tracing */ byte echConfigs[1000]; word32 echConfigsLen = 1000; @@ -1789,49 +1794,48 @@ static CURLcode wssl_handshake(struct Curl_cfilter *cf, } } -static ssize_t wssl_send(struct Curl_cfilter *cf, - struct Curl_easy *data, - const void *buf, size_t blen, - CURLcode *curlcode) +static CURLcode wssl_send(struct Curl_cfilter *cf, + struct Curl_easy *data, + const void *buf, size_t blen, + size_t *pnwritten) { struct ssl_connect_data *connssl = cf->ctx; struct wssl_ctx *wssl = (struct wssl_ctx *)connssl->backend; - size_t total_written = 0; - ssize_t nwritten = -1; - DEBUGASSERT(wssl); + CURLcode result = CURLE_OK; + int nwritten; + DEBUGASSERT(wssl); + *pnwritten = 0; wolfSSL_ERR_clear_error(); if(blen) { int memlen = (blen > (size_t)INT_MAX) ? INT_MAX : (int)blen; - int rc; - rc = wolfSSL_write(wssl->ssl, buf, memlen); - if(rc <= 0) { - int err = wolfSSL_get_error(wssl->ssl, rc); + nwritten = wolfSSL_write(wssl->ssl, buf, memlen); + + if(nwritten > 0) + *pnwritten += (size_t)nwritten; + else { + int err = wolfSSL_get_error(wssl->ssl, nwritten); switch(err) { case WOLFSSL_ERROR_WANT_READ: case WOLFSSL_ERROR_WANT_WRITE: /* there is data pending, re-invoke wolfSSL_write() */ - if(total_written) { - *curlcode = CURLE_OK; - nwritten = total_written; + if(*pnwritten) { + result = CURLE_OK; goto out; } - *curlcode = CURLE_AGAIN; - nwritten = -1; + result = CURLE_AGAIN; goto out; default: if(wssl->io_result == CURLE_AGAIN) { - if(total_written) { - *curlcode = CURLE_OK; - nwritten = total_written; + if(*pnwritten) { + result = CURLE_OK; goto out; } - *curlcode = CURLE_AGAIN; - nwritten = -1; + result = CURLE_AGAIN; goto out; } { @@ -1841,21 +1845,16 @@ static ssize_t wssl_send(struct Curl_cfilter *cf, sizeof(error_buffer)), SOCKERRNO); } - *curlcode = CURLE_SEND_ERROR; - nwritten = -1; + result = CURLE_SEND_ERROR; goto out; } } - else - total_written += rc; } - *curlcode = CURLE_OK; - nwritten = total_written; out: - CURL_TRC_CF(data, cf, "wssl_send(len=%zu) -> %" FMT_OFF_T ", %d", - blen, nwritten, *curlcode); - return nwritten; + CURL_TRC_CF(data, cf, "wssl_send(len=%zu) -> %d, %zu", + blen, result, *pnwritten); + return result; } static CURLcode wssl_shutdown(struct Curl_cfilter *cf, @@ -1968,7 +1967,7 @@ static void wssl_close(struct Curl_cfilter *cf, struct Curl_easy *data) struct ssl_connect_data *connssl = cf->ctx; struct wssl_ctx *wssl = (struct wssl_ctx *)connssl->backend; - (void) data; + (void)data; DEBUGASSERT(wssl); @@ -1982,10 +1981,10 @@ static void wssl_close(struct Curl_cfilter *cf, struct Curl_easy *data) } } -static ssize_t wssl_recv(struct Curl_cfilter *cf, - struct Curl_easy *data, - char *buf, size_t blen, - CURLcode *curlcode) +static CURLcode wssl_recv(struct Curl_cfilter *cf, + struct Curl_easy *data, + char *buf, size_t blen, + size_t *pnread) { struct ssl_connect_data *connssl = cf->ctx; struct wssl_ctx *wssl = (struct wssl_ctx *)connssl->backend; @@ -1994,41 +1993,38 @@ static ssize_t wssl_recv(struct Curl_cfilter *cf, DEBUGASSERT(wssl); + *pnread = 0; wolfSSL_ERR_clear_error(); - *curlcode = CURLE_OK; nread = wolfSSL_read(wssl->ssl, buf, buffsize); - if(nread <= 0) { + if(nread > 0) + *pnread = (size_t)nread; + else { int err = wolfSSL_get_error(wssl->ssl, nread); switch(err) { case WOLFSSL_ERROR_ZERO_RETURN: /* no more data */ CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> CLOSED", blen); - *curlcode = CURLE_OK; - return 0; + return CURLE_OK; case WOLFSSL_ERROR_NONE: case WOLFSSL_ERROR_WANT_READ: case WOLFSSL_ERROR_WANT_WRITE: if(!wssl->io_result && connssl->peer_closed) { CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> CLOSED", blen); - *curlcode = CURLE_OK; - return 0; + return CURLE_OK; } /* there is data pending, re-invoke wolfSSL_read() */ CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> AGAIN", blen); - *curlcode = CURLE_AGAIN; - return -1; + return CURLE_AGAIN; default: if(wssl->io_result == CURLE_AGAIN) { CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> AGAIN", blen); - *curlcode = CURLE_AGAIN; - return -1; + return CURLE_AGAIN; } else if(!wssl->io_result && connssl->peer_closed) { CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> CLOSED", blen); - *curlcode = CURLE_OK; - return 0; + failf(data, "Connection closed abruptly"); } else { char error_buffer[256]; @@ -2037,13 +2033,12 @@ static ssize_t wssl_recv(struct Curl_cfilter *cf, sizeof(error_buffer)), SOCKERRNO); } - *curlcode = CURLE_RECV_ERROR; - return -1; + return CURLE_RECV_ERROR; } } - CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> %d", blen, nread); - return nread; + CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> 0, %zu", blen, *pnread); + return CURLE_OK; } size_t Curl_wssl_version(char *buffer, size_t size) @@ -2095,6 +2090,18 @@ static bool wssl_data_pending(struct Curl_cfilter *cf, return FALSE; } +void Curl_wssl_report_handshake(struct Curl_easy *data, + struct wssl_ctx *wssl) +{ +#if (LIBWOLFSSL_VERSION_HEX >= 0x03009010) + infof(data, "SSL connection using %s / %s", + wolfSSL_get_version(wssl->ssl), + wolfSSL_get_cipher_name(wssl->ssl)); +#else + infof(data, "SSL connected"); +#endif +} + static CURLcode wssl_connect(struct Curl_cfilter *cf, struct Curl_easy *data, bool *done) @@ -2168,16 +2175,9 @@ static CURLcode wssl_connect(struct Curl_cfilter *cf, } #endif /* HAVE_ALPN */ -#if (LIBWOLFSSL_VERSION_HEX >= 0x03009010) - infof(data, "SSL connection using %s / %s", - wolfSSL_get_version(wssl->ssl), - wolfSSL_get_cipher_name(wssl->ssl)); -#else - infof(data, "SSL connected"); -#endif - connssl->connecting_state = ssl_connect_done; connssl->state = ssl_connection_complete; + Curl_wssl_report_handshake(data, wssl); #ifdef WOLFSSL_EARLY_DATA if(connssl->earlydata_state > ssl_earlydata_none) { @@ -2240,12 +2240,12 @@ static CURLcode wssl_sha256sum(const unsigned char *tmp, /* input */ } static void *wssl_get_internals(struct ssl_connect_data *connssl, - CURLINFO info UNUSED_PARAM) + CURLINFO info) { struct wssl_ctx *wssl = (struct wssl_ctx *)connssl->backend; - (void)info; DEBUGASSERT(wssl); - return wssl->ssl; + return info == CURLINFO_TLS_SESSION ? + (void *)wssl->ssl_ctx : (void *)wssl->ssl; } const struct Curl_ssl Curl_ssl_wolfssl = { @@ -2286,7 +2286,6 @@ const struct Curl_ssl Curl_ssl_wolfssl = { NULL, /* set_engine */ NULL, /* set_engine_default */ NULL, /* engines_list */ - NULL, /* false_start */ wssl_sha256sum, /* sha256sum */ wssl_recv, /* recv decrypted data */ wssl_send, /* send data to encrypt */ diff --git a/vendor/curl/lib/vtls/wolfssl.h b/vendor/curl/lib/vtls/wolfssl.h index 0ddbee9ed9e..7ff4cfb8817 100644 --- a/vendor/curl/lib/vtls/wolfssl.h +++ b/vendor/curl/lib/vtls/wolfssl.h @@ -44,7 +44,7 @@ struct wssl_ctx { struct WOLFSSL *ssl; CURLcode io_result; /* result of last BIO cfilter operation */ CURLcode hs_result; /* result of handshake */ - int io_send_blocked_len; /* length of last BIO write that EAGAINed */ + int io_send_blocked_len; /* length of last BIO write that EAGAIN-ed */ BIT(x509_store_setup); /* x509 store has been set up */ BIT(shutting_down); /* TLS is being shut down */ }; @@ -88,6 +88,8 @@ CURLcode Curl_wssl_verify_pinned(struct Curl_cfilter *cf, struct Curl_easy *data, struct wssl_ctx *wssl); +void Curl_wssl_report_handshake(struct Curl_easy *data, + struct wssl_ctx *wssl); #endif /* USE_WOLFSSL */ #endif /* HEADER_CURL_WOLFSSL_H */ diff --git a/vendor/curl/lib/vtls/x509asn1.c b/vendor/curl/lib/vtls/x509asn1.c index c6246cbd096..fe47e81a87d 100644 --- a/vendor/curl/lib/vtls/x509asn1.c +++ b/vendor/curl/lib/vtls/x509asn1.c @@ -24,23 +24,21 @@ #include "../curl_setup.h" -#if defined(USE_GNUTLS) || defined(USE_WOLFSSL) || \ - defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \ +#if defined(USE_GNUTLS) || defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || \ defined(USE_MBEDTLS) || defined(USE_RUSTLS) -#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \ - defined(USE_MBEDTLS) || defined(USE_WOLFSSL) || defined(USE_RUSTLS) +#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_MBEDTLS) || \ + defined(USE_WOLFSSL) || defined(USE_RUSTLS) #define WANT_PARSEX509 /* uses Curl_parseX509() */ #endif -#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \ - defined(USE_MBEDTLS) || defined(USE_RUSTLS) +#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_MBEDTLS) || \ + defined(USE_RUSTLS) #define WANT_EXTRACT_CERTINFO /* uses Curl_extract_certinfo() */ #endif #include #include "../urldata.h" -#include "../strcase.h" #include "../curl_ctype.h" #include "hostcheck.h" #include "vtls.h" @@ -263,7 +261,7 @@ static const struct Curl_OID *searchOID(const char *oid) { const struct Curl_OID *op; for(op = OIDtable; op->numoid; op++) - if(!strcmp(op->numoid, oid) || strcasecompare(op->textoid, oid)) + if(!strcmp(op->numoid, oid) || curl_strequal(op->textoid, oid)) return op; return NULL; @@ -591,7 +589,7 @@ CURLcode Curl_x509_GTime2str(struct dynbuf *store, * Return error code. */ static CURLcode UTime2str(struct dynbuf *store, - const char *beg, const char *end) + const char *beg, const char *end) { const char *tzp; size_t tzl; @@ -861,7 +859,7 @@ int Curl_parseX509(struct Curl_X509certificate *cert, if(!getASN1Element(&cert->subjectPublicKey, ccp, cert->subjectPublicKeyInfo.end)) return -1; - /* Get optional issuerUiqueID, subjectUniqueID and extensions. */ + /* Get optional issuerUniqueID, subjectUniqueID and extensions. */ cert->issuerUniqueID.tag = cert->subjectUniqueID.tag = 0; cert->extensions.tag = elem.tag = 0; cert->issuerUniqueID.header = cert->subjectUniqueID.header = NULL; @@ -990,7 +988,7 @@ static int do_pubkey(struct Curl_easy *data, int certnum, /* Generate all information records for the public key. */ - if(strcasecompare(algo, "ecPublicKey")) { + if(curl_strequal(algo, "ecPublicKey")) { /* * ECC public key is all the data, a value of type BIT STRING mapped to * OCTET STRING and should not be parsed as an ASN.1 value. @@ -1012,7 +1010,7 @@ static int do_pubkey(struct Curl_easy *data, int certnum, if(!getASN1Element(&pk, pubkey->beg + 1, pubkey->end)) return 1; - if(strcasecompare(algo, "rsaEncryption")) { + if(curl_strequal(algo, "rsaEncryption")) { const char *q; size_t len; @@ -1047,7 +1045,7 @@ static int do_pubkey(struct Curl_easy *data, int certnum, if(do_pubkey_field(data, certnum, "rsa(e)", &elem)) return 1; } - else if(strcasecompare(algo, "dsa")) { + else if(curl_strequal(algo, "dsa")) { p = getASN1Element(&elem, param->beg, param->end); if(p) { if(do_pubkey_field(data, certnum, "dsa(p)", &elem)) @@ -1065,7 +1063,7 @@ static int do_pubkey(struct Curl_easy *data, int certnum, } } } - else if(strcasecompare(algo, "dhpublicnumber")) { + else if(curl_strequal(algo, "dhpublicnumber")) { p = getASN1Element(&elem, param->beg, param->end); if(p) { if(do_pubkey_field(data, certnum, "dh(p)", &elem)) @@ -1277,5 +1275,5 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data, #endif /* WANT_EXTRACT_CERTINFO */ -#endif /* USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL or USE_SECTRANSP - or USE_MBEDTLS or USE_RUSTLS */ +#endif /* USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL or USE_MBEDTLS or + USE_RUSTLS */ diff --git a/vendor/curl/lib/vtls/x509asn1.h b/vendor/curl/lib/vtls/x509asn1.h index 1c9c35c3d4e..f9bd455b704 100644 --- a/vendor/curl/lib/vtls/x509asn1.h +++ b/vendor/curl/lib/vtls/x509asn1.h @@ -27,8 +27,7 @@ #include "../curl_setup.h" -#if defined(USE_GNUTLS) || defined(USE_WOLFSSL) || \ - defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \ +#if defined(USE_GNUTLS) || defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || \ defined(USE_MBEDTLS) || defined(USE_RUSTLS) #include "../cfilters.h" @@ -79,8 +78,8 @@ CURLcode Curl_verifyhost(struct Curl_cfilter *cf, struct Curl_easy *data, const char *beg, const char *end); #ifdef UNITTESTS -#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \ - defined(USE_MBEDTLS) || defined(USE_RUSTLS) +#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_MBEDTLS) || \ + defined(USE_RUSTLS) /* used by unit1656.c */ CURLcode Curl_x509_GTime2str(struct dynbuf *store, @@ -91,6 +90,6 @@ CURLcode Curl_x509_getASN1Element(struct Curl_asn1Element *elem, #endif #endif -#endif /* USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL or USE_SECTRANSP - or USE_MBEDTLS or USE_RUSTLS */ +#endif /* USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL or USE_MBEDTLS or + USE_RUSTLS */ #endif /* HEADER_CURL_X509ASN1_H */ diff --git a/vendor/curl/lib/ws.c b/vendor/curl/lib/ws.c index fc02025f1d2..82b8a2c2209 100644 --- a/vendor/curl/lib/ws.c +++ b/vendor/curl/lib/ws.c @@ -116,7 +116,7 @@ struct websocket { struct ws_encoder enc; /* decode of we frames */ struct bufq recvbuf; /* raw data from the server */ struct bufq sendbuf; /* raw data to be sent to the server */ - struct curl_ws_frame frame; /* the current WS FRAME received */ + struct curl_ws_frame recvframe; /* the current WS FRAME received */ size_t sendbuf_payload; /* number of payload bytes in sendbuf */ }; @@ -220,62 +220,66 @@ static int ws_frame_firstbyte2flags(struct Curl_easy *data, } } -static unsigned char ws_frame_flags2firstbyte(struct Curl_easy *data, - unsigned int flags, - bool contfragment, - CURLcode *err) +static CURLcode ws_frame_flags2firstbyte(struct Curl_easy *data, + unsigned int flags, + bool contfragment, + unsigned char *pfirstbyte) { + *pfirstbyte = 0; switch(flags & ~CURLWS_OFFSET) { case 0: if(contfragment) { infof(data, "[WS] no flags given; interpreting as continuation " "fragment for compatibility"); - return (WSBIT_OPCODE_CONT | WSBIT_FIN); + *pfirstbyte = (WSBIT_OPCODE_CONT | WSBIT_FIN); + return CURLE_OK; } failf(data, "[WS] no flags given"); - *err = CURLE_BAD_FUNCTION_ARGUMENT; - return 0xff; + return CURLE_BAD_FUNCTION_ARGUMENT; case CURLWS_CONT: if(contfragment) { infof(data, "[WS] setting CURLWS_CONT flag without message type is " "supported for compatibility but highly discouraged"); - return WSBIT_OPCODE_CONT; + *pfirstbyte = WSBIT_OPCODE_CONT; + return CURLE_OK; } failf(data, "[WS] No ongoing fragmented message to continue"); - *err = CURLE_BAD_FUNCTION_ARGUMENT; - return 0xff; + return CURLE_BAD_FUNCTION_ARGUMENT; case CURLWS_TEXT: - return contfragment ? (WSBIT_OPCODE_CONT | WSBIT_FIN) - : (WSBIT_OPCODE_TEXT | WSBIT_FIN); + *pfirstbyte = contfragment ? (WSBIT_OPCODE_CONT | WSBIT_FIN) + : (WSBIT_OPCODE_TEXT | WSBIT_FIN); + return CURLE_OK; case (CURLWS_TEXT | CURLWS_CONT): - return contfragment ? WSBIT_OPCODE_CONT : WSBIT_OPCODE_TEXT; + *pfirstbyte = contfragment ? WSBIT_OPCODE_CONT : WSBIT_OPCODE_TEXT; + return CURLE_OK; case CURLWS_BINARY: - return contfragment ? (WSBIT_OPCODE_CONT | WSBIT_FIN) - : (WSBIT_OPCODE_BIN | WSBIT_FIN); + *pfirstbyte = contfragment ? (WSBIT_OPCODE_CONT | WSBIT_FIN) + : (WSBIT_OPCODE_BIN | WSBIT_FIN); + return CURLE_OK; case (CURLWS_BINARY | CURLWS_CONT): - return contfragment ? WSBIT_OPCODE_CONT : WSBIT_OPCODE_BIN; + *pfirstbyte = contfragment ? WSBIT_OPCODE_CONT : WSBIT_OPCODE_BIN; + return CURLE_OK; case CURLWS_CLOSE: - return WSBIT_OPCODE_CLOSE | WSBIT_FIN; + *pfirstbyte = WSBIT_OPCODE_CLOSE | WSBIT_FIN; + return CURLE_OK; case (CURLWS_CLOSE | CURLWS_CONT): failf(data, "[WS] CLOSE frame must not be fragmented"); - *err = CURLE_BAD_FUNCTION_ARGUMENT; - return 0xff; + return CURLE_BAD_FUNCTION_ARGUMENT; case CURLWS_PING: - return WSBIT_OPCODE_PING | WSBIT_FIN; + *pfirstbyte = WSBIT_OPCODE_PING | WSBIT_FIN; + return CURLE_OK; case (CURLWS_PING | CURLWS_CONT): failf(data, "[WS] PING frame must not be fragmented"); - *err = CURLE_BAD_FUNCTION_ARGUMENT; - return 0xff; + return CURLE_BAD_FUNCTION_ARGUMENT; case CURLWS_PONG: - return WSBIT_OPCODE_PONG | WSBIT_FIN; + *pfirstbyte = WSBIT_OPCODE_PONG | WSBIT_FIN; + return CURLE_OK; case (CURLWS_PONG | CURLWS_CONT): failf(data, "[WS] PONG frame must not be fragmented"); - *err = CURLE_BAD_FUNCTION_ARGUMENT; - return 0xff; + return CURLE_BAD_FUNCTION_ARGUMENT; default: failf(data, "[WS] unknown flags: %x", flags); - *err = CURLE_BAD_FUNCTION_ARGUMENT; - return 0xff; + return CURLE_BAD_FUNCTION_ARGUMENT; } } @@ -308,7 +312,8 @@ static void ws_dec_info(struct ws_decoder *dec, struct Curl_easy *data, } } -static CURLcode ws_send_raw_blocking(CURL *data, struct websocket *ws, +static CURLcode ws_send_raw_blocking(struct Curl_easy *data, + struct websocket *ws, const char *buffer, size_t buflen); typedef ssize_t ws_write_payload(const unsigned char *buf, size_t buflen, @@ -517,7 +522,7 @@ static CURLcode ws_dec_pass(struct ws_decoder *dec, result = ws_dec_read_head(dec, data, inraw); if(result) { if(result != CURLE_AGAIN) { - infof(data, "[WS] decode error %d", (int)result); + failf(data, "[WS] decode frame error %d", (int)result); break; /* real error */ } /* incomplete ws frame head */ @@ -543,7 +548,7 @@ static CURLcode ws_dec_pass(struct ws_decoder *dec, ws_dec_info(dec, data, "passing"); if(result) return result; - /* paylod parsing done */ + /* payload parsing done */ dec->state = WS_DEC_INIT; break; default: @@ -561,11 +566,11 @@ static void update_meta(struct websocket *ws, { curl_off_t bytesleft = (payload_len - payload_offset - cur_len); - ws->frame.age = frame_age; - ws->frame.flags = frame_flags; - ws->frame.offset = payload_offset; - ws->frame.len = cur_len; - ws->frame.bytesleft = bytesleft; + ws->recvframe.age = frame_age; + ws->recvframe.flags = frame_flags; + ws->recvframe.offset = payload_offset; + ws->recvframe.len = cur_len; + ws->recvframe.bytesleft = bytesleft; } /* WebSockets decoding client writer */ @@ -586,7 +591,7 @@ static CURLcode ws_cw_init(struct Curl_easy *data, static void ws_cw_close(struct Curl_easy *data, struct Curl_cwriter *writer) { struct ws_cw_ctx *ctx = writer->ctx; - (void) data; + (void)data; Curl_bufq_free(&ctx->buf); } @@ -643,6 +648,7 @@ static CURLcode ws_cw_write(struct Curl_easy *data, struct websocket *ws; CURLcode result; + CURL_TRC_WRITE(data, "ws_cw_write(len=%zu, type=%d)", nbytes, type); if(!(type & CLIENTWRITE_BODY) || data->set.ws_raw_mode) return Curl_cwriter_write(data, writer->next, type, buf, nbytes); @@ -653,11 +659,11 @@ static CURLcode ws_cw_write(struct Curl_easy *data, } if(nbytes) { - ssize_t nwritten; - nwritten = Curl_bufq_write(&ctx->buf, (const unsigned char *)buf, - nbytes, &result); - if(nwritten < 0) { - infof(data, "[WS] error adding data to buffer %d", result); + size_t nwritten; + result = Curl_bufq_write(&ctx->buf, (const unsigned char *)buf, + nbytes, &nwritten); + if(result) { + infof(data, "WS: error adding data to buffer %d", result); return result; } } @@ -673,11 +679,10 @@ static CURLcode ws_cw_write(struct Curl_easy *data, if(result == CURLE_AGAIN) { /* insufficient amount of data, keep it for later. * we pretend to have written all since we have a copy */ - CURL_TRC_WS(data, "buffered incomplete frame head"); return CURLE_OK; } else if(result) { - infof(data, "[WS] decode error %d", (int)result); + failf(data, "[WS] decode payload error %d", (int)result); return result; } } @@ -747,37 +752,33 @@ static void ws_enc_init(struct ws_encoder *enc) +---------------------------------------------------------------+ */ -static ssize_t ws_enc_write_head(struct Curl_easy *data, +static CURLcode ws_enc_write_head(struct Curl_easy *data, struct ws_encoder *enc, unsigned int flags, curl_off_t payload_len, - struct bufq *out, - CURLcode *err) + struct bufq *out) { - unsigned char firstbyte = 0; + unsigned char firstb = 0; unsigned char head[14]; - size_t hlen; - ssize_t n; + CURLcode result; + size_t hlen, nwritten; if(payload_len < 0) { failf(data, "[WS] starting new frame with negative payload length %" FMT_OFF_T, payload_len); - *err = CURLE_SEND_ERROR; - return -1; + return CURLE_SEND_ERROR; } if(enc->payload_remain > 0) { /* trying to write a new frame before the previous one is finished */ failf(data, "[WS] starting new frame with %zd bytes from last one " "remaining to be sent", (ssize_t)enc->payload_remain); - *err = CURLE_SEND_ERROR; - return -1; + return CURLE_SEND_ERROR; } - firstbyte = ws_frame_flags2firstbyte(data, flags, enc->contfragment, err); - if(*err) { - return -1; - } + result = ws_frame_flags2firstbyte(data, flags, enc->contfragment, &firstb); + if(result) + return result; /* fragmentation only applies to data frames (text/binary); * control frames (close/ping/pong) do not affect the CONT status */ @@ -788,23 +789,20 @@ static ssize_t ws_enc_write_head(struct Curl_easy *data, if(flags & CURLWS_PING && payload_len > 125) { /* The maximum valid size of PING frames is 125 bytes. */ failf(data, "[WS] given PING frame is too big"); - *err = CURLE_TOO_LARGE; - return -1; + return CURLE_TOO_LARGE; } if(flags & CURLWS_PONG && payload_len > 125) { /* The maximum valid size of PONG frames is 125 bytes. */ failf(data, "[WS] given PONG frame is too big"); - *err = CURLE_TOO_LARGE; - return -1; + return CURLE_TOO_LARGE; } if(flags & CURLWS_CLOSE && payload_len > 125) { /* The maximum valid size of CLOSE frames is 125 bytes. */ failf(data, "[WS] given CLOSE frame is too big"); - *err = CURLE_TOO_LARGE; - return -1; + return CURLE_TOO_LARGE; } - head[0] = enc->firstbyte = firstbyte; + head[0] = enc->firstbyte = firstb; if(payload_len > 65535) { head[1] = 127 | WSBIT_MASK; head[2] = (unsigned char)((payload_len >> 56) & 0xff); @@ -837,30 +835,28 @@ static ssize_t ws_enc_write_head(struct Curl_easy *data, /* reset for payload to come */ enc->xori = 0; - n = Curl_bufq_write(out, head, hlen, err); - if(n < 0) - return -1; - if((size_t)n != hlen) { + result = Curl_bufq_write(out, head, hlen, &nwritten); + if(result) + return result; + if(nwritten != hlen) { /* We use a bufq with SOFT_LIMIT, writing should always succeed */ DEBUGASSERT(0); - *err = CURLE_SEND_ERROR; - return -1; + return CURLE_SEND_ERROR; } - return n; + return CURLE_OK; } -static ssize_t ws_enc_write_payload(struct ws_encoder *enc, - struct Curl_easy *data, - const unsigned char *buf, size_t buflen, - struct bufq *out, CURLcode *err) +static CURLcode ws_enc_write_payload(struct ws_encoder *enc, + struct Curl_easy *data, + const unsigned char *buf, size_t buflen, + struct bufq *out, size_t *pnwritten) { - ssize_t n; - size_t i, len; + CURLcode result; + size_t i, len, n; - if(Curl_bufq_is_full(out)) { - *err = CURLE_AGAIN; - return -1; - } + *pnwritten = 0; + if(Curl_bufq_is_full(out)) + return CURLE_AGAIN; /* not the most performant way to do this */ len = buflen; @@ -869,20 +865,138 @@ static ssize_t ws_enc_write_payload(struct ws_encoder *enc, for(i = 0; i < len; ++i) { unsigned char c = buf[i] ^ enc->mask[enc->xori]; - n = Curl_bufq_write(out, &c, 1, err); - if(n < 0) { - if((*err != CURLE_AGAIN) || !i) - return -1; + result = Curl_bufq_write(out, &c, 1, &n); + if(result) { + if((result != CURLE_AGAIN) || !i) + return result; break; } enc->xori++; enc->xori &= 3; } + *pnwritten = i; enc->payload_remain -= (curl_off_t)i; ws_enc_info(enc, data, "buffered"); - return (ssize_t)i; + return CURLE_OK; +} + + + +struct cr_ws_ctx { + struct Curl_creader super; + BIT(read_eos); /* we read an EOS from the next reader */ + BIT(eos); /* we have returned an EOS */ +}; + +static CURLcode cr_ws_init(struct Curl_easy *data, struct Curl_creader *reader) +{ + (void)data; + (void)reader; + return CURLE_OK; } +static void cr_ws_close(struct Curl_easy *data, struct Curl_creader *reader) +{ + (void)data; + (void)reader; +} + +static CURLcode cr_ws_read(struct Curl_easy *data, + struct Curl_creader *reader, + char *buf, size_t blen, + size_t *pnread, bool *peos) +{ + struct cr_ws_ctx *ctx = reader->ctx; + CURLcode result = CURLE_OK; + size_t nread, n; + struct websocket *ws; + bool eos; + + *pnread = 0; + if(ctx->eos) { + *peos = TRUE; + return CURLE_OK; + } + + ws = Curl_conn_meta_get(data->conn, CURL_META_PROTO_WS_CONN); + if(!ws) { + failf(data, "[WS] not a websocket transfer"); + return CURLE_FAILED_INIT; + } + + if(Curl_bufq_is_empty(&ws->sendbuf)) { + if(ctx->read_eos) { + ctx->eos = TRUE; + *peos = TRUE; + return CURLE_OK; + } + + if(ws->enc.payload_remain) { + CURL_TRC_WS(data, "current frame, %" FMT_OFF_T " remaining", + ws->enc.payload_remain); + if(ws->enc.payload_remain < (curl_off_t)blen) + blen = (size_t)ws->enc.payload_remain; + } + + result = Curl_creader_read(data, reader->next, buf, blen, &nread, &eos); + if(result) + return result; + ctx->read_eos = eos; + + if(!nread) { + /* nothing to convert, return this right away */ + if(ctx->read_eos) + ctx->eos = TRUE; + *pnread = nread; + *peos = ctx->eos; + goto out; + } + + if(!ws->enc.payload_remain) { + /* encode the data as a new BINARY frame */ + result = ws_enc_write_head(data, &ws->enc, CURLWS_BINARY, nread, + &ws->sendbuf); + if(result) + goto out; + } + + result = ws_enc_write_payload(&ws->enc, data, (unsigned char *)buf, + nread, &ws->sendbuf, &n); + if(result) + goto out; + CURL_TRC_READ(data, "cr_ws_read, added %zu payload, len=%zu", nread, n); + } + + DEBUGASSERT(!Curl_bufq_is_empty(&ws->sendbuf)); + *peos = FALSE; + result = Curl_bufq_cread(&ws->sendbuf, buf, blen, pnread); + if(!result && ctx->read_eos && Curl_bufq_is_empty(&ws->sendbuf)) { + /* no more data, read all, done. */ + ctx->eos = TRUE; + *peos = TRUE; + } + +out: + CURL_TRC_READ(data, "cr_ws_read(len=%zu) -> %d, nread=%zu, eos=%d", + blen, result, *pnread, *peos); + return result; +} + +static const struct Curl_crtype ws_cr_encode = { + "ws-encode", + cr_ws_init, + cr_ws_read, + cr_ws_close, + Curl_creader_def_needs_rewind, + Curl_creader_def_total_length, + Curl_creader_def_resume_from, + Curl_creader_def_rewind, + Curl_creader_def_unpause, + Curl_creader_def_is_paused, + Curl_creader_def_done, + sizeof(struct cr_ws_ctx) +}; + struct wsfield { const char *name; @@ -969,7 +1083,8 @@ CURLcode Curl_ws_accept(struct Curl_easy *data, { struct SingleRequest *k = &data->req; struct websocket *ws; - struct Curl_cwriter *ws_dec_writer; + struct Curl_cwriter *ws_dec_writer = NULL; + struct Curl_creader *ws_enc_reader = NULL; CURLcode result; DEBUGASSERT(data->conn); @@ -1045,33 +1160,69 @@ CURLcode Curl_ws_accept(struct Curl_easy *data, result = Curl_cwriter_create(&ws_dec_writer, data, &ws_cw_decode, CURL_CW_CONTENT_DECODE); if(result) - return result; - + goto out; result = Curl_cwriter_add(data, ws_dec_writer); - if(result) { - Curl_cwriter_free(data, ws_dec_writer); - return result; - } + if(result) + goto out; + ws_dec_writer = NULL; /* owned by transfer now */ if(data->set.connect_only) { - ssize_t nwritten; + size_t nwritten; /* In CONNECT_ONLY setup, the payloads from `mem` need to be received * when using `curl_ws_recv` later on after this transfer is already * marked as DONE. */ - nwritten = Curl_bufq_write(&ws->recvbuf, (const unsigned char *)mem, - nread, &result); - if(nwritten < 0) - return result; - CURL_TRC_WS(data, "%zu bytes payload", nread); + result = Curl_bufq_write(&ws->recvbuf, (const unsigned char *)mem, + nread, &nwritten); + if(result) + goto out; + DEBUGASSERT(nread == nwritten); + k->keepon &= ~KEEP_RECV; /* read no more content */ } else { /* !connect_only */ + if(data->set.method == HTTPREQ_PUT) { + CURL_TRC_WS(data, "UPLOAD set, add ws-encode reader"); + result = Curl_creader_set_fread(data, -1); + if(result) + goto out; + + if(!data->set.ws_raw_mode) { + /* Add our client readerr encoding WS BINARY frames */ + result = Curl_creader_create(&ws_enc_reader, data, &ws_cr_encode, + CURL_CR_CONTENT_ENCODE); + if(result) + goto out; + result = Curl_creader_add(data, ws_enc_reader); + if(result) + goto out; + ws_enc_reader = NULL; /* owned by transfer now */ + } + + /* start over with sending */ + data->req.eos_read = FALSE; + k->keepon |= KEEP_SEND; + } + /* And pass any additional data to the writers */ if(nread) { result = Curl_client_write(data, CLIENTWRITE_BODY, mem, nread); + if(result) + goto out; } } + k->upgr101 = UPGR101_RECEIVED; + k->header = FALSE; /* we will not get more responses */ +out: + if(ws_dec_writer) + Curl_cwriter_free(data, ws_dec_writer); + if(ws_enc_reader) + Curl_creader_free(data, ws_enc_reader); + if(result) + CURL_TRC_WS(data, "Curl_ws_accept() failed -> %d", result); + else + CURL_TRC_WS(data, "websocket established, %s mode", + data->set.connect_only ? "connect-only" : "callback"); return result; } @@ -1137,31 +1288,29 @@ static ssize_t ws_client_collect(const unsigned char *buf, size_t buflen, return nwritten; } -static ssize_t nw_in_recv(void *reader_ctx, - unsigned char *buf, size_t buflen, - CURLcode *err) +static CURLcode nw_in_recv(void *reader_ctx, + unsigned char *buf, size_t buflen, + size_t *pnread) { struct Curl_easy *data = reader_ctx; - size_t nread; - - *err = curl_easy_recv(data, buf, buflen, &nread); - if(*err) - return -1; - return (ssize_t)nread; + return curl_easy_recv(data, buf, buflen, pnread); } -CURL_EXTERN CURLcode curl_ws_recv(CURL *d, void *buffer, - size_t buflen, size_t *nread, - const struct curl_ws_frame **metap) +CURLcode curl_ws_recv(CURL *d, void *buffer, + size_t buflen, size_t *nread, + const struct curl_ws_frame **metap) { struct Curl_easy *data = d; - struct connectdata *conn = data->conn; + struct connectdata *conn; struct websocket *ws; struct ws_collect ctx; *nread = 0; *metap = NULL; + if(!GOOD_EASY_HANDLE(data)) + return CURLE_BAD_FUNCTION_ARGUMENT; + conn = data->conn; if(!conn) { /* Unhappy hack with lifetimes of transfers and connection */ if(!data->set.connect_only) { @@ -1192,10 +1341,10 @@ CURL_EXTERN CURLcode curl_ws_recv(CURL *d, void *buffer, /* receive more when our buffer is empty */ if(Curl_bufq_is_empty(&ws->recvbuf)) { - ssize_t n = Curl_bufq_slurp(&ws->recvbuf, nw_in_recv, data, &result); - if(n < 0) { + size_t n; + result = Curl_bufq_slurp(&ws->recvbuf, nw_in_recv, data, &n); + if(result) return result; - } else if(n == 0) { /* connection closed */ infof(data, "[WS] connection expectedly closed?"); @@ -1228,11 +1377,12 @@ CURL_EXTERN CURLcode curl_ws_recv(CURL *d, void *buffer, /* update frame information to be passed back */ update_meta(ws, ctx.frame_age, ctx.frame_flags, ctx.payload_offset, ctx.payload_len, ctx.bufidx); - *metap = &ws->frame; - *nread = ws->frame.len; + *metap = &ws->recvframe; + *nread = ws->recvframe.len; CURL_TRC_WS(data, "curl_ws_recv(len=%zu) -> %zu bytes (frame at %" FMT_OFF_T ", %" FMT_OFF_T " left)", - buflen, *nread, ws->frame.offset, ws->frame.bytesleft); + buflen, *nread, ws->recvframe.offset, + ws->recvframe.bytesleft); return CURLE_OK; } @@ -1294,12 +1444,12 @@ static CURLcode ws_flush(struct Curl_easy *data, struct websocket *ws, return CURLE_OK; } -static CURLcode ws_send_raw_blocking(CURL *d, struct websocket *ws, +static CURLcode ws_send_raw_blocking(struct Curl_easy *data, + struct websocket *ws, const char *buffer, size_t buflen) { CURLcode result = CURLE_OK; size_t nwritten; - struct Curl_easy *data = d; (void)ws; while(buflen) { @@ -1373,21 +1523,32 @@ static CURLcode ws_send_raw(struct Curl_easy *data, const void *buffer, return result; } -CURL_EXTERN CURLcode curl_ws_send(CURL *d, const void *buffer_arg, - size_t buflen, size_t *sent, - curl_off_t fragsize, - unsigned int flags) +CURLcode curl_ws_send(CURL *d, const void *buffer_arg, + size_t buflen, size_t *sent, + curl_off_t fragsize, + unsigned int flags) { struct websocket *ws; const unsigned char *buffer = buffer_arg; - ssize_t n; + size_t n; CURLcode result = CURLE_OK; struct Curl_easy *data = d; + if(!GOOD_EASY_HANDLE(data)) + return CURLE_BAD_FUNCTION_ARGUMENT; CURL_TRC_WS(data, "curl_ws_send(len=%zu, fragsize=%" FMT_OFF_T ", flags=%x), raw=%d", buflen, fragsize, flags, data->set.ws_raw_mode); - *sent = 0; + + if(sent) + *sent = 0; + + if(!buffer && buflen) { + failf(data, "[WS] buffer is NULL when buflen is not"); + result = CURLE_BAD_FUNCTION_ARGUMENT; + goto out; + } + if(!data->conn && data->set.connect_only) { result = Curl_connect_only_attach(data); if(result) @@ -1412,6 +1573,14 @@ CURL_EXTERN CURLcode curl_ws_send(CURL *d, const void *buffer_arg, if(result) goto out; + if(!buffer) { + failf(data, "[WS] buffer is NULL in raw mode"); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + if(!sent) { + failf(data, "[WS] sent is NULL in raw mode"); + return CURLE_BAD_FUNCTION_ARGUMENT; + } if(fragsize || flags) { failf(data, "[WS] fragsize and flags must be zero in raw mode"); return CURLE_BAD_FUNCTION_ARGUMENT; @@ -1446,16 +1615,18 @@ CURL_EXTERN CURLcode curl_ws_send(CURL *d, const void *buffer_arg, } else { /* starting a new frame, we want a clean sendbuf */ - curl_off_t payload_len = (flags & CURLWS_OFFSET) ? - fragsize : (curl_off_t)buflen; result = ws_flush(data, ws, Curl_is_in_callback(data)); if(result) goto out; - n = ws_enc_write_head(data, &ws->enc, flags, payload_len, - &ws->sendbuf, &result); - if(n < 0) + result = ws_enc_write_head(data, &ws->enc, flags, + (flags & CURLWS_OFFSET) ? + fragsize : (curl_off_t)buflen, + &ws->sendbuf); + if(result) { + CURL_TRC_WS(data, "curl_ws_send(), error writing frame head %d", result); goto out; + } } /* While there is either sendbuf to flush OR more payload to encode... */ @@ -1463,11 +1634,11 @@ CURL_EXTERN CURLcode curl_ws_send(CURL *d, const void *buffer_arg, /* Try to add more payload to sendbuf */ if(buflen > ws->sendbuf_payload) { size_t prev_len = Curl_bufq_len(&ws->sendbuf); - n = ws_enc_write_payload(&ws->enc, data, - buffer + ws->sendbuf_payload, - buflen - ws->sendbuf_payload, - &ws->sendbuf, &result); - if(n < 0 && (result != CURLE_AGAIN)) + result = ws_enc_write_payload(&ws->enc, data, + buffer + ws->sendbuf_payload, + buflen - ws->sendbuf_payload, + &ws->sendbuf, &n); + if(result && (result != CURLE_AGAIN)) goto out; ws->sendbuf_payload += Curl_bufq_len(&ws->sendbuf) - prev_len; if(!ws->sendbuf_payload) { @@ -1479,7 +1650,8 @@ CURL_EXTERN CURLcode curl_ws_send(CURL *d, const void *buffer_arg, /* flush, blocking when in callback */ result = ws_flush(data, ws, Curl_is_in_callback(data)); if(!result && ws->sendbuf_payload > 0) { - *sent += ws->sendbuf_payload; + if(sent) + *sent += ws->sendbuf_payload; buffer += ws->sendbuf_payload; buflen -= ws->sendbuf_payload; ws->sendbuf_payload = 0; @@ -1489,7 +1661,8 @@ CURL_EXTERN CURLcode curl_ws_send(CURL *d, const void *buffer_arg, /* blocked, part of payload bytes remain, report length * that we managed to send. */ size_t flushed = (ws->sendbuf_payload - Curl_bufq_len(&ws->sendbuf)); - *sent += flushed; + if(sent) + *sent += flushed; ws->sendbuf_payload -= flushed; result = CURLE_OK; goto out; @@ -1499,7 +1672,7 @@ CURL_EXTERN CURLcode curl_ws_send(CURL *d, const void *buffer_arg, * OK on 0-length send (caller counts only payload) and EAGAIN */ CURL_TRC_WS(data, "EAGAIN flushing sendbuf, payload_encoded: %zu/%zu", ws->sendbuf_payload, buflen); - DEBUGASSERT(*sent == 0); + DEBUGASSERT(!sent || *sent == 0); result = CURLE_AGAIN; goto out; } @@ -1511,7 +1684,8 @@ CURL_EXTERN CURLcode curl_ws_send(CURL *d, const void *buffer_arg, out: CURL_TRC_WS(data, "curl_ws_send(len=%zu, fragsize=%" FMT_OFF_T ", flags=%x, raw=%d) -> %d, %zu", - buflen, fragsize, flags, data->set.ws_raw_mode, result, *sent); + buflen, fragsize, flags, data->set.ws_raw_mode, result, + sent ? *sent : 0); return result; } @@ -1527,7 +1701,7 @@ static CURLcode ws_setup_conn(struct Curl_easy *data, } -CURL_EXTERN const struct curl_ws_frame *curl_ws_meta(CURL *d) +const struct curl_ws_frame *curl_ws_meta(CURL *d) { /* we only return something for websocket, called from within the callback when not using raw mode */ @@ -1537,12 +1711,63 @@ CURL_EXTERN const struct curl_ws_frame *curl_ws_meta(CURL *d) struct websocket *ws; ws = Curl_conn_meta_get(data->conn, CURL_META_PROTO_WS_CONN); if(ws) - return &ws->frame; + return &ws->recvframe; } return NULL; } +CURL_EXTERN CURLcode curl_ws_start_frame(CURL *d, + unsigned int flags, + curl_off_t frame_len) +{ + struct websocket *ws; + CURLcode result = CURLE_OK; + struct Curl_easy *data = d; + + if(!GOOD_EASY_HANDLE(data)) + return CURLE_BAD_FUNCTION_ARGUMENT; + if(data->set.ws_raw_mode) { + failf(data, "cannot curl_ws_start_frame() with CURLWS_RAW_MODE enabled"); + return CURLE_FAILED_INIT; + } + + CURL_TRC_WS(data, "curl_start_frame(flags=%x, frame_len=%" FMT_OFF_T, + flags, frame_len); + + if(!data->conn) { + failf(data, "[WS] No associated connection"); + result = CURLE_SEND_ERROR; + goto out; + } + ws = Curl_conn_meta_get(data->conn, CURL_META_PROTO_WS_CONN); + if(!ws) { + failf(data, "[WS] Not a websocket transfer"); + result = CURLE_SEND_ERROR; + goto out; + } + + if(data->set.ws_raw_mode) { + failf(data, "[WS] cannot start frame in raw mode"); + result = CURLE_SEND_ERROR; + goto out; + } + + if(ws->enc.payload_remain) { + failf(data, "[WS] previous frame not finished"); + result = CURLE_SEND_ERROR; + goto out; + } + + result = ws_enc_write_head(data, &ws->enc, flags, frame_len, &ws->sendbuf); + if(result) + CURL_TRC_WS(data, "curl_start_frame(), error adding frame head %d", + result); + +out: + return result; +} + const struct Curl_handler Curl_handler_ws = { "WS", /* scheme */ ws_setup_conn, /* setup_connection */ @@ -1552,10 +1777,10 @@ const struct Curl_handler Curl_handler_ws = { Curl_http_connect, /* connect_it */ ZERO_NULL, /* connecting */ ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - Curl_http_getsock_do, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* proto_pollset */ + Curl_http_do_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ ZERO_NULL, /* disconnect */ Curl_http_write_resp, /* write_resp */ Curl_http_write_resp_hd, /* write_resp_hd */ @@ -1579,10 +1804,10 @@ const struct Curl_handler Curl_handler_wss = { Curl_http_connect, /* connect_it */ NULL, /* connecting */ ZERO_NULL, /* doing */ - NULL, /* proto_getsock */ - Curl_http_getsock_do, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ + NULL, /* proto_pollset */ + Curl_http_do_pollset, /* doing_pollset */ + ZERO_NULL, /* domore_pollset */ + ZERO_NULL, /* perform_pollset */ ZERO_NULL, /* disconnect */ Curl_http_write_resp, /* write_resp */ Curl_http_write_resp_hd, /* write_resp_hd */ @@ -1600,9 +1825,9 @@ const struct Curl_handler Curl_handler_wss = { #else -CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen, - size_t *nread, - const struct curl_ws_frame **metap) +CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen, + size_t *nread, + const struct curl_ws_frame **metap) { (void)curl; (void)buffer; @@ -1612,10 +1837,10 @@ CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen, return CURLE_NOT_BUILT_IN; } -CURL_EXTERN CURLcode curl_ws_send(CURL *curl, const void *buffer, - size_t buflen, size_t *sent, - curl_off_t fragsize, - unsigned int flags) +CURLcode curl_ws_send(CURL *curl, const void *buffer, + size_t buflen, size_t *sent, + curl_off_t fragsize, + unsigned int flags) { (void)curl; (void)buffer; @@ -1626,9 +1851,20 @@ CURL_EXTERN CURLcode curl_ws_send(CURL *curl, const void *buffer, return CURLE_NOT_BUILT_IN; } -CURL_EXTERN const struct curl_ws_frame *curl_ws_meta(CURL *data) +const struct curl_ws_frame *curl_ws_meta(CURL *data) { (void)data; return NULL; } + +CURL_EXTERN CURLcode curl_ws_start_frame(CURL *curl, + unsigned int flags, + curl_off_t frame_len) +{ + (void)curl; + (void)flags; + (void)frame_len; + return CURLE_NOT_BUILT_IN; +} + #endif /* !CURL_DISABLE_WEBSOCKETS */ diff --git a/vendor/curl/scripts/schemetable.c b/vendor/curl/scripts/schemetable.c index bebf29d9fe5..7da4613212c 100644 --- a/vendor/curl/scripts/schemetable.c +++ b/vendor/curl/scripts/schemetable.c @@ -61,7 +61,7 @@ static const struct detail scheme[] = { {"rtmpts", "#ifdef USE_LIBRTMP" }, {"rtsp", "#ifndef CURL_DISABLE_RTSP" }, {"scp", "#if defined(USE_SSH) && !defined(USE_WOLFSSH)" }, - {"sftp", "#if defined(USE_SSH)" }, + {"sftp", "#ifdef USE_SSH" }, {"smb", "#if !defined(CURL_DISABLE_SMB) && \\\n" " defined(USE_CURL_NTLM_CORE) && (SIZEOF_CURL_OFF_T > 4)" }, {"smbs", "#if defined(USE_SSL) && !defined(CURL_DISABLE_SMB) && \\\n" diff --git a/vendor/curl/src/.gitignore b/vendor/curl/src/.gitignore new file mode 100644 index 00000000000..67410d9042c --- /dev/null +++ b/vendor/curl/src/.gitignore @@ -0,0 +1,10 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +curl +tool_ca_embed.c +tool_hugehelp.c +curltool_unity.c +libcurltool_unity.c +curlinfo diff --git a/vendor/curl/src/config2setopts.c b/vendor/curl/src/config2setopts.c index d7a4187a8bb..ba31de9abfd 100644 --- a/vendor/curl/src/config2setopts.c +++ b/vendor/curl/src/config2setopts.c @@ -87,8 +87,7 @@ static int sockopt_callback(void *clientp, curl_socket_t curlfd, } if(result < 0) { int error = errno; - warnf(config->global, - "Setting type of service to %d failed with errno %d: %s;\n", + warnf("Setting type of service to %d failed with errno %d: %s", tos, error, strerror(error)); } } @@ -97,9 +96,9 @@ static int sockopt_callback(void *clientp, curl_socket_t curlfd, if(config->vlan_priority > 0) { int priority = (int)config->vlan_priority; if(setsockopt(curlfd, SOL_SOCKET, SO_PRIORITY, - (void *)&priority, sizeof(priority)) != 0) { + (void *)&priority, sizeof(priority)) != 0) { int error = errno; - warnf(config->global, "VLAN priority %d failed with errno %d: %s;\n", + warnf("VLAN priority %d failed with errno %d: %s", priority, error, strerror(error)); } } @@ -171,9 +170,7 @@ static CURLcode url_proto_and_rewrite(char **url, return result; } -static CURLcode ssh_setopts(struct GlobalConfig *global, - struct OperationConfig *config, - CURL *curl) +static CURLcode ssh_setopts(struct OperationConfig *config, CURL *curl) { CURLcode result; @@ -214,11 +211,11 @@ static CURLcode ssh_setopts(struct GlobalConfig *global, global->knownhosts = known; } else if(!config->hostpubmd5 && !config->hostpubsha256) { - errorf(global, "Couldn't find a known_hosts file"); + errorf("Couldn't find a known_hosts file"); return CURLE_FAILED_INIT; } else - warnf(global, "Couldn't find a known_hosts file"); + warnf("Couldn't find a known_hosts file"); } return CURLE_OK; /* ignore if SHA256 did not work */ } @@ -230,10 +227,55 @@ extern const unsigned char curl_ca_embed[]; #endif #endif +static long tlsversion(unsigned char mintls, + unsigned char maxtls) +{ + long tlsver = 0; + if(!mintls) { /* minimum is at default */ + /* minimum is set to default, which we want to be 1.2 */ + if(maxtls && (maxtls < 3)) + /* max is set lower than 1.2 and minimum is default, change minimum to + the same as max */ + mintls = maxtls; + } + switch(mintls) { + case 1: + tlsver = CURL_SSLVERSION_TLSv1_0; + break; + case 2: + tlsver = CURL_SSLVERSION_TLSv1_1; + break; + case 0: /* let default minimum be 1.2 */ + case 3: + tlsver = CURL_SSLVERSION_TLSv1_2; + break; + case 4: + default: /* just in case */ + tlsver = CURL_SSLVERSION_TLSv1_3; + break; + } + switch(maxtls) { + case 0: /* not set, leave it */ + break; + case 1: + tlsver |= CURL_SSLVERSION_MAX_TLSv1_0; + break; + case 2: + tlsver |= CURL_SSLVERSION_MAX_TLSv1_1; + break; + case 3: + tlsver |= CURL_SSLVERSION_MAX_TLSv1_2; + break; + case 4: + default: /* just in case */ + tlsver |= CURL_SSLVERSION_MAX_TLSv1_3; + break; + } + return tlsver; +} + /* only called if libcurl supports TLS */ -static CURLcode ssl_setopts(struct GlobalConfig *global, - struct OperationConfig *config, - CURL *curl) +static CURLcode ssl_setopts(struct OperationConfig *config, CURL *curl) { CURLcode result = CURLE_OK; @@ -256,7 +298,7 @@ static CURLcode ssl_setopts(struct GlobalConfig *global, if((result == CURLE_NOT_BUILT_IN) || (result == CURLE_UNKNOWN_OPTION)) { if(config->proxy_capath) { - warnf(global, "ignoring %s, not supported by libcurl with %s", + warnf("ignoring %s, not supported by libcurl with %s", config->proxy_capath ? "--proxy-capath" : "--capath", ssl_backend()); } @@ -271,12 +313,10 @@ static CURLcode ssl_setopts(struct GlobalConfig *global, blob.data = CURL_UNCONST(curl_ca_embed); blob.len = strlen((const char *)curl_ca_embed); blob.flags = CURL_BLOB_NOCOPY; - notef(config->global, - "Using embedded CA bundle (%zu bytes)", - blob.len); + notef("Using embedded CA bundle (%zu bytes)", blob.len); result = curl_easy_setopt(curl, CURLOPT_CAINFO_BLOB, &blob); if(result == CURLE_NOT_BUILT_IN) { - warnf(global, "ignoring %s, not supported by libcurl with %s", + warnf("ignoring %s, not supported by libcurl with %s", "embedded CA bundle", ssl_backend()); } } @@ -285,12 +325,10 @@ static CURLcode ssl_setopts(struct GlobalConfig *global, blob.data = CURL_UNCONST(curl_ca_embed); blob.len = strlen((const char *)curl_ca_embed); blob.flags = CURL_BLOB_NOCOPY; - notef(config->global, - "Using embedded CA bundle, for proxies (%zu bytes)", - blob.len); + notef("Using embedded CA bundle, for proxies (%zu bytes)", blob.len); result = curl_easy_setopt(curl, CURLOPT_PROXY_CAINFO_BLOB, &blob); if(result == CURLE_NOT_BUILT_IN) { - warnf(global, "ignoring %s, not supported by libcurl with %s", + warnf("ignoring %s, not supported by libcurl with %s", "embedded CA bundle", ssl_backend()); } } @@ -307,14 +345,14 @@ static CURLcode ssl_setopts(struct GlobalConfig *global, result = my_setopt_str(curl, CURLOPT_PINNEDPUBLICKEY, config->pinnedpubkey); if(result == CURLE_NOT_BUILT_IN) - warnf(global, "ignoring %s, not supported by libcurl with %s", + warnf("ignoring %s, not supported by libcurl with %s", "--pinnedpubkey", ssl_backend()); } if(config->proxy_pinnedpubkey) { result = my_setopt_str(curl, CURLOPT_PROXY_PINNEDPUBLICKEY, config->proxy_pinnedpubkey); if(result == CURLE_NOT_BUILT_IN) - warnf(global, "ignoring %s, not supported by libcurl with %s", + warnf("ignoring %s, not supported by libcurl with %s", "--proxy-pinnedpubkey", ssl_backend()); } @@ -361,11 +399,9 @@ static CURLcode ssl_setopts(struct GlobalConfig *global, if(config->doh_verifystatus) my_setopt_long(curl, CURLOPT_DOH_SSL_VERIFYSTATUS, 1); - if(config->falsestart) - my_setopt_long(curl, CURLOPT_SSL_FALSESTART, 1); - my_setopt_SSLVERSION(curl, CURLOPT_SSLVERSION, - config->ssl_version | config->ssl_version_max); + tlsversion(config->ssl_version, + config->ssl_version_max)); if(config->proxy) my_setopt_SSLVERSION(curl, CURLOPT_PROXY_SSLVERSION, config->proxy_ssl_version); @@ -398,28 +434,28 @@ static CURLcode ssl_setopts(struct GlobalConfig *global, result = my_setopt_str(curl, CURLOPT_SSL_CIPHER_LIST, config->cipher_list); if(result == CURLE_NOT_BUILT_IN) - warnf(global, "ignoring %s, not supported by libcurl with %s", + warnf("ignoring %s, not supported by libcurl with %s", "--ciphers", ssl_backend()); } if(config->proxy_cipher_list) { result = my_setopt_str(curl, CURLOPT_PROXY_SSL_CIPHER_LIST, config->proxy_cipher_list); if(result == CURLE_NOT_BUILT_IN) - warnf(global, "ignoring %s, not supported by libcurl with %s", + warnf("ignoring %s, not supported by libcurl with %s", "--proxy-ciphers", ssl_backend()); } if(config->cipher13_list) { result = my_setopt_str(curl, CURLOPT_TLS13_CIPHERS, config->cipher13_list); if(result == CURLE_NOT_BUILT_IN) - warnf(global, "ignoring %s, not supported by libcurl with %s", + warnf("ignoring %s, not supported by libcurl with %s", "--tls13-ciphers", ssl_backend()); } if(config->proxy_cipher13_list) { result = my_setopt_str(curl, CURLOPT_PROXY_TLS13_CIPHERS, config->proxy_cipher13_list); if(result == CURLE_NOT_BUILT_IN) - warnf(global, "ignoring %s, not supported by libcurl with %s", + warnf("ignoring %s, not supported by libcurl with %s", "--proxy-tls13-ciphers", ssl_backend()); } @@ -464,15 +500,12 @@ static CURLcode ssl_setopts(struct GlobalConfig *global, } /* only called for HTTP transfers */ -static CURLcode http_setopts(struct GlobalConfig *global, - struct OperationConfig *config, +static CURLcode http_setopts(struct OperationConfig *config, CURL *curl) { long postRedir = 0; - (void) global; /* for builds without --libcurl */ - my_setopt_long(curl, CURLOPT_FOLLOWLOCATION, - config->followlocation); + my_setopt_long(curl, CURLOPT_FOLLOWLOCATION, config->followlocation); my_setopt_long(curl, CURLOPT_UNRESTRICTED_AUTH, config->unrestricted_auth); my_setopt_str(curl, CURLOPT_AWS_SIGV4, config->aws_sigv4); @@ -524,9 +557,7 @@ static CURLcode http_setopts(struct GlobalConfig *global, return CURLE_OK; } -static CURLcode cookie_setopts(struct GlobalConfig *global, - struct OperationConfig *config, - CURL *curl) +static CURLcode cookie_setopts(struct OperationConfig *config, CURL *curl) { CURLcode result = CURLE_OK; if(config->cookies) { @@ -538,13 +569,12 @@ static CURLcode cookie_setopts(struct GlobalConfig *global, curlx_dyn_init(&cookies, MAX_COOKIE_LINE); for(cl = config->cookies; cl; cl = cl->next) { if(cl == config->cookies) - result = curlx_dyn_addf(&cookies, "%s", cl->data); + result = curlx_dyn_add(&cookies, cl->data); else result = curlx_dyn_addf(&cookies, ";%s", cl->data); if(result) { - warnf(global, - "skipped provided cookie, the cookie header " + warnf("skipped provided cookie, the cookie header " "would go over %u bytes", MAX_COOKIE_LINE); return result; } @@ -571,11 +601,9 @@ static CURLcode cookie_setopts(struct GlobalConfig *global, return result; } -static CURLcode tcp_setopts(struct GlobalConfig *global, - struct OperationConfig *config, +static CURLcode tcp_setopts(struct OperationConfig *config, CURL *curl) { - (void) global; /* for builds without --libcurl */ if(!config->tcp_nodelay) my_setopt_long(curl, CURLOPT_TCP_NODELAY, 0); @@ -600,11 +628,8 @@ static CURLcode tcp_setopts(struct GlobalConfig *global, return CURLE_OK; } -static CURLcode ftp_setopts(struct GlobalConfig *global, - struct OperationConfig *config, - CURL *curl) +static CURLcode ftp_setopts(struct OperationConfig *config, CURL *curl) { - (void) global; /* for builds without --libcurl */ my_setopt_str(curl, CURLOPT_FTPPORT, config->ftpport); /* new in libcurl 7.9.2: */ @@ -619,7 +644,7 @@ static CURLcode ftp_setopts(struct GlobalConfig *global, /* new in curl 7.16.1 */ if(config->ftp_ssl_ccc) - my_setopt_enum(curl, CURLOPT_FTP_SSL_CCC, (long)config->ftp_ssl_ccc_mode); + my_setopt_enum(curl, CURLOPT_FTP_SSL_CCC, config->ftp_ssl_ccc_mode); my_setopt_str(curl, CURLOPT_FTP_ACCOUNT, config->ftp_account); @@ -640,9 +665,7 @@ static CURLcode ftp_setopts(struct GlobalConfig *global, return CURLE_OK; } -static void gen_trace_setopts(struct GlobalConfig *global, - struct OperationConfig *config, - CURL *curl) +static void gen_trace_setopts(struct OperationConfig *config, CURL *curl) { if(global->tracetype != TRACE_NONE) { my_setopt(curl, CURLOPT_DEBUGFUNCTION, tool_debug_cb); @@ -651,13 +674,12 @@ static void gen_trace_setopts(struct GlobalConfig *global, } } -static void gen_cb_setopts(struct GlobalConfig *global, - struct OperationConfig *config, +static void gen_cb_setopts(struct OperationConfig *config, struct per_transfer *per, CURL *curl) { - (void) global; /* for builds without --libcurl */ - (void) config; + (void)config; /* when --libcurl is disabled */ + /* where to store */ my_setopt(curl, CURLOPT_WRITEDATA, per); my_setopt(curl, CURLOPT_INTERLEAVEDATA, per); @@ -693,17 +715,13 @@ static void gen_cb_setopts(struct GlobalConfig *global, my_setopt(curl, CURLOPT_HEADERDATA, per); } -static CURLcode proxy_setopts(struct GlobalConfig *global, - struct OperationConfig *config, - CURL *curl) +static CURLcode proxy_setopts(struct OperationConfig *config, CURL *curl) { - (void) global; /* for builds without --libcurl */ - if(config->proxy) { CURLcode result = my_setopt_str(curl, CURLOPT_PROXY, config->proxy); if(result) { - errorf(global, "proxy support is disabled in this libcurl"); + errorf("proxy support is disabled in this libcurl"); config->synthetic_error = TRUE; return CURLE_NOT_BUILT_IN; } @@ -724,7 +742,7 @@ static CURLcode proxy_setopts(struct GlobalConfig *global, /* new in libcurl 7.10.6 */ if(config->proxyanyauth) - my_setopt_bitmask(curl, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY); + my_setopt_bitmask(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY); else if(config->proxynegotiate) my_setopt_bitmask(curl, CURLOPT_PROXYAUTH, CURLAUTH_GSSNEGOTIATE); else if(config->proxyntlm) @@ -756,11 +774,8 @@ static CURLcode proxy_setopts(struct GlobalConfig *global, return CURLE_OK; } -static void tls_srp_setopts(struct GlobalConfig *global, - struct OperationConfig *config, - CURL *curl) +static void tls_srp_setopts(struct OperationConfig *config, CURL *curl) { - (void) global; /* for builds without --libcurl */ if(config->tls_username) my_setopt_str(curl, CURLOPT_TLSAUTH_USERNAME, config->tls_username); if(config->tls_password) @@ -778,8 +793,7 @@ static void tls_srp_setopts(struct GlobalConfig *global, config->proxy_tls_authtype); } -CURLcode config2setopts(struct GlobalConfig *global, - struct OperationConfig *config, +CURLcode config2setopts(struct OperationConfig *config, struct per_transfer *per, CURL *curl, CURLSH *share) @@ -804,7 +818,7 @@ CURLcode config2setopts(struct GlobalConfig *global, return result; #endif - gen_trace_setopts(global, config, curl); + gen_trace_setopts(config, curl); { #ifdef DEBUGBUILD @@ -828,15 +842,12 @@ CURLcode config2setopts(struct GlobalConfig *global, my_setopt_long(curl, CURLOPT_NOPROGRESS, global->noprogress || global->silent); /* call after the line above. It may override CURLOPT_NOPROGRESS */ - gen_cb_setopts(global, config, per, curl); - - if(config->no_body) - my_setopt_long(curl, CURLOPT_NOBODY, 1); + gen_cb_setopts(config, per, curl); - if(config->oauth_bearer) - my_setopt_str(curl, CURLOPT_XOAUTH2_BEARER, config->oauth_bearer); + my_setopt_long(curl, CURLOPT_NOBODY, config->no_body); + my_setopt_str(curl, CURLOPT_XOAUTH2_BEARER, config->oauth_bearer); - result = proxy_setopts(global, config, curl); + result = proxy_setopts(config, curl); if(result) return result; @@ -853,12 +864,9 @@ CURLcode config2setopts(struct GlobalConfig *global, else my_setopt_enum(curl, CURLOPT_NETRC, CURL_NETRC_IGNORED); - if(config->netrc_file) - my_setopt_str(curl, CURLOPT_NETRC_FILE, config->netrc_file); - + my_setopt_str(curl, CURLOPT_NETRC_FILE, config->netrc_file); my_setopt_long(curl, CURLOPT_TRANSFERTEXT, config->use_ascii); - if(config->login_options) - my_setopt_str(curl, CURLOPT_LOGIN_OPTIONS, config->login_options); + my_setopt_str(curl, CURLOPT_LOGIN_OPTIONS, config->login_options); my_setopt_str(curl, CURLOPT_USERPWD, config->userpwd); my_setopt_str(curl, CURLOPT_RANGE, config->range); if(!global->parallel) { @@ -870,7 +878,7 @@ CURLcode config2setopts(struct GlobalConfig *global, switch(config->httpreq) { case TOOL_HTTPREQ_SIMPLEPOST: if(config->resume_from) { - errorf(global, "cannot mix --continue-at with --data"); + errorf("cannot mix --continue-at with --data"); result = CURLE_FAILED_INIT; } else { @@ -885,7 +893,7 @@ CURLcode config2setopts(struct GlobalConfig *global, curl_mime_free(config->mimepost); config->mimepost = NULL; if(config->resume_from) { - errorf(global, "cannot mix --continue-at with --form"); + errorf("cannot mix --continue-at with --form"); result = CURLE_FAILED_INIT; } else { @@ -900,11 +908,9 @@ CURLcode config2setopts(struct GlobalConfig *global, if(result) return result; - /* new in libcurl 7.81.0 */ if(config->mime_options) my_setopt_long(curl, CURLOPT_MIME_OPTIONS, config->mime_options); - /* new in libcurl 7.10.6 (default is Basic) */ if(config->authtype) my_setopt_bitmask(curl, CURLOPT_HTTPAUTH, config->authtype); @@ -916,15 +922,15 @@ CURLcode config2setopts(struct GlobalConfig *global, } if(use_proto == proto_http || use_proto == proto_https) { - result = http_setopts(global, config, curl); + result = http_setopts(config, curl); if(!result) - result = cookie_setopts(global, config, curl); + result = cookie_setopts(config, curl); if(result) return result; } if(use_proto == proto_ftp || use_proto == proto_ftps) { - result = ftp_setopts(global, config, curl); + result = ftp_setopts(config, curl); if(result) return result; } @@ -937,19 +943,19 @@ CURLcode config2setopts(struct GlobalConfig *global, if(config->use_resume) my_setopt_offt(curl, CURLOPT_RESUME_FROM_LARGE, config->resume_from); else - my_setopt_offt(curl, CURLOPT_RESUME_FROM_LARGE, CURL_OFF_T_C(0)); + my_setopt_offt(curl, CURLOPT_RESUME_FROM_LARGE, 0); my_setopt_str(curl, CURLOPT_KEYPASSWD, config->key_passwd); my_setopt_str(curl, CURLOPT_PROXY_KEYPASSWD, config->proxy_key_passwd); if(use_proto == proto_scp || use_proto == proto_sftp) { - result = ssh_setopts(global, config, curl); + result = ssh_setopts(config, curl); if(result) return result; } if(feature_ssl) { - result = ssl_setopts(global, config, curl); + result = ssl_setopts(config, curl); if(result) return result; } @@ -970,93 +976,52 @@ CURLcode config2setopts(struct GlobalConfig *global, my_setopt_enum(curl, CURLOPT_TIMECONDITION, config->timecond); my_setopt_offt(curl, CURLOPT_TIMEVALUE_LARGE, config->condtime); my_setopt_str(curl, CURLOPT_CUSTOMREQUEST, config->customrequest); - customrequest_helper(config, config->httpreq, config->customrequest); + customrequest_helper(config->httpreq, config->customrequest); my_setopt(curl, CURLOPT_STDERR, tool_stderr); - - /* three new ones in libcurl 7.3: */ my_setopt_str(curl, CURLOPT_INTERFACE, config->iface); my_setopt_str(curl, CURLOPT_KRBLEVEL, config->krblevel); progressbarinit(&per->progressbar, config); - - /* new in libcurl 7.24.0: */ - if(config->dns_servers) - my_setopt_str(curl, CURLOPT_DNS_SERVERS, config->dns_servers); - - /* new in libcurl 7.33.0: */ - if(config->dns_interface) - my_setopt_str(curl, CURLOPT_DNS_INTERFACE, config->dns_interface); - if(config->dns_ipv4_addr) - my_setopt_str(curl, CURLOPT_DNS_LOCAL_IP4, config->dns_ipv4_addr); - if(config->dns_ipv6_addr) - my_setopt_str(curl, CURLOPT_DNS_LOCAL_IP6, config->dns_ipv6_addr); - - /* new in libcurl 7.6.2: */ + my_setopt_str(curl, CURLOPT_DNS_SERVERS, config->dns_servers); + my_setopt_str(curl, CURLOPT_DNS_INTERFACE, config->dns_interface); + my_setopt_str(curl, CURLOPT_DNS_LOCAL_IP4, config->dns_ipv4_addr); + my_setopt_str(curl, CURLOPT_DNS_LOCAL_IP6, config->dns_ipv6_addr); my_setopt_slist(curl, CURLOPT_TELNETOPTIONS, config->telnet_options); - - /* new in libcurl 7.7: */ my_setopt_long(curl, CURLOPT_CONNECTTIMEOUT_MS, config->connecttimeout_ms); - - if(config->doh_url) - my_setopt_str(curl, CURLOPT_DOH_URL, config->doh_url); - - /* new in curl 7.10.7, extended in 7.19.4. Modified to use - CREATE_DIR_RETRY in 7.49.0 */ + my_setopt_str(curl, CURLOPT_DOH_URL, config->doh_url); my_setopt_long(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, (config->ftp_create_dirs ? CURLFTP_CREATE_DIR_RETRY : CURLFTP_CREATE_DIR_NONE)); - - /* new in curl 7.10.8 */ - if(config->max_filesize) - my_setopt_offt(curl, CURLOPT_MAXFILESIZE_LARGE, - config->max_filesize); - + my_setopt_offt(curl, CURLOPT_MAXFILESIZE_LARGE, + config->max_filesize); my_setopt_long(curl, CURLOPT_IPRESOLVE, config->ip_version); - - /* new in curl 7.19.4 */ if(config->socks5_gssapi_nec) my_setopt_long(curl, CURLOPT_SOCKS5_GSSAPI_NEC, 1); - - /* new in curl 7.55.0 */ if(config->socks5_auth) my_setopt_bitmask(curl, CURLOPT_SOCKS5_AUTH, config->socks5_auth); - - /* new in curl 7.43.0 */ - if(config->service_name) - my_setopt_str(curl, CURLOPT_SERVICE_NAME, config->service_name); - - /* curl 7.13.0 */ + my_setopt_str(curl, CURLOPT_SERVICE_NAME, config->service_name); my_setopt_long(curl, CURLOPT_IGNORE_CONTENT_LENGTH, config->ignorecl); - /* curl 7.15.2 */ if(config->localport) { my_setopt_long(curl, CURLOPT_LOCALPORT, config->localport); my_setopt_long(curl, CURLOPT_LOCALPORTRANGE, config->localportrange); } - /* curl 7.16.2 */ if(config->raw) { my_setopt_long(curl, CURLOPT_HTTP_CONTENT_DECODING, 0); my_setopt_long(curl, CURLOPT_HTTP_TRANSFER_DECODING, 0); } - result = tcp_setopts(global, config, curl); + result = tcp_setopts(config, curl); if(result) return result; - /* curl 7.20.0 */ if(config->tftp_blksize && proto_tftp) my_setopt_long(curl, CURLOPT_TFTP_BLKSIZE, config->tftp_blksize); - if(config->mail_from) - my_setopt_str(curl, CURLOPT_MAIL_FROM, config->mail_from); - - if(config->mail_rcpt) - my_setopt_slist(curl, CURLOPT_MAIL_RCPT, config->mail_rcpt); - - /* curl 7.69.x */ + my_setopt_str(curl, CURLOPT_MAIL_FROM, config->mail_from); + my_setopt_slist(curl, CURLOPT_MAIL_RCPT, config->mail_rcpt); my_setopt_long(curl, CURLOPT_MAIL_RCPT_ALLOWFAILS, config->mail_rcpt_allowfails); - if(config->create_file_mode) my_setopt_long(curl, CURLOPT_NEW_FILE_PERMS, config->create_file_mode); @@ -1065,34 +1030,19 @@ CURLcode config2setopts(struct GlobalConfig *global, if(config->proto_redir_present) my_setopt_str(curl, CURLOPT_REDIR_PROTOCOLS_STR, config->proto_redir_str); - if(config->resolve) - /* new in 7.21.3 */ - my_setopt_slist(curl, CURLOPT_RESOLVE, config->resolve); - - if(config->connect_to) - /* new in 7.49.0 */ - my_setopt_slist(curl, CURLOPT_CONNECT_TO, config->connect_to); + my_setopt_slist(curl, CURLOPT_RESOLVE, config->resolve); + my_setopt_slist(curl, CURLOPT_CONNECT_TO, config->connect_to); - /* new in 7.21.4 */ if(feature_tls_srp) - tls_srp_setopts(global, config, curl); + tls_srp_setopts(config, curl); - /* new in 7.22.0 */ if(config->gssapi_delegation) my_setopt_long(curl, CURLOPT_GSSAPI_DELEGATION, config->gssapi_delegation); - if(config->mail_auth) - my_setopt_str(curl, CURLOPT_MAIL_AUTH, config->mail_auth); - - /* new in 7.66.0 */ - if(config->sasl_authzid) - my_setopt_str(curl, CURLOPT_SASL_AUTHZID, config->sasl_authzid); + my_setopt_str(curl, CURLOPT_MAIL_AUTH, config->mail_auth); + my_setopt_str(curl, CURLOPT_SASL_AUTHZID, config->sasl_authzid); + my_setopt_long(curl, CURLOPT_SASL_IR, config->sasl_ir); - /* new in 7.31.0 */ - if(config->sasl_ir) - my_setopt_long(curl, CURLOPT_SASL_IR, 1); - - /* new in 7.40.0, abstract support added in 7.53.0 */ if(config->unix_socket_path) { if(config->abstract_unix_socket) { my_setopt_str(curl, CURLOPT_ABSTRACT_UNIX_SOCKET, @@ -1104,42 +1054,32 @@ CURLcode config2setopts(struct GlobalConfig *global, } } - /* new in 7.45.0 */ - if(config->proto_default) - my_setopt_str(curl, CURLOPT_DEFAULT_PROTOCOL, config->proto_default); - - /* new in 7.48.0 */ - if(config->tftp_no_options && proto_tftp) - my_setopt_long(curl, CURLOPT_TFTP_NO_OPTIONS, 1); + my_setopt_str(curl, CURLOPT_DEFAULT_PROTOCOL, config->proto_default); + my_setopt_long(curl, CURLOPT_TFTP_NO_OPTIONS, + config->tftp_no_options && proto_tftp); - /* new in 7.59.0 */ if(config->happy_eyeballs_timeout_ms != CURL_HET_DEFAULT) my_setopt_long(curl, CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, config->happy_eyeballs_timeout_ms); - if(config->disallow_username_in_url) - my_setopt_long(curl, CURLOPT_DISALLOW_USERNAME_IN_URL, 1); + my_setopt_long(curl, CURLOPT_DISALLOW_USERNAME_IN_URL, + config->disallow_username_in_url); - /* new in 8.9.0 */ if(config->ip_tos > 0 || config->vlan_priority > 0) { #if defined(IP_TOS) || defined(IPV6_TCLASS) || defined(SO_PRIORITY) my_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback); my_setopt(curl, CURLOPT_SOCKOPTDATA, config); #else if(config->ip_tos > 0) { - errorf(config->global, - "Type of service is not supported in this build."); + errorf("Type of service is not supported in this build."); result = CURLE_NOT_BUILT_IN; } if(config->vlan_priority > 0) { - errorf(config->global, - "VLAN priority is not supported in this build."); + errorf("VLAN priority is not supported in this build."); result = CURLE_NOT_BUILT_IN; } #endif } - /* new in 8.13.0 */ - if(config->upload_flags) - my_setopt_long(curl, CURLOPT_UPLOAD_FLAGS, config->upload_flags); + my_setopt_long(curl, CURLOPT_UPLOAD_FLAGS, config->upload_flags); return result; } diff --git a/vendor/curl/src/config2setopts.h b/vendor/curl/src/config2setopts.h index 59d875fa1d6..3cf51b0d105 100644 --- a/vendor/curl/src/config2setopts.h +++ b/vendor/curl/src/config2setopts.h @@ -24,8 +24,7 @@ * ***************************************************************************/ -CURLcode config2setopts(struct GlobalConfig *global, - struct OperationConfig *config, +CURLcode config2setopts(struct OperationConfig *config, struct per_transfer *per, CURL *curl, CURLSH *share); diff --git a/vendor/curl/src/curlinfo.c b/vendor/curl/src/curlinfo.c index 0274b0a2d51..d601904f3ee 100644 --- a/vendor/curl/src/curlinfo.c +++ b/vendor/curl/src/curlinfo.c @@ -70,7 +70,7 @@ static const char *disabled[]={ "ON" #endif , - "digest-auth: " + "digest: " #ifdef CURL_DISABLE_DIGEST_AUTH "OFF" #else @@ -244,8 +244,8 @@ int main(int argc, char **argv) { int i; - (void) argc; - (void) argv; + (void)argc; + (void)argv; for(i = 0; disabled[i]; i++) printf("%s\n", disabled[i]); diff --git a/vendor/curl/src/slist_wc.c b/vendor/curl/src/slist_wc.c index 41c944d94b9..7f1e8f19be8 100644 --- a/vendor/curl/src/slist_wc.c +++ b/vendor/curl/src/slist_wc.c @@ -29,7 +29,7 @@ #include "slist_wc.h" /* The last #include files should be: */ -#include +#include "memdebug.h" /* * slist_wc_append() appends a string to the linked list. This function can be diff --git a/vendor/curl/src/terminal.c b/vendor/curl/src/terminal.c index 384afd8cb3b..0150cd4a56c 100644 --- a/vendor/curl/src/terminal.c +++ b/vendor/curl/src/terminal.c @@ -28,8 +28,7 @@ #endif #include "terminal.h" -#include -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ #ifdef HAVE_TERMIOS_H # include diff --git a/vendor/curl/src/tool_bname.c b/vendor/curl/src/tool_bname.c index 62dbcf2ed51..4ba1a3b8eea 100644 --- a/vendor/curl/src/tool_bname.c +++ b/vendor/curl/src/tool_bname.c @@ -25,7 +25,7 @@ #include "tool_bname.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ #ifndef HAVE_BASENAME diff --git a/vendor/curl/src/tool_cb_dbg.c b/vendor/curl/src/tool_cb_dbg.c index 2cf889c51cf..0b36236ab7d 100644 --- a/vendor/curl/src/tool_cb_dbg.c +++ b/vendor/curl/src/tool_cb_dbg.c @@ -23,14 +23,12 @@ ***************************************************************************/ #include "tool_setup.h" -#include - #include "tool_cfgable.h" #include "tool_msgs.h" #include "tool_cb_dbg.h" #include "tool_util.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ static void dump(const char *timebuf, const char *idsbuf, const char *text, FILE *stream, const unsigned char *ptr, size_t size, @@ -81,8 +79,6 @@ int tool_debug_cb(CURL *handle, curl_infotype type, char *data, size_t size, void *userdata) { - struct OperationConfig *operation = userdata; - struct GlobalConfig *config = operation->global; FILE *output = tool_stderr; const char *text; struct timeval tv; @@ -96,8 +92,9 @@ int tool_debug_cb(CURL *handle, curl_infotype type, curl_off_t xfer_id, conn_id; (void)handle; /* not used */ + (void)userdata; - if(config->tracetime) { + if(global->tracetime) { tv = tvrealnow(); msnprintf(timebuf, sizeof(timebuf), "%s.%06ld ", hms_for_sec(tv.tv_sec), (long)tv.tv_usec); @@ -105,7 +102,7 @@ int tool_debug_cb(CURL *handle, curl_infotype type, else timebuf[0] = 0; - if(handle && config->traceids && + if(handle && global->traceids && !curl_easy_getinfo(handle, CURLINFO_XFER_ID, &xfer_id) && xfer_id >= 0) { if(!curl_easy_getinfo(handle, CURLINFO_CONN_ID, &conn_id) && conn_id >= 0) { @@ -119,28 +116,28 @@ int tool_debug_cb(CURL *handle, curl_infotype type, else idsbuf[0] = 0; - if(!config->trace_stream) { + if(!global->trace_stream) { /* open for append */ - if(!strcmp("-", config->trace_dump)) - config->trace_stream = stdout; - else if(!strcmp("%", config->trace_dump)) + if(!strcmp("-", global->trace_dump)) + global->trace_stream = stdout; + else if(!strcmp("%", global->trace_dump)) /* Ok, this is somewhat hackish but we do it undocumented for now */ - config->trace_stream = tool_stderr; + global->trace_stream = tool_stderr; else { - config->trace_stream = fopen(config->trace_dump, FOPEN_WRITETEXT); - config->trace_fopened = TRUE; + global->trace_stream = fopen(global->trace_dump, FOPEN_WRITETEXT); + global->trace_fopened = TRUE; } } - if(config->trace_stream) - output = config->trace_stream; + if(global->trace_stream) + output = global->trace_stream; if(!output) { - warnf(config, "Failed to create/open output"); + warnf("Failed to create/open output"); return 0; } - if(config->tracetype == TRACE_PLAIN) { + if(global->tracetype == TRACE_PLAIN) { static bool newl = FALSE; static bool traced_data = FALSE; @@ -183,7 +180,7 @@ int tool_debug_cb(CURL *handle, curl_infotype type, to stderr or stdout, we do not display the alert about the data not being shown as the data _is_ shown then just not via this function */ - if(!config->isatty || + if(!global->isatty || ((output != tool_stderr) && (output != stdout))) { if(!newl) log_line_start(output, timebuf, idsbuf, type); @@ -230,7 +227,7 @@ int tool_debug_cb(CURL *handle, curl_infotype type, } dump(timebuf, idsbuf, text, output, (unsigned char *) data, size, - config->tracetype, type); + global->tracetype, type); return 0; } diff --git a/vendor/curl/src/tool_cb_hdr.c b/vendor/curl/src/tool_cb_hdr.c index 151fd5c0ffd..6af9d1947e1 100644 --- a/vendor/curl/src/tool_cb_hdr.c +++ b/vendor/curl/src/tool_cb_hdr.c @@ -27,8 +27,6 @@ #include #endif -#include - #include "tool_cfgable.h" #include "tool_doswin.h" #include "tool_msgs.h" @@ -36,8 +34,9 @@ #include "tool_cb_wrt.h" #include "tool_operate.h" #include "tool_libinfo.h" +#include "tool_strdup.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ static char *parse_filename(const char *ptr, size_t len); @@ -58,7 +57,7 @@ static char *parse_filename(const char *ptr, size_t len); #ifdef LINK static void write_linked_location(CURL *curl, const char *location, - size_t loclen, FILE *stream); + size_t loclen, FILE *stream); #endif int tool_write_headers(struct HdrCbData *hdrcbdata, FILE *stream) @@ -83,7 +82,6 @@ int tool_write_headers(struct HdrCbData *hdrcbdata, FILE *stream) /* ** callback for CURLOPT_HEADERFUNCTION */ - size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) { struct per_transfer *per = userdata; @@ -101,7 +99,7 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) #ifdef DEBUGBUILD if(size * nmemb > (size_t)CURL_MAX_HTTP_HEADER) { - warnf(per->config->global, "Header data exceeds single call write limit"); + warnf("Header data exceeds write limit"); return CURL_WRITEFUNC_ERROR; } #endif @@ -122,8 +120,7 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) return rc; /* flush the stream to send off what we got earlier */ if(fflush(heads->stream)) { - errorf(per->config->global, "Failed writing headers to %s", - per->config->headerfile); + errorf("Failed writing headers to %s", per->config->headerfile); return CURL_WRITEFUNC_ERROR; } } @@ -288,11 +285,11 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) if(!outs->stream && !tool_create_output_file(outs, per->config)) return CURL_WRITEFUNC_ERROR; - if(hdrcbdata->global->isatty && + if(global->isatty && #ifdef _WIN32 tool_term_has_bold && #endif - hdrcbdata->global->styled_output) + global->styled_output) value = memchr(ptr, ':', cb); if(value) { size_t namelen = value - ptr; @@ -325,12 +322,9 @@ static char *parse_filename(const char *ptr, size_t len) char *q; char stop = '\0'; - /* simple implementation of strndup() */ - copy = malloc(len + 1); + copy = memdup0(ptr, len); if(!copy) return NULL; - memcpy(copy, ptr, len); - copy[len] = '\0'; p = copy; if(*p == '\'' || *p == '"') { @@ -404,9 +398,9 @@ static char *parse_filename(const char *ptr, size_t len) * should not be needed but the real world returns plenty of relative * URLs here. */ -static -void write_linked_location(CURL *curl, const char *location, size_t loclen, - FILE *stream) { +static void write_linked_location(CURL *curl, const char *location, + size_t loclen, FILE *stream) +{ /* This would so simple if CURLINFO_REDIRECT_URL were available here */ CURLU *u = NULL; char *copyloc = NULL, *locurl = NULL, *scheme = NULL, *finalurl = NULL; @@ -441,11 +435,9 @@ void write_linked_location(CURL *curl, const char *location, size_t loclen, goto locout; /* Create a null-terminated and whitespace-stripped copy of Location: */ - copyloc = malloc(llen + 1); + copyloc = memdup0(loc, llen); if(!copyloc) goto locout; - memcpy(copyloc, loc, llen); - copyloc[llen] = 0; /* The original URL to use as a base for a relative redirect URL */ if(curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &locurl)) diff --git a/vendor/curl/src/tool_cb_hdr.h b/vendor/curl/src/tool_cb_hdr.h index 7402c12a9b9..37be591e70e 100644 --- a/vendor/curl/src/tool_cb_hdr.h +++ b/vendor/curl/src/tool_cb_hdr.h @@ -41,7 +41,6 @@ */ struct HdrCbData { - struct GlobalConfig *global; struct OperationConfig *config; struct OutStruct *outs; struct OutStruct *heads; diff --git a/vendor/curl/src/tool_cb_prg.c b/vendor/curl/src/tool_cb_prg.c index 56f03f2e4e4..c6ee6b2822f 100644 --- a/vendor/curl/src/tool_cb_prg.c +++ b/vendor/curl/src/tool_cb_prg.c @@ -23,15 +23,13 @@ ***************************************************************************/ #include "tool_setup.h" -#include - #include "tool_cfgable.h" #include "tool_cb_prg.h" #include "tool_util.h" #include "tool_operate.h" #include "terminal.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ #define MAX_BARLENGTH 400 #define MIN_BARLENGTH 20 @@ -115,7 +113,7 @@ static void fly(struct ProgressData *bar, bool moved) #error "too small curl_off_t" #else /* assume SIZEOF_CURL_OFF_T == 8 */ -# define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF) +# define CURL_OFF_T_MAX 0x7FFFFFFFFFFFFFFF #endif static void update_width(struct ProgressData *bar) diff --git a/vendor/curl/src/tool_cb_rea.c b/vendor/curl/src/tool_cb_rea.c index 86ae476a225..5b8ba62a56b 100644 --- a/vendor/curl/src/tool_cb_rea.c +++ b/vendor/curl/src/tool_cb_rea.c @@ -27,16 +27,13 @@ #include #endif -#include - #include "tool_cfgable.h" #include "tool_cb_rea.h" #include "tool_operate.h" #include "tool_util.h" #include "tool_msgs.h" -#include "tool_sleep.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ /* ** callback for CURLOPT_READFUNCTION @@ -74,12 +71,12 @@ size_t tool_read_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) timeout.tv_usec = (int)((wait%1000)*1000); FD_ZERO(&bits); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif FD_SET(per->infd, &bits); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif if(!select(per->infd + 1, &bits, NULL, NULL, &timeout)) @@ -88,21 +85,45 @@ size_t tool_read_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) #endif } - rc = read(per->infd, buffer, sz*nmemb); - if(rc < 0) { - if(errno == EAGAIN) { - CURL_SETERRNO(0); - config->readbusy = TRUE; - return CURL_READFUNC_PAUSE; + /* If we are on Windows, and using `-T .`, then per->infd points to a socket + connected to stdin via a reader thread, and needs to be read with recv() + Make sure we are in non-blocking mode and infd is not regular stdin + On Linux per->infd should be stdin (0) and the block below should not + execute */ + if(per->uploadfile && !strcmp(per->uploadfile, ".") && per->infd > 0) { +#if defined(_WIN32) && !defined(CURL_WINDOWS_UWP) && !defined(UNDER_CE) + rc = recv(per->infd, buffer, curlx_uztosi(sz * nmemb), 0); + if(rc < 0) { + if(SOCKERRNO == SOCKEWOULDBLOCK) { + CURL_SETERRNO(0); + config->readbusy = TRUE; + return CURL_READFUNC_PAUSE; + } + + rc = 0; + } +#else + warnf("per->infd != 0: FD == %d. This behavior" + " is only supported on desktop Windows", per->infd); +#endif + } + else { + rc = read(per->infd, buffer, sz*nmemb); + if(rc < 0) { + if(errno == EAGAIN) { + CURL_SETERRNO(0); + config->readbusy = TRUE; + return CURL_READFUNC_PAUSE; + } + /* since size_t is unsigned we cannot return negative values fine */ + rc = 0; } - /* since size_t is unsigned we cannot return negative values fine */ - rc = 0; } if((per->uploadfilesize != -1) && (per->uploadedsofar + rc > per->uploadfilesize)) { /* do not allow uploading more than originally set out to do */ curl_off_t delta = per->uploadedsofar + rc - per->uploadfilesize; - warnf(per->config->global, "File size larger in the end than when " + warnf("File size larger in the end than when " "started. Dropping at least %" CURL_FORMAT_CURL_OFF_T " bytes", delta); rc = (ssize_t)(per->uploadfilesize - per->uploadedsofar); @@ -123,6 +144,7 @@ int tool_readbusy_cb(void *clientp, { struct per_transfer *per = clientp; struct OperationConfig *config = per->config; + static curl_off_t ulprev; (void)dltotal; /* unused */ (void)dlnow; /* unused */ @@ -130,33 +152,35 @@ int tool_readbusy_cb(void *clientp, (void)ulnow; /* unused */ if(config->readbusy) { - /* lame code to keep the rate down because the input might not deliver - anything, get paused again and come back here immediately */ - static timediff_t rate = 500; - static struct curltime prev; - static curl_off_t ulprev; - if(ulprev == ulnow) { - /* it did not upload anything since last call */ - struct curltime now = curlx_now(); - if(prev.tv_sec) - /* get a rolling average rate */ - rate -= rate/4 - curlx_timediff(now, prev)/4; - prev = now; - } - else { - rate = 50; - ulprev = ulnow; - } - if(rate >= 50) { - /* keeps the looping down to 20 times per second in the crazy case */ - config->readbusy = FALSE; - curl_easy_pause(per->curl, CURLPAUSE_CONT); +#ifndef _WIN32 + fd_set bits; + struct timeval timeout; + /* wait this long at the most */ + timeout.tv_sec = 0; + timeout.tv_usec = 1000; + + FD_ZERO(&bits); +#ifdef __DJGPP__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warith-conversion" +#endif + FD_SET(per->infd, &bits); +#ifdef __DJGPP__ +#pragma GCC diagnostic pop +#endif + select(per->infd + 1, &bits, NULL, NULL, &timeout); +#else + /* sleep */ + curlx_wait_ms(1); +#endif } - else - /* sleep half a period */ - tool_go_sleep(25); + + config->readbusy = FALSE; + curl_easy_pause(per->curl, CURLPAUSE_CONT); } + ulprev = ulnow; + return per->noprogress ? 0 : CURL_PROGRESSFUNC_CONTINUE; } diff --git a/vendor/curl/src/tool_cb_see.c b/vendor/curl/src/tool_cb_see.c index dea98a8e8af..68899c58295 100644 --- a/vendor/curl/src/tool_cb_see.c +++ b/vendor/curl/src/tool_cb_see.c @@ -23,13 +23,11 @@ ***************************************************************************/ #include "tool_setup.h" -#include - #include "tool_cfgable.h" #include "tool_operate.h" #include "tool_cb_see.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ /* ** callback for CURLOPT_SEEKFUNCTION @@ -49,7 +47,7 @@ int tool_seek_cb(void *userdata, curl_off_t offset, int whence) using a 'long' data type offset */ #define OUR_MAX_SEEK_L 2147483647L - 1L -#define OUR_MAX_SEEK_O CURL_OFF_T_C(0x7FFFFFFF) - CURL_OFF_T_C(0x1) +#define OUR_MAX_SEEK_O 0x7FFFFFFF - 0x1 /* The offset check following here is only interesting if curl_off_t is larger than off_t and we are not using the Win32 large file support diff --git a/vendor/curl/src/tool_cb_wrt.c b/vendor/curl/src/tool_cb_wrt.c index e0dbe2c9c75..6fbf80753de 100644 --- a/vendor/curl/src/tool_cb_wrt.c +++ b/vendor/curl/src/tool_cb_wrt.c @@ -28,16 +28,12 @@ #include #endif -#include - -#include - #include "tool_cfgable.h" #include "tool_msgs.h" #include "tool_cb_wrt.h" #include "tool_operate.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ #ifdef _WIN32 #define OPENMODE S_IREAD | S_IWRITE @@ -49,12 +45,10 @@ bool tool_create_output_file(struct OutStruct *outs, struct OperationConfig *config) { - struct GlobalConfig *global; FILE *file = NULL; const char *fname = outs->filename; DEBUGASSERT(outs); DEBUGASSERT(config); - global = config->global; DEBUGASSERT(fname && *fname); if(config->file_clobber_mode == CLOBBER_ALWAYS || @@ -72,35 +66,24 @@ bool tool_create_output_file(struct OutStruct *outs, } while(fd == -1 && errno == EINTR); if(config->file_clobber_mode == CLOBBER_NEVER && fd == -1) { int next_num = 1; - size_t len = strlen(fname); - size_t newlen = len + 13; /* nul + 1-11 digits + dot */ - char *newname; - /* Guard against wraparound in new filename */ - if(newlen < len) { - errorf(global, "overflow in filename generation"); - return FALSE; - } - newname = malloc(newlen); - if(!newname) { - errorf(global, "out of memory"); - return FALSE; - } - memcpy(newname, fname, len); - newname[len] = '.'; + struct dynbuf fbuffer; + curlx_dyn_init(&fbuffer, 1025); /* !checksrc! disable ERRNOVAR 1 */ while(fd == -1 && /* have not successfully opened a file */ (errno == EEXIST || errno == EISDIR) && /* because we keep having files that already exist */ next_num < 100 /* and we have not reached the retry limit */ ) { - msnprintf(newname + len + 1, 12, "%d", next_num); + curlx_dyn_reset(&fbuffer); + if(curlx_dyn_addf(&fbuffer, "%s.%d", fname, next_num)) + return FALSE; next_num++; do { - fd = open(newname, O_CREAT | O_WRONLY | O_EXCL | CURL_O_BINARY, - OPENMODE); + fd = open(curlx_dyn_ptr(&fbuffer), + O_CREAT | O_WRONLY | O_EXCL | CURL_O_BINARY, OPENMODE); /* Keep retrying in the hope that it is not interrupted sometime */ } while(fd == -1 && errno == EINTR); } - outs->filename = newname; /* remember the new one */ + outs->filename = curlx_dyn_ptr(&fbuffer); /* remember the new one */ outs->alloc_filename = TRUE; } /* An else statement to not overwrite existing files and not retry with @@ -116,8 +99,7 @@ bool tool_create_output_file(struct OutStruct *outs, } if(!file) { - warnf(global, "Failed to open the file %s: %s", fname, - strerror(errno)); + warnf("Failed to open the file %s: %s", fname, strerror(errno)); return FALSE; } outs->s_isreg = TRUE; @@ -128,6 +110,132 @@ bool tool_create_output_file(struct OutStruct *outs, return TRUE; } +#if defined(_WIN32) && !defined(UNDER_CE) +static size_t win_console(intptr_t fhnd, struct OutStruct *outs, + char *buffer, size_t bytes, + size_t *retp) +{ + DWORD chars_written; + unsigned char *rbuf = (unsigned char *)buffer; + DWORD rlen = (DWORD)bytes; + +#define IS_TRAILING_BYTE(x) (0x80 <= (x) && (x) < 0xC0) + + /* attempt to complete an incomplete UTF-8 sequence from previous call. the + sequence does not have to be well-formed. */ + if(outs->utf8seq[0] && rlen) { + bool complete = false; + /* two byte sequence (lead byte 110yyyyy) */ + if(0xC0 <= outs->utf8seq[0] && outs->utf8seq[0] < 0xE0) { + outs->utf8seq[1] = *rbuf++; + --rlen; + complete = true; + } + /* three byte sequence (lead byte 1110zzzz) */ + else if(0xE0 <= outs->utf8seq[0] && outs->utf8seq[0] < 0xF0) { + if(!outs->utf8seq[1]) { + outs->utf8seq[1] = *rbuf++; + --rlen; + } + if(rlen && !outs->utf8seq[2]) { + outs->utf8seq[2] = *rbuf++; + --rlen; + complete = true; + } + } + /* four byte sequence (lead byte 11110uuu) */ + else if(0xF0 <= outs->utf8seq[0] && outs->utf8seq[0] < 0xF8) { + if(!outs->utf8seq[1]) { + outs->utf8seq[1] = *rbuf++; + --rlen; + } + if(rlen && !outs->utf8seq[2]) { + outs->utf8seq[2] = *rbuf++; + --rlen; + } + if(rlen && !outs->utf8seq[3]) { + outs->utf8seq[3] = *rbuf++; + --rlen; + complete = true; + } + } + + if(complete) { + WCHAR prefix[3] = {0}; /* UTF-16 (1-2 WCHARs) + NUL */ + + if(MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)outs->utf8seq, -1, + prefix, CURL_ARRAYSIZE(prefix))) { + DEBUGASSERT(prefix[2] == L'\0'); + if(!WriteConsoleW((HANDLE) fhnd, prefix, prefix[1] ? 2 : 1, + &chars_written, NULL)) { + return CURL_WRITEFUNC_ERROR; + } + } + /* else: UTF-8 input was not well formed and OS is pre-Vista which drops + invalid characters instead of writing U+FFFD to output. */ + memset(outs->utf8seq, 0, sizeof(outs->utf8seq)); + } + } + + /* suppress an incomplete utf-8 sequence at end of rbuf */ + if(!outs->utf8seq[0] && rlen && (rbuf[rlen - 1] & 0x80)) { + /* check for lead byte from a two, three or four byte sequence */ + if(0xC0 <= rbuf[rlen - 1] && rbuf[rlen - 1] < 0xF8) { + outs->utf8seq[0] = rbuf[rlen - 1]; + rlen -= 1; + } + else if(rlen >= 2 && IS_TRAILING_BYTE(rbuf[rlen - 1])) { + /* check for lead byte from a three or four byte sequence */ + if(0xE0 <= rbuf[rlen - 2] && rbuf[rlen - 2] < 0xF8) { + outs->utf8seq[0] = rbuf[rlen - 2]; + outs->utf8seq[1] = rbuf[rlen - 1]; + rlen -= 2; + } + else if(rlen >= 3 && IS_TRAILING_BYTE(rbuf[rlen - 2])) { + /* check for lead byte from a four byte sequence */ + if(0xF0 <= rbuf[rlen - 3] && rbuf[rlen - 3] < 0xF8) { + outs->utf8seq[0] = rbuf[rlen - 3]; + outs->utf8seq[1] = rbuf[rlen - 2]; + outs->utf8seq[2] = rbuf[rlen - 1]; + rlen -= 3; + } + } + } + } + + if(rlen) { + /* calculate buffer size for wide characters */ + DWORD len = (DWORD)MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)rbuf, + (int)rlen, NULL, 0); + if(!len) + return CURL_WRITEFUNC_ERROR; + + /* grow the buffer if needed */ + if(len > global->term.len) { + wchar_t *buf = (wchar_t *) realloc(global->term.buf, + len * sizeof(wchar_t)); + if(!buf) + return CURL_WRITEFUNC_ERROR; + global->term.len = len; + global->term.buf = buf; + } + + len = (DWORD)MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)rbuf, (int)rlen, + global->term.buf, + (int)len); + if(!len) + return CURL_WRITEFUNC_ERROR; + + if(!WriteConsoleW((HANDLE) fhnd, global->term.buf, + len, &chars_written, NULL)) + return CURL_WRITEFUNC_ERROR; + } + + *retp = bytes; + return 0; +} +#endif + /* ** callback for CURLOPT_WRITEFUNCTION */ @@ -139,12 +247,15 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) struct OutStruct *outs = &per->outs; struct OperationConfig *config = per->config; size_t bytes = sz * nmemb; - bool is_tty = config->global->isatty; + bool is_tty = global->isatty; #if defined(_WIN32) && !defined(UNDER_CE) CONSOLE_SCREEN_BUFFER_INFO console_info; intptr_t fhnd; #endif + if(outs->out_null) + return bytes; + #ifdef DEBUGBUILD { char *tty = curl_getenv("CURL_ISATTY"); @@ -156,14 +267,13 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) if(config->show_headers) { if(bytes > (size_t)CURL_MAX_HTTP_HEADER) { - warnf(config->global, "Header data size exceeds single call write " - "limit"); + warnf("Header data size exceeds write limit"); return CURL_WRITEFUNC_ERROR; } } else { if(bytes > (size_t)CURL_MAX_WRITE_SIZE) { - warnf(config->global, "Data size exceeds single call write limit"); + warnf("Data size exceeds write limit"); return CURL_WRITEFUNC_ERROR; } } @@ -192,7 +302,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) check_fails = TRUE; } if(check_fails) { - warnf(config->global, "Invalid output struct data for write callback"); + warnf("Invalid output struct data for write callback"); return CURL_WRITEFUNC_ERROR; } } @@ -204,7 +314,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) if(is_tty && (outs->bytes < 2000) && !config->terminal_binary_ok) { /* binary output to terminal? */ if(memchr(buffer, 0, bytes)) { - warnf(config->global, "Binary output can mess up your terminal. " + warnf("Binary output can mess up your terminal. " "Use \"--output -\" to tell curl to output it to your terminal " "anyway, or consider \"--output \" to save to a file."); config->synthetic_error = TRUE; @@ -217,131 +327,9 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) /* if Windows console then UTF-8 must be converted to UTF-16 */ if(isatty(fileno(outs->stream)) && GetConsoleScreenBufferInfo((HANDLE)fhnd, &console_info)) { - wchar_t *wc_buf; - DWORD wc_len, chars_written; - unsigned char *rbuf = (unsigned char *)buffer; - DWORD rlen = (DWORD)bytes; - -#define IS_TRAILING_BYTE(x) (0x80 <= (x) && (x) < 0xC0) - - /* attempt to complete an incomplete UTF-8 sequence from previous call. - the sequence does not have to be well-formed. */ - if(outs->utf8seq[0] && rlen) { - bool complete = false; - /* two byte sequence (lead byte 110yyyyy) */ - if(0xC0 <= outs->utf8seq[0] && outs->utf8seq[0] < 0xE0) { - outs->utf8seq[1] = *rbuf++; - --rlen; - complete = true; - } - /* three byte sequence (lead byte 1110zzzz) */ - else if(0xE0 <= outs->utf8seq[0] && outs->utf8seq[0] < 0xF0) { - if(!outs->utf8seq[1]) { - outs->utf8seq[1] = *rbuf++; - --rlen; - } - if(rlen && !outs->utf8seq[2]) { - outs->utf8seq[2] = *rbuf++; - --rlen; - complete = true; - } - } - /* four byte sequence (lead byte 11110uuu) */ - else if(0xF0 <= outs->utf8seq[0] && outs->utf8seq[0] < 0xF8) { - if(!outs->utf8seq[1]) { - outs->utf8seq[1] = *rbuf++; - --rlen; - } - if(rlen && !outs->utf8seq[2]) { - outs->utf8seq[2] = *rbuf++; - --rlen; - } - if(rlen && !outs->utf8seq[3]) { - outs->utf8seq[3] = *rbuf++; - --rlen; - complete = true; - } - } - - if(complete) { - WCHAR prefix[3] = {0}; /* UTF-16 (1-2 WCHARs) + NUL */ - - if(MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)outs->utf8seq, -1, - prefix, CURL_ARRAYSIZE(prefix))) { - DEBUGASSERT(prefix[2] == L'\0'); - if(!WriteConsoleW( - (HANDLE) fhnd, - prefix, - prefix[1] ? 2 : 1, - &chars_written, - NULL)) { - return CURL_WRITEFUNC_ERROR; - } - } - /* else: UTF-8 input was not well formed and OS is pre-Vista which - drops invalid characters instead of writing U+FFFD to output. */ - - memset(outs->utf8seq, 0, sizeof(outs->utf8seq)); - } - } - - /* suppress an incomplete utf-8 sequence at end of rbuf */ - if(!outs->utf8seq[0] && rlen && (rbuf[rlen - 1] & 0x80)) { - /* check for lead byte from a two, three or four byte sequence */ - if(0xC0 <= rbuf[rlen - 1] && rbuf[rlen - 1] < 0xF8) { - outs->utf8seq[0] = rbuf[rlen - 1]; - rlen -= 1; - } - else if(rlen >= 2 && IS_TRAILING_BYTE(rbuf[rlen - 1])) { - /* check for lead byte from a three or four byte sequence */ - if(0xE0 <= rbuf[rlen - 2] && rbuf[rlen - 2] < 0xF8) { - outs->utf8seq[0] = rbuf[rlen - 2]; - outs->utf8seq[1] = rbuf[rlen - 1]; - rlen -= 2; - } - else if(rlen >= 3 && IS_TRAILING_BYTE(rbuf[rlen - 2])) { - /* check for lead byte from a four byte sequence */ - if(0xF0 <= rbuf[rlen - 3] && rbuf[rlen - 3] < 0xF8) { - outs->utf8seq[0] = rbuf[rlen - 3]; - outs->utf8seq[1] = rbuf[rlen - 2]; - outs->utf8seq[2] = rbuf[rlen - 1]; - rlen -= 3; - } - } - } - } - - if(rlen) { - /* calculate buffer size for wide characters */ - wc_len = (DWORD)MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)rbuf, (int)rlen, - NULL, 0); - if(!wc_len) - return CURL_WRITEFUNC_ERROR; - - wc_buf = (wchar_t*) malloc(wc_len * sizeof(wchar_t)); - if(!wc_buf) - return CURL_WRITEFUNC_ERROR; - - wc_len = (DWORD)MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)rbuf, (int)rlen, - wc_buf, (int)wc_len); - if(!wc_len) { - free(wc_buf); - return CURL_WRITEFUNC_ERROR; - } - - if(!WriteConsoleW( - (HANDLE) fhnd, - wc_buf, - wc_len, - &chars_written, - NULL)) { - free(wc_buf); - return CURL_WRITEFUNC_ERROR; - } - free(wc_buf); - } - - rc = bytes; + size_t retval = win_console(fhnd, outs, buffer, bytes, &rc); + if(retval) + return retval; } else #endif diff --git a/vendor/curl/src/tool_cfgable.c b/vendor/curl/src/tool_cfgable.c index 99fc91b0972..0321848b0d5 100644 --- a/vendor/curl/src/tool_cfgable.c +++ b/vendor/curl/src/tool_cfgable.c @@ -27,12 +27,18 @@ #include "tool_formparse.h" #include "tool_paramhlp.h" #include "tool_main.h" -#include -#include /* keep this as LAST include */ +#include "tool_msgs.h" +#include "memdebug.h" /* keep this as LAST include */ -void config_init(struct OperationConfig *config) +static struct GlobalConfig globalconf; +struct GlobalConfig *global; + +struct OperationConfig *config_alloc(void) { - memset(config, 0, sizeof(struct OperationConfig)); + struct OperationConfig *config = + calloc(1, sizeof(struct OperationConfig)); + if(!config) + return NULL; config->use_httpget = FALSE; config->create_dirs = FALSE; @@ -46,7 +52,9 @@ void config_init(struct OperationConfig *config) config->ftp_skip_ip = TRUE; config->file_clobber_mode = CLOBBER_DEFAULT; config->upload_flags = CURLULFLAG_SEEN; + config->retry_delay_ms = RETRY_SLEEP_DEFAULT; curlx_dyn_init(&config->postdata, MAX_FILE2MEMORY); + return config; } static void free_config_fields(struct OperationConfig *config) @@ -198,3 +206,81 @@ void config_free(struct OperationConfig *config) last = prev; } } + +/* + * This is the main global constructor for the app. Call this before + * _any_ libcurl usage. If this fails, *NO* libcurl functions may be + * used, or havoc may be the result. + */ +CURLcode globalconf_init(void) +{ + CURLcode result = CURLE_OK; + global = &globalconf; + +#ifdef __DJGPP__ + /* stop stat() wasting time */ + _djstat_flags |= _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE; +#endif + + /* Initialise the global config */ + global->showerror = FALSE; /* show errors when silent */ + global->styled_output = TRUE; /* enable detection */ + global->parallel_max = PARALLEL_DEFAULT; + + /* Allocate the initial operate config */ + global->first = global->last = config_alloc(); + if(global->first) { + /* Perform the libcurl initialization */ + result = curl_global_init(CURL_GLOBAL_DEFAULT); + if(!result) { + /* Get information about libcurl */ + result = get_libcurl_info(); + + if(result) { + errorf("error retrieving curl library information"); + free(global->first); + } + } + else { + errorf("error initializing curl library"); + free(global->first); + } + } + else { + errorf("error initializing curl"); + result = CURLE_FAILED_INIT; + } + + return result; +} + +static void free_globalconfig(void) +{ + tool_safefree(global->trace_dump); + + if(global->trace_fopened && global->trace_stream) + fclose(global->trace_stream); + global->trace_stream = NULL; + + tool_safefree(global->libcurl); +#if defined(_WIN32) && !defined(UNDER_CE) + free(global->term.buf); +#endif +} + +/* + * This is the main global destructor for the app. Call this after _all_ + * libcurl usage is done. + */ +void globalconf_free(void) +{ + /* Cleanup the easy handle */ + /* Main cleanup */ + curl_global_cleanup(); + free_globalconfig(); + + /* Free the OperationConfig structures */ + config_free(global->last); + global->first = NULL; + global->last = NULL; +} diff --git a/vendor/curl/src/tool_cfgable.h b/vendor/curl/src/tool_cfgable.h index c4f1d6b2344..23e874f448e 100644 --- a/vendor/curl/src/tool_cfgable.h +++ b/vendor/curl/src/tool_cfgable.h @@ -62,24 +62,21 @@ #define tool_safefree(ptr) \ do { free((ptr)); (ptr) = NULL;} while(0) -struct GlobalConfig; +extern struct GlobalConfig *global; struct State { struct getout *urlnode; - struct URLGlob *inglob; - struct URLGlob *urls; - char *outfiles; + struct URLGlob inglob; + struct URLGlob urlglob; char *httpgetfields; char *uploadfile; - curl_off_t infilenum; /* number of files to upload */ - curl_off_t up; /* upload file counter within a single upload glob */ - curl_off_t urlnum; /* how many iterations this single URL has with ranges - etc */ - curl_off_t li; + curl_off_t upnum; /* number of files to upload */ + curl_off_t upidx; /* index for upload glob */ + curl_off_t urlnum; /* how many iterations this URL has with ranges etc */ + curl_off_t urlidx; /* index for globbed URLs */ }; struct OperationConfig { - struct State state; /* for create_transfer() */ struct dynbuf postdata; char *useragent; struct curl_slist *cookies; /* cookies to serialize into a single line */ @@ -189,7 +186,6 @@ struct OperationConfig { char *ech; /* Config set by --ech keywords */ char *ech_config; /* Config set by "--ech esl:" option */ char *ech_public; /* Config set by "--ech pn:" option */ - struct GlobalConfig *global; struct OperationConfig *prev; struct OperationConfig *next; /* Always last in the struct */ curl_off_t condtime; @@ -197,8 +193,6 @@ struct OperationConfig { curl_off_t sendpersecond; /* send to peer */ curl_off_t recvpersecond; /* receive from peer */ - long ssl_version; - long ssl_version_max; long proxy_ssl_version; long ip_version; long create_file_mode; /* CURLOPT_NEW_FILE_PERMS */ @@ -215,8 +209,8 @@ struct OperationConfig { long httpversion; unsigned long socks5_auth;/* auth bitmask for socks5 proxies */ long req_retry; /* number of retries */ - long retry_delay; /* delay between retries (in seconds) */ - long retry_maxtime; /* maximum time to keep retrying */ + long retry_delay_ms; /* delay between retries (in milliseconds) */ + long retry_maxtime_ms; /* maximum time to keep retrying */ unsigned long mime_options; /* Mime option flags. */ long tftp_blksize; /* TFTP BLKSIZE option */ @@ -227,10 +221,11 @@ struct OperationConfig { long happy_eyeballs_timeout_ms; /* happy eyeballs timeout in milliseconds. 0 is valid. default: CURL_HET_DEFAULT. */ unsigned long timecond; + long followlocation; /* follow http redirects mode */ HttpReq httpreq; long proxyver; /* set to CURLPROXY_HTTP* define */ - int ftp_ssl_ccc_mode; - int ftp_filemethod; + long ftp_ssl_ccc_mode; + long ftp_filemethod; enum { CLOBBER_DEFAULT, /* Provides compatibility with previous versions of curl, by using the default behavior for -o, -O, and -J. @@ -242,6 +237,8 @@ struct OperationConfig { } file_clobber_mode; unsigned char upload_flags; /* Bitmask for --upload-flags */ unsigned short porttouse; + unsigned char ssl_version; /* 0 - 4, 0 being default */ + unsigned char ssl_version_max; /* 0 - 4, 0 being default */ BIT(remote_name_all); /* --remote-name-all */ BIT(remote_time); BIT(cookiesession); /* new session? */ @@ -265,7 +262,6 @@ struct OperationConfig { BIT(show_headers); /* show headers to data output */ BIT(no_body); /* do not get the body */ BIT(dirlistonly); /* only get the FTP dir list */ - BIT(followlocation); /* follow http redirects */ BIT(unrestricted_auth); /* Continue to send authentication (user+password) when following redirects, even when hostname changed */ @@ -330,7 +326,6 @@ struct OperationConfig { BIT(proxy_ssl_auto_client_cert); /* proxy version of ssl_auto_client_cert */ BIT(noalpn); /* enable/disable TLS ALPN extension */ BIT(abstract_unix_socket); /* path to an abstract Unix domain socket */ - BIT(falsestart); BIT(path_as_is); BIT(suppress_connect_headers); /* suppress proxy CONNECT response headers from user callbacks */ @@ -344,7 +339,15 @@ struct OperationConfig { BIT(skip_existing); }; +#if defined(_WIN32) && !defined(UNDER_CE) +struct termout { + wchar_t *buf; + DWORD len; +}; +#endif + struct GlobalConfig { + struct State state; /* for create_transfer() */ char *trace_dump; /* file to dump the network trace to */ FILE *trace_stream; char *libcurl; /* Output libcurl code to this filename */ @@ -355,10 +358,14 @@ struct GlobalConfig { struct OperationConfig *first; struct OperationConfig *current; struct OperationConfig *last; +#if defined(_WIN32) && !defined(UNDER_CE) + struct termout term; +#endif timediff_t ms_per_transfer; /* start next transfer after (at least) this many milliseconds */ trace tracetype; int progressmode; /* CURL_PROGRESS_BAR / CURL_PROGRESS_STATS */ + unsigned short parallel_host; /* MAX_PARALLEL_HOST is the maximum */ unsigned short parallel_max; /* MAX_PARALLEL is the maximum */ unsigned char verbosity; /* How verbose we should be */ #ifdef DEBUGBUILD @@ -378,7 +385,9 @@ struct GlobalConfig { BIT(isatty); /* Updated internally if output is a tty */ }; -void config_init(struct OperationConfig *config); +struct OperationConfig *config_alloc(void); void config_free(struct OperationConfig *config); +CURLcode globalconf_init(void); +void globalconf_free(void); #endif /* HEADER_CURL_TOOL_CFGABLE_H */ diff --git a/vendor/curl/src/tool_dirhie.c b/vendor/curl/src/tool_dirhie.c index 88e4daffb7b..91cc1b60cbd 100644 --- a/vendor/curl/src/tool_dirhie.c +++ b/vendor/curl/src/tool_dirhie.c @@ -23,59 +23,55 @@ ***************************************************************************/ #include "tool_setup.h" -#include - #if defined(_WIN32) && !defined(UNDER_CE) # include #endif -#include - #include "tool_dirhie.h" #include "tool_msgs.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ #if defined(_WIN32) || (defined(MSDOS) && !defined(__DJGPP__)) # define mkdir(x,y) (mkdir)((x)) # ifndef F_OK -# define F_OK 0 +# define F_OK 0 # endif #endif -static void show_dir_errno(struct GlobalConfig *global, const char *name) +static void show_dir_errno(const char *name) { switch(errno) { #ifdef EACCES /* !checksrc! disable ERRNOVAR 1 */ case EACCES: - errorf(global, "You do not have permission to create %s", name); + errorf("You do not have permission to create %s", name); break; #endif #ifdef ENAMETOOLONG case ENAMETOOLONG: - errorf(global, "The directory name %s is too long", name); + errorf("The directory name %s is too long", name); break; #endif #ifdef EROFS case EROFS: - errorf(global, "%s resides on a read-only file system", name); + errorf("%s resides on a read-only file system", name); break; #endif #ifdef ENOSPC case ENOSPC: - errorf(global, "No space left on the file system that will " + errorf("No space left on the file system that will " "contain the directory %s", name); break; #endif #ifdef EDQUOT case EDQUOT: - errorf(global, "Cannot create directory %s because you " + errorf("Cannot create directory %s because you " "exceeded your quota", name); break; #endif default: - errorf(global, "Error creating directory %s", name); + errorf("Error creating directory %s", name); break; } } @@ -94,7 +90,7 @@ static void show_dir_errno(struct GlobalConfig *global, const char *name) #define PATH_DELIMITERS DIR_CHAR #endif -CURLcode create_dir_hierarchy(const char *outfile, struct GlobalConfig *global) +CURLcode create_dir_hierarchy(const char *outfile) { CURLcode result = CURLE_OK; size_t outlen = strlen(outfile); @@ -130,9 +126,9 @@ CURLcode create_dir_hierarchy(const char *outfile, struct GlobalConfig *global) /* Create directory. Ignore access denied error to allow traversal. */ /* !checksrc! disable ERRNOVAR 1 */ - if(!skip && (-1 == mkdir(curlx_dyn_ptr(&dirbuf), (mode_t)0000750)) && + if(!skip && (mkdir(curlx_dyn_ptr(&dirbuf), (mode_t)0000750) == -1) && (errno != EACCES) && (errno != EEXIST)) { - show_dir_errno(global, curlx_dyn_ptr(&dirbuf)); + show_dir_errno(curlx_dyn_ptr(&dirbuf)); result = CURLE_WRITE_ERROR; break; /* get out of loop */ } diff --git a/vendor/curl/src/tool_dirhie.h b/vendor/curl/src/tool_dirhie.h index 0ee407fe54f..cb59208d9f3 100644 --- a/vendor/curl/src/tool_dirhie.h +++ b/vendor/curl/src/tool_dirhie.h @@ -26,7 +26,6 @@ #include "tool_setup.h" #include "tool_cfgable.h" -CURLcode create_dir_hierarchy(const char *outfile, - struct GlobalConfig *global); +CURLcode create_dir_hierarchy(const char *outfileo); #endif /* HEADER_CURL_TOOL_DIRHIE_H */ diff --git a/vendor/curl/src/tool_doswin.c b/vendor/curl/src/tool_doswin.c index 46993e43c71..23233bc2d19 100644 --- a/vendor/curl/src/tool_doswin.c +++ b/vendor/curl/src/tool_doswin.c @@ -38,9 +38,9 @@ #include "tool_bname.h" #include "tool_doswin.h" +#include "tool_msgs.h" -#include -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ #ifdef _WIN32 # undef PATH_MAX @@ -741,6 +741,217 @@ CURLcode win32_init(void) return CURLE_OK; } +#if !defined(CURL_WINDOWS_UWP) && !defined(UNDER_CE) +/* The following STDIN non - blocking read techniques are heavily inspired + by nmap and ncat (https://nmap.org/ncat/) */ +struct win_thread_data { + /* This is a copy of the true stdin file handle before any redirection. It is + read by the thread. */ + HANDLE stdin_handle; + /* This is the listen socket for the thread. It is closed after the first + connection. */ + curl_socket_t socket_l; +}; + +static DWORD WINAPI win_stdin_thread_func(void *thread_data) +{ + struct win_thread_data *tdata = (struct win_thread_data *)thread_data; + DWORD n; + int nwritten; + char buffer[BUFSIZ]; + BOOL r; + + SOCKADDR_IN clientAddr; + int clientAddrLen = sizeof(clientAddr); + + curl_socket_t socket_w = accept(tdata->socket_l, (SOCKADDR*)&clientAddr, + &clientAddrLen); + + if(socket_w == CURL_SOCKET_BAD) { + errorf("accept error: %08lx", GetLastError()); + goto ThreadCleanup; + } + + closesocket(tdata->socket_l); /* sclose here fails test 1498 */ + tdata->socket_l = CURL_SOCKET_BAD; + if(shutdown(socket_w, SD_RECEIVE) == SOCKET_ERROR) { + errorf("shutdown error: %08lx", GetLastError()); + goto ThreadCleanup; + } + for(;;) { + r = ReadFile(tdata->stdin_handle, buffer, sizeof(buffer), &n, NULL); + if(r == 0) + break; + if(n == 0) + break; + nwritten = send(socket_w, buffer, n, 0); + if(nwritten == SOCKET_ERROR) + break; + if((DWORD)nwritten != n) + break; + } +ThreadCleanup: + CloseHandle(tdata->stdin_handle); + tdata->stdin_handle = NULL; + if(tdata->socket_l != CURL_SOCKET_BAD) { + sclose(tdata->socket_l); + tdata->socket_l = CURL_SOCKET_BAD; + } + if(socket_w != CURL_SOCKET_BAD) + sclose(socket_w); + + if(tdata) { + free(tdata); + } + + return 0; +} + +/* The background thread that reads and buffers the true stdin. */ +static HANDLE stdin_thread = NULL; +static curl_socket_t socket_r = CURL_SOCKET_BAD; + +curl_socket_t win32_stdin_read_thread(void) +{ + int result; + bool r; + int rc = 0, socksize = 0; + struct win_thread_data *tdata = NULL; + SOCKADDR_IN selfaddr; + + if(socket_r != CURL_SOCKET_BAD) { + assert(stdin_thread != NULL); + return socket_r; + } + assert(stdin_thread == NULL); + + do { + /* Prepare handles for thread */ + tdata = (struct win_thread_data*)calloc(1, sizeof(struct win_thread_data)); + if(!tdata) { + errorf("calloc() error"); + break; + } + /* Create the listening socket for the thread. When it starts, it will + * accept our connection and begin writing STDIN data to the connection. */ + tdata->socket_l = WSASocketW(AF_INET, SOCK_STREAM, + IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); + + if(tdata->socket_l == CURL_SOCKET_BAD) { + errorf("WSASocketW error: %08lx", GetLastError()); + break; + } + + socksize = sizeof(selfaddr); + memset(&selfaddr, 0, socksize); + selfaddr.sin_family = AF_INET; + selfaddr.sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK); + /* Bind to any available loopback port */ + result = bind(tdata->socket_l, (SOCKADDR*)&selfaddr, socksize); + if(result == SOCKET_ERROR) { + errorf("bind error: %08lx", GetLastError()); + break; + } + + /* Bind to any available loopback port */ + result = getsockname(tdata->socket_l, (SOCKADDR*)&selfaddr, &socksize); + if(result == SOCKET_ERROR) { + errorf("getsockname error: %08lx", GetLastError()); + break; + } + + result = listen(tdata->socket_l, 1); + if(result == SOCKET_ERROR) { + errorf("listen error: %08lx", GetLastError()); + break; + } + + /* Make a copy of the stdin handle to be used by win_stdin_thread_func */ + r = DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE), + GetCurrentProcess(), &tdata->stdin_handle, + 0, FALSE, DUPLICATE_SAME_ACCESS); + + if(!r) { + errorf("DuplicateHandle error: %08lx", GetLastError()); + break; + } + + /* Start up the thread. We don't bother keeping a reference to it + because it runs until program termination. From here on out all reads + from the stdin handle or file descriptor 0 will be reading from the + socket that is fed by the thread. */ + stdin_thread = CreateThread(NULL, 0, win_stdin_thread_func, + tdata, 0, NULL); + if(!stdin_thread) { + errorf("CreateThread error: %08lx", GetLastError()); + break; + } + + /* Connect to the thread and rearrange our own STDIN handles */ + socket_r = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if(socket_r == CURL_SOCKET_BAD) { + errorf("socket error: %08lx", GetLastError()); + break; + } + + /* Hard close the socket on closesocket() */ + setsockopt(socket_r, SOL_SOCKET, SO_DONTLINGER, 0, 0); + + if(connect(socket_r, (SOCKADDR*)&selfaddr, socksize) == SOCKET_ERROR) { + errorf("connect error: %08lx", GetLastError()); + break; + } + + if(shutdown(socket_r, SD_SEND) == SOCKET_ERROR) { + errorf("shutdown error: %08lx", GetLastError()); + break; + } + + /* Set the stdin handle to read from the socket. */ + if(SetStdHandle(STD_INPUT_HANDLE, (HANDLE)socket_r) == 0) { + errorf("SetStdHandle error: %08lx", GetLastError()); + break; + } + + rc = 1; + } while(0); + + if(rc != 1) { + if(socket_r != CURL_SOCKET_BAD && tdata) { + if(GetStdHandle(STD_INPUT_HANDLE) == (HANDLE)socket_r && + tdata->stdin_handle) { + /* restore STDIN */ + SetStdHandle(STD_INPUT_HANDLE, tdata->stdin_handle); + tdata->stdin_handle = NULL; + } + + sclose(socket_r); + socket_r = CURL_SOCKET_BAD; + } + + if(stdin_thread) { + TerminateThread(stdin_thread, 1); + stdin_thread = NULL; + } + + if(tdata) { + if(tdata->stdin_handle) + CloseHandle(tdata->stdin_handle); + if(tdata->socket_l != CURL_SOCKET_BAD) + sclose(tdata->socket_l); + + free(tdata); + } + + return CURL_SOCKET_BAD; + } + + assert(socket_r != CURL_SOCKET_BAD); + return socket_r; +} + +#endif /* !CURL_WINDOWS_UWP && !UNDER_CE */ + #endif /* _WIN32 */ #endif /* _WIN32 || MSDOS */ diff --git a/vendor/curl/src/tool_doswin.h b/vendor/curl/src/tool_doswin.h index 1e9656f30f9..7fe5260476e 100644 --- a/vendor/curl/src/tool_doswin.h +++ b/vendor/curl/src/tool_doswin.h @@ -55,6 +55,10 @@ CURLcode FindWin32CACert(struct OperationConfig *config, struct curl_slist *GetLoadedModulePaths(void); CURLcode win32_init(void); +#if !defined(CURL_WINDOWS_UWP) && !defined(UNDER_CE) +curl_socket_t win32_stdin_read_thread(void); +#endif /* !CURL_WINDOWS_UWP && !UNDER_CE */ + #endif /* _WIN32 */ #endif /* _WIN32 || MSDOS */ diff --git a/vendor/curl/src/tool_easysrc.c b/vendor/curl/src/tool_easysrc.c index fa264606fc5..223c66bdf50 100644 --- a/vendor/curl/src/tool_easysrc.c +++ b/vendor/curl/src/tool_easysrc.c @@ -27,13 +27,11 @@ #ifndef CURL_DISABLE_LIBCURL_OPTION -#include - #include "tool_cfgable.h" #include "tool_easysrc.h" #include "tool_msgs.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ /* global variable definitions, for easy-interface source code generation */ @@ -172,10 +170,10 @@ CURLcode easysrc_cleanup(void) return ret; } -void dumpeasysrc(struct GlobalConfig *config) +void dumpeasysrc(void) { struct curl_slist *ptr; - char *o = config->libcurl; + char *o = global->libcurl; FILE *out; bool fopened = FALSE; @@ -186,7 +184,7 @@ void dumpeasysrc(struct GlobalConfig *config) else out = stdout; if(!out) - warnf(config, "Failed to open %s to write libcurl code", o); + warnf("Failed to open %s to write libcurl code", o); else { int i; const char *c; diff --git a/vendor/curl/src/tool_easysrc.h b/vendor/curl/src/tool_easysrc.h index f698c8f5cc2..44d40b727a4 100644 --- a/vendor/curl/src/tool_easysrc.h +++ b/vendor/curl/src/tool_easysrc.h @@ -43,8 +43,7 @@ extern CURLcode easysrc_addf(struct slist_wc **plist, const char *fmt, ...) CURL_PRINTF(2, 3); extern CURLcode easysrc_perform(void); extern CURLcode easysrc_cleanup(void); - -void dumpeasysrc(struct GlobalConfig *config); +void dumpeasysrc(void); #else /* CURL_DISABLE_LIBCURL_OPTION is defined */ diff --git a/vendor/curl/src/tool_filetime.c b/vendor/curl/src/tool_filetime.c index 4946e68a396..8907bcda618 100644 --- a/vendor/curl/src/tool_filetime.c +++ b/vendor/curl/src/tool_filetime.c @@ -24,7 +24,6 @@ #include "tool_filetime.h" #include "tool_cfgable.h" #include "tool_msgs.h" -#include #ifdef HAVE_UTIME_H # include @@ -33,8 +32,7 @@ #endif /* Returns 0 on success, non-zero on file problems */ -int getfiletime(const char *filename, struct GlobalConfig *global, - curl_off_t *stamp) +int getfiletime(const char *filename, curl_off_t *stamp) { int rc = 1; @@ -46,9 +44,9 @@ int getfiletime(const char *filename, struct GlobalConfig *global, TCHAR *tchar_filename = curlx_convert_UTF8_to_tchar(filename); hfile = CreateFile(tchar_filename, FILE_READ_ATTRIBUTES, - (FILE_SHARE_READ | FILE_SHARE_WRITE | - FILE_SHARE_DELETE), - NULL, OPEN_EXISTING, 0, NULL); + (FILE_SHARE_READ | FILE_SHARE_WRITE | + FILE_SHARE_DELETE), + NULL, OPEN_EXISTING, 0, NULL); curlx_unicodefree(tchar_filename); if(hfile != INVALID_HANDLE_VALUE) { FILETIME ft; @@ -56,40 +54,39 @@ int getfiletime(const char *filename, struct GlobalConfig *global, curl_off_t converted = (curl_off_t)ft.dwLowDateTime | ((curl_off_t)ft.dwHighDateTime) << 32; - if(converted < CURL_OFF_T_C(116444736000000000)) - warnf(global, "Failed to get filetime: underflow"); + if(converted < 116444736000000000) + warnf("Failed to get filetime: underflow"); else { - *stamp = (converted - CURL_OFF_T_C(116444736000000000)) / 10000000; + *stamp = (converted - 116444736000000000) / 10000000; rc = 0; } } else { - warnf(global, "Failed to get filetime: " + warnf("Failed to get filetime: " "GetFileTime failed: GetLastError %u", (unsigned int)GetLastError()); } CloseHandle(hfile); } else if(GetLastError() != ERROR_FILE_NOT_FOUND) { - warnf(global, "Failed to get filetime: " + warnf("Failed to get filetime: " "CreateFile failed: GetLastError %u", (unsigned int)GetLastError()); } #else struct_stat statbuf; - if(-1 != stat(filename, &statbuf)) { + if(stat(filename, &statbuf) != -1) { *stamp = (curl_off_t)statbuf.st_mtime; rc = 0; } else - warnf(global, "Failed to get filetime: %s", strerror(errno)); + warnf("Failed to get filetime: %s", strerror(errno)); #endif return rc; } #if defined(HAVE_UTIME) || defined(HAVE_UTIMES) || defined(_WIN32) -void setfiletime(curl_off_t filetime, const char *filename, - struct GlobalConfig *global) +void setfiletime(curl_off_t filetime, const char *filename) { if(filetime >= 0) { /* Windows utime() may attempt to adjust the Unix GMT file time by a daylight @@ -101,8 +98,8 @@ void setfiletime(curl_off_t filetime, const char *filename, /* 910670515199 is the maximum Unix filetime that can be used as a Windows FILETIME without overflow: 30827-12-31T23:59:59. */ - if(filetime > CURL_OFF_T_C(910670515199)) { - warnf(global, "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T + if(filetime > 910670515199) { + warnf("Failed to set filetime %" CURL_FORMAT_CURL_OFF_T " on outfile: overflow", filetime); curlx_unicodefree(tchar_filename); return; @@ -115,19 +112,19 @@ void setfiletime(curl_off_t filetime, const char *filename, curlx_unicodefree(tchar_filename); if(hfile != INVALID_HANDLE_VALUE) { curl_off_t converted = ((curl_off_t)filetime * 10000000) + - CURL_OFF_T_C(116444736000000000); + 116444736000000000; FILETIME ft; ft.dwLowDateTime = (DWORD)(converted & 0xFFFFFFFF); ft.dwHighDateTime = (DWORD)(converted >> 32); if(!SetFileTime(hfile, NULL, &ft, &ft)) { - warnf(global, "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T + warnf("Failed to set filetime %" CURL_FORMAT_CURL_OFF_T " on outfile: SetFileTime failed: GetLastError %u", filetime, (unsigned int)GetLastError()); } CloseHandle(hfile); } else { - warnf(global, "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T + warnf("Failed to set filetime %" CURL_FORMAT_CURL_OFF_T " on outfile: CreateFile failed: GetLastError %u", filetime, (unsigned int)GetLastError()); } @@ -137,7 +134,7 @@ void setfiletime(curl_off_t filetime, const char *filename, times[0].tv_sec = times[1].tv_sec = (time_t)filetime; times[0].tv_usec = times[1].tv_usec = 0; if(utimes(filename, times)) { - warnf(global, "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T + warnf("Failed to set filetime %" CURL_FORMAT_CURL_OFF_T " on '%s': %s", filetime, filename, strerror(errno)); } @@ -146,11 +143,10 @@ void setfiletime(curl_off_t filetime, const char *filename, times.actime = (time_t)filetime; times.modtime = (time_t)filetime; if(utime(filename, ×)) { - warnf(global, "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T + warnf("Failed to set filetime %" CURL_FORMAT_CURL_OFF_T " on '%s': %s", filetime, filename, strerror(errno)); } #endif } } -#endif /* defined(HAVE_UTIME) || defined(HAVE_UTIMES) || \ - defined(_WIN32) */ +#endif /* HAVE_UTIME || HAVE_UTIMES || _WIN32 */ diff --git a/vendor/curl/src/tool_filetime.h b/vendor/curl/src/tool_filetime.h index 4830b218c31..c3663617b53 100644 --- a/vendor/curl/src/tool_filetime.h +++ b/vendor/curl/src/tool_filetime.h @@ -25,18 +25,13 @@ ***************************************************************************/ #include "tool_setup.h" -struct GlobalConfig; +int getfiletime(const char *filename, curl_off_t *stamp); -int getfiletime(const char *filename, struct GlobalConfig *global, - curl_off_t *stamp); - -#if defined(HAVE_UTIME) || defined(HAVE_UTIMES) || \ +#if defined(HAVE_UTIME) || defined(HAVE_UTIMES) || \ (defined(_WIN32) && (SIZEOF_CURL_OFF_T >= 8)) -void setfiletime(curl_off_t filetime, const char *filename, - struct GlobalConfig *global); +void setfiletime(curl_off_t filetime, const char *filename); #else #define setfiletime(a,b,c) tool_nop_stmt -#endif /* defined(HAVE_UTIME) || defined(HAVE_UTIMES) || \ - (defined(_WIN32) && (SIZEOF_CURL_OFF_T >= 8)) */ +#endif #endif /* HEADER_CURL_TOOL_FILETIME_H */ diff --git a/vendor/curl/src/tool_findfile.c b/vendor/curl/src/tool_findfile.c index 02bdefea874..72868f4b4f7 100644 --- a/vendor/curl/src/tool_findfile.c +++ b/vendor/curl/src/tool_findfile.c @@ -29,19 +29,14 @@ #define __NO_NET_API #endif -#ifdef HAVE_SYS_STAT_H -#include -#endif #ifdef HAVE_FCNTL_H #include #endif -#include - #include "tool_findfile.h" #include "tool_cfgable.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ struct finder { const char *env; diff --git a/vendor/curl/src/tool_formparse.c b/vendor/curl/src/tool_formparse.c index 2273b69dd30..b5ab10a00f8 100644 --- a/vendor/curl/src/tool_formparse.c +++ b/vendor/curl/src/tool_formparse.c @@ -23,16 +23,13 @@ ***************************************************************************/ #include "tool_setup.h" -#include - #include "tool_cfgable.h" #include "tool_msgs.h" -#include "tool_binmode.h" #include "tool_getparam.h" #include "tool_paramhlp.h" #include "tool_formparse.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ /* tool_mime functions. */ static struct tool_mime *tool_mime_new(struct tool_mime *parent, @@ -133,7 +130,7 @@ static struct tool_mime *tool_mime_new_filedata(struct tool_mime *parent, curl_off_t origin; struct_stat sbuf; - CURL_SET_BINMODE(stdin); + CURLX_SET_BINMODE(stdin); origin = ftell(stdin); /* If stdin is a regular file, do not buffer data but read it when needed. */ @@ -207,7 +204,7 @@ size_t tool_mime_stdin_read(char *buffer, { struct tool_mime *sip = (struct tool_mime *) arg; curl_off_t bytesleft; - (void) size; /* Always 1: ignored. */ + (void)size; /* Always 1: ignored. */ if(sip->size >= 0) { if(sip->curpos >= sip->size) @@ -226,10 +223,7 @@ size_t tool_mime_stdin_read(char *buffer, nitems = fread(buffer, 1, nitems, stdin); if(ferror(stdin)) { /* Show error only once. */ - if(sip->config) { - warnf(sip->config, "stdin: %s", strerror(errno)); - sip->config = NULL; - } + warnf("stdin: %s", strerror(errno)); return CURL_READFUNC_ABORT; } } @@ -348,11 +342,10 @@ CURLcode tool2curlmime(CURL *curl, struct tool_mime *m, curl_mime **mime) /* * helper function to get a word from form param - * after call get_parm_word, str either point to string end + * after call get_param_word, str either point to string end * or point to any of end chars. */ -static char *get_param_word(struct OperationConfig *config, char **str, - char **end_pos, char endchar) +static char *get_param_word(char **str, char **end_pos, char endchar) { char *ptr = *str; /* the first non-space char is here */ @@ -394,7 +387,7 @@ static char *get_param_word(struct OperationConfig *config, char **str, ++ptr; } if(trailing_data) - warnf(config->global, "Trailing data after quoted form parameter"); + warnf("Trailing data after quoted form parameter"); *str = ptr; return word_begin + 1; } @@ -423,8 +416,7 @@ static int slist_append(struct curl_slist **plist, const char *data) } /* Read headers from a file and append to list. */ -static int read_field_headers(struct OperationConfig *config, - const char *filename, FILE *fp, +static int read_field_headers(const char *filename, FILE *fp, struct curl_slist **pheaders) { size_t hdrlen = 0; @@ -442,7 +434,7 @@ static int read_field_headers(struct OperationConfig *config, if(hdrlen) { hdrbuf[hdrlen] = '\0'; if(slist_append(pheaders, hdrbuf)) { - errorf(config->global, "Out of memory for field headers"); + errorf("Out of memory for field headers"); return -1; } hdrlen = 0; @@ -452,7 +444,7 @@ static int read_field_headers(struct OperationConfig *config, switch(c) { case EOF: if(ferror(fp)) { - errorf(config->global, "Header file %s read error: %s", filename, + errorf("Header file %s read error: %s", filename, strerror(errno)); return -1; } @@ -473,7 +465,7 @@ static int read_field_headers(struct OperationConfig *config, pos++; if(!incomment) { if(hdrlen == sizeof(hdrbuf) - 1) { - warnf(config->global, "File %s line %d: header too long (truncated)", + warnf("File %s line %d: header too long (truncated)", filename, lineno); c = ' '; } @@ -484,7 +476,7 @@ static int read_field_headers(struct OperationConfig *config, /* NOTREACHED */ } -static int get_param_part(struct OperationConfig *config, char endchar, +static int get_param_part(char endchar, char **str, char **pdata, char **ptype, char **pfilename, char **pencoder, struct curl_slist **pheaders) @@ -510,7 +502,7 @@ static int get_param_part(struct OperationConfig *config, char endchar, while(ISBLANK(*p)) p++; tp = p; - *pdata = get_param_word(config, &p, &endpos, endchar); + *pdata = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(*pdata == tp) while(endpos > *pdata && ISBLANK(endpos[-1])) @@ -542,7 +534,7 @@ static int get_param_part(struct OperationConfig *config, char endchar, for(p += 9; ISBLANK(*p); p++) ; tp = p; - filename = get_param_word(config, &p, &endpos, endchar); + filename = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(filename == tp) while(endpos > filename && ISBLANK(endpos[-1])) @@ -564,7 +556,7 @@ static int get_param_part(struct OperationConfig *config, char endchar, p++; } while(ISBLANK(*p)); tp = p; - hdrfile = get_param_word(config, &p, &endpos, endchar); + hdrfile = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(hdrfile == tp) while(endpos > hdrfile && ISBLANK(endpos[-1])) @@ -573,10 +565,10 @@ static int get_param_part(struct OperationConfig *config, char endchar, *endpos = '\0'; fp = fopen(hdrfile, FOPEN_READTEXT); if(!fp) - warnf(config->global, "Cannot read from %s: %s", hdrfile, + warnf("Cannot read from %s: %s", hdrfile, strerror(errno)); else { - int i = read_field_headers(config, hdrfile, fp, &headers); + int i = read_field_headers(hdrfile, fp, &headers); fclose(fp); if(i) { @@ -591,7 +583,7 @@ static int get_param_part(struct OperationConfig *config, char endchar, while(ISBLANK(*p)) p++; tp = p; - hdr = get_param_word(config, &p, &endpos, endchar); + hdr = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(hdr == tp) while(endpos > hdr && ISBLANK(endpos[-1])) @@ -599,7 +591,7 @@ static int get_param_part(struct OperationConfig *config, char endchar, sep = *p; *endpos = '\0'; if(slist_append(&headers, hdr)) { - errorf(config->global, "Out of memory for field header"); + errorf("Out of memory for field header"); curl_slist_free_all(headers); return -1; } @@ -613,7 +605,7 @@ static int get_param_part(struct OperationConfig *config, char endchar, for(p += 8; ISBLANK(*p); p++) ; tp = p; - encoder = get_param_word(config, &p, &endpos, endchar); + encoder = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(encoder == tp) while(endpos > encoder && ISSPACE(endpos[-1])) @@ -630,12 +622,12 @@ static int get_param_part(struct OperationConfig *config, char endchar, } else { /* unknown prefix, skip to next block */ - char *unknown = get_param_word(config, &p, &endpos, endchar); + char *unknown = get_param_word(&p, &endpos, endchar); sep = *p; *endpos = '\0'; if(*unknown) - warnf(config->global, "skip unknown form field: %s", unknown); + warnf("skip unknown form field: %s", unknown); } } @@ -646,25 +638,22 @@ static int get_param_part(struct OperationConfig *config, char endchar, if(ptype) *ptype = type; else if(type) - warnf(config->global, "Field content type not allowed here: %s", type); + warnf("Field content type not allowed here: %s", type); if(pfilename) *pfilename = filename; else if(filename) - warnf(config->global, - "Field filename not allowed here: %s", filename); + warnf("Field filename not allowed here: %s", filename); if(pencoder) *pencoder = encoder; else if(encoder) - warnf(config->global, - "Field encoder not allowed here: %s", encoder); + warnf("Field encoder not allowed here: %s", encoder); if(pheaders) *pheaders = headers; else if(headers) { - warnf(config->global, - "Field headers not allowed here: %s", headers->data); + warnf("Field headers not allowed here: %s", headers->data); curl_slist_free_all(headers); } @@ -729,8 +718,7 @@ static int get_param_part(struct OperationConfig *config, char endchar, } \ } while(0) -int formparse(struct OperationConfig *config, - const char *input, +int formparse(const char *input, struct tool_mime **mimeroot, struct tool_mime **mimecurrent, bool literal_value) @@ -772,8 +760,7 @@ int formparse(struct OperationConfig *config, if(*contp == '(' && !literal_value) { /* Starting a multipart. */ - sep = get_param_part(config, '\0', - &contp, &data, &type, NULL, NULL, &headers); + sep = get_param_part('\0', &contp, &data, &type, NULL, NULL, &headers); if(sep < 0) goto fail; part = tool_mime_new_parts(*mimecurrent); @@ -787,7 +774,7 @@ int formparse(struct OperationConfig *config, else if(!name && !strcmp(contp, ")") && !literal_value) { /* Ending a multipart. */ if(*mimecurrent == *mimeroot) { - warnf(config->global, "no multipart to terminate"); + warnf("no multipart to terminate"); goto fail; } *mimecurrent = (*mimecurrent)->parent; @@ -802,7 +789,7 @@ int formparse(struct OperationConfig *config, /* since this was a file, it may have a content-type specifier at the end too, or a filename. Or both. */ ++contp; - sep = get_param_part(config, ',', &contp, + sep = get_param_part(',', &contp, &data, &type, &filename, &encoder, &headers); if(sep < 0) { goto fail; @@ -826,14 +813,12 @@ int formparse(struct OperationConfig *config, goto fail; part->headers = headers; headers = NULL; - part->config = config->global; if(res == CURLE_READ_ERROR) { /* An error occurred while reading stdin: if read has started, issue the error now. Else, delay it until processed by libcurl. */ if(part->size > 0) { - warnf(config->global, - "error while reading standard input"); + warnf("error while reading standard input"); goto fail; } tool_safefree(part->data); @@ -851,7 +836,7 @@ int formparse(struct OperationConfig *config, else { if(*contp == '<' && !literal_value) { ++contp; - sep = get_param_part(config, '\0', &contp, + sep = get_param_part('\0', &contp, &data, &type, NULL, &encoder, &headers); if(sep < 0) goto fail; @@ -862,14 +847,12 @@ int formparse(struct OperationConfig *config, goto fail; part->headers = headers; headers = NULL; - part->config = config->global; if(res == CURLE_READ_ERROR) { /* An error occurred while reading stdin: if read has started, issue the error now. Else, delay it until processed by libcurl. */ if(part->size > 0) { - warnf(config->global, - "error while reading standard input"); + warnf("error while reading standard input"); goto fail; } tool_safefree(part->data); @@ -881,7 +864,7 @@ int formparse(struct OperationConfig *config, if(literal_value) data = contp; else { - sep = get_param_part(config, '\0', &contp, + sep = get_param_part('\0', &contp, &data, &type, &filename, &encoder, &headers); if(sep < 0) goto fail; @@ -900,8 +883,7 @@ int formparse(struct OperationConfig *config, if(sep) { *contp = (char) sep; - warnf(config->global, - "garbage at end of field specification: %s", contp); + warnf("garbage at end of field specification: %s", contp); } } @@ -909,7 +891,7 @@ int formparse(struct OperationConfig *config, SET_TOOL_MIME_PTR(part, name); } else { - warnf(config->global, "Illegally formatted input field"); + warnf("Illegally formatted input field"); goto fail; } err = 0; diff --git a/vendor/curl/src/tool_formparse.h b/vendor/curl/src/tool_formparse.h index 35d5c952d50..d2222330eef 100644 --- a/vendor/curl/src/tool_formparse.h +++ b/vendor/curl/src/tool_formparse.h @@ -55,15 +55,13 @@ struct tool_mime { curl_off_t origin; /* Stdin read origin offset. */ curl_off_t size; /* Stdin data size. */ curl_off_t curpos; /* Stdin current read position. */ - struct GlobalConfig *config; /* For access from callback. */ }; size_t tool_mime_stdin_read(char *buffer, size_t size, size_t nitems, void *arg); int tool_mime_stdin_seek(void *instream, curl_off_t offset, int whence); -int formparse(struct OperationConfig *config, - const char *input, +int formparse(const char *input, struct tool_mime **mimeroot, struct tool_mime **mimecurrent, bool literal_value); diff --git a/vendor/curl/src/tool_getparam.c b/vendor/curl/src/tool_getparam.c index 51156e46b97..475cbd4927e 100644 --- a/vendor/curl/src/tool_getparam.c +++ b/vendor/curl/src/tool_getparam.c @@ -23,8 +23,6 @@ ***************************************************************************/ #include "tool_setup.h" -#include -#include "tool_binmode.h" #include "tool_cfgable.h" #include "tool_cb_prg.h" #include "tool_filetime.h" @@ -40,7 +38,7 @@ #include "tool_help.h" #include "var.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ #define ALLOW_BLANK TRUE #define DENY_BLANK FALSE @@ -146,6 +144,7 @@ static const struct LongShort aliases[]= { {"fail-early", ARG_BOOL, ' ', C_FAIL_EARLY}, {"fail-with-body", ARG_BOOL, ' ', C_FAIL_WITH_BODY}, {"false-start", ARG_BOOL, ' ', C_FALSE_START}, + {"follow", ARG_BOOL, ' ', C_FOLLOW}, {"form", ARG_STRG, 'F', C_FORM}, {"form-escape", ARG_BOOL, ' ', C_FORM_ESCAPE}, {"form-string", ARG_STRG, ' ', C_FORM_STRING}, @@ -153,7 +152,7 @@ static const struct LongShort aliases[]= { {"ftp-alternative-to-user", ARG_STRG, ' ', C_FTP_ALTERNATIVE_TO_USER}, {"ftp-create-dirs", ARG_BOOL, ' ', C_FTP_CREATE_DIRS}, {"ftp-method", ARG_STRG, ' ', C_FTP_METHOD}, - {"ftp-pasv", ARG_BOOL, ' ', C_FTP_PASV}, + {"ftp-pasv", ARG_NONE, ' ', C_FTP_PASV}, {"ftp-port", ARG_STRG, 'P', C_FTP_PORT}, {"ftp-pret", ARG_BOOL, ' ', C_FTP_PRET}, {"ftp-skip-pasv-ip", ARG_BOOL, ' ', C_FTP_SKIP_PASV_IP}, @@ -226,11 +225,13 @@ static const struct LongShort aliases[]= { {"ntlm", ARG_BOOL, ' ', C_NTLM}, {"ntlm-wb", ARG_BOOL|ARG_DEPR, ' ', C_NTLM_WB}, {"oauth2-bearer", ARG_STRG|ARG_CLEAR, ' ', C_OAUTH2_BEARER}, + {"out-null", ARG_BOOL, ' ', C_OUT_NULL}, {"output", ARG_FILE, 'o', C_OUTPUT}, {"output-dir", ARG_STRG, ' ', C_OUTPUT_DIR}, {"parallel", ARG_BOOL, 'Z', C_PARALLEL}, {"parallel-immediate", ARG_BOOL, ' ', C_PARALLEL_IMMEDIATE}, {"parallel-max", ARG_STRG, ' ', C_PARALLEL_MAX}, + {"parallel-max-host", ARG_STRG, ' ', C_PARALLEL_HOST}, {"pass", ARG_STRG|ARG_CLEAR, ' ', C_PASS}, {"path-as-is", ARG_BOOL, ' ', C_PATH_AS_IS}, {"pinnedpubkey", ARG_STRG|ARG_TLS, ' ', C_PINNEDPUBKEY}, @@ -522,8 +523,7 @@ GetFileAndPassword(const char *nextarg, char **file, char **password) /* Get a size parameter for '--limit-rate' or '--max-filesize'. * We support a 'G', 'M' or 'K' suffix too. */ -static ParameterError GetSizeParameter(struct GlobalConfig *global, - const char *arg, +static ParameterError GetSizeParameter(const char *arg, const char *which, curl_off_t *value_out) { @@ -531,7 +531,7 @@ static ParameterError GetSizeParameter(struct GlobalConfig *global, curl_off_t value; if(curlx_str_number(&unit, &value, CURL_OFF_T_MAX)) { - warnf(global, "invalid number specified for %s", which); + warnf("invalid number specified for %s", which); return PARAM_BAD_USE; } @@ -564,7 +564,7 @@ static ParameterError GetSizeParameter(struct GlobalConfig *global, /* for plain bytes, leave as-is */ break; default: - warnf(global, "unsupported %s unit. Use G, M, K or B", which); + warnf("unsupported %s unit. Use G, M, K or B", which); return PARAM_BAD_USE; } *value_out = value; @@ -590,8 +590,7 @@ static void cleanarg(char *str) #define MAX_DATAURLENCODE (500*1024*1024) /* --data-urlencode */ -static ParameterError data_urlencode(struct GlobalConfig *global, - const char *nextarg, +static ParameterError data_urlencode(const char *nextarg, char **postp, size_t *lenp) { @@ -625,12 +624,12 @@ static ParameterError data_urlencode(struct GlobalConfig *global, /* a '@' letter, it means that a filename or - (stdin) follows */ if(!strcmp("-", p)) { file = stdin; - CURL_SET_BINMODE(stdin); + CURLX_SET_BINMODE(stdin); } else { file = fopen(p, "rb"); if(!file) { - errorf(global, "Failed to open %s", p); + errorf("Failed to open %s", p); return PARAM_READ_ERROR; } } @@ -692,19 +691,17 @@ static ParameterError data_urlencode(struct GlobalConfig *global, return err; } -static void sethttpver(struct GlobalConfig *global, - struct OperationConfig *config, +static void sethttpver(struct OperationConfig *config, long httpversion) { if(config->httpversion && (config->httpversion != httpversion)) - warnf(global, "Overrides previous HTTP version option"); + warnf("Overrides previous HTTP version option"); config->httpversion = httpversion; } -static CURLcode set_trace_config(struct GlobalConfig *global, - const char *token) +static CURLcode set_trace_config(const char *token) { CURLcode result = CURLE_OK; const char *next, *name; @@ -843,7 +840,6 @@ static int find_tos(const void *a, const void *b) #define MAX_QUERY_LEN 100000 /* larger is not likely to ever work */ static ParameterError url_query(const char *nextarg, - struct GlobalConfig *global, struct OperationConfig *config) { size_t size = 0; @@ -859,7 +855,7 @@ static ParameterError url_query(const char *nextarg, err = PARAM_NO_MEM; } else - err = data_urlencode(global, nextarg, &query, &size); + err = data_urlencode(nextarg, &query, &size); if(!err) { if(config->query) { @@ -880,7 +876,6 @@ static ParameterError url_query(const char *nextarg, static ParameterError set_data(cmdline_t cmd, const char *nextarg, - struct GlobalConfig *global, struct OperationConfig *config) { char *postdata = NULL; @@ -889,7 +884,7 @@ static ParameterError set_data(cmdline_t cmd, ParameterError err = PARAM_OK; if(cmd == C_DATA_URLENCODE) { /* --data-urlencode */ - err = data_urlencode(global, nextarg, &postdata, &size); + err = data_urlencode(nextarg, &postdata, &size); if(err) return err; } @@ -901,12 +896,12 @@ static ParameterError set_data(cmdline_t cmd, if(!strcmp("-", nextarg)) { file = stdin; if(cmd == C_DATA_BINARY) /* forced data-binary */ - CURL_SET_BINMODE(stdin); + CURLX_SET_BINMODE(stdin); } else { file = fopen(nextarg, "rb"); if(!file) { - errorf(global, "Failed to open %s", nextarg); + errorf("Failed to open %s", nextarg); return PARAM_READ_ERROR; } } @@ -945,7 +940,7 @@ static ParameterError set_data(cmdline_t cmd, if(curlx_dyn_len(&config->postdata)) { /* skip separator append for --json */ - if(!err && (cmd != C_JSON) && + if(!err && (cmd != C_JSON) && curlx_dyn_addn(&config->postdata, "&", 1)) err = PARAM_NO_MEM; } @@ -959,8 +954,7 @@ static ParameterError set_data(cmdline_t cmd, return err; } -static ParameterError set_rate(struct GlobalConfig *global, - const char *nextarg) +static ParameterError set_rate(const char *nextarg) { /* --rate */ /* support a few different suffixes, extract the suffix first, then @@ -1008,14 +1002,14 @@ static ParameterError set_rate(struct GlobalConfig *global, numerator = 24*60*60*1000; break; default: - errorf(global, "unsupported --rate unit"); + errorf("unsupported --rate unit"); err = PARAM_BAD_USE; break; } if((LONG_MAX / numerator) < numunits) { /* overflow, too large number */ - errorf(global, "too large --rate unit"); + errorf("too large --rate unit"); err = PARAM_NUMBER_TOO_LARGE; } /* this typecast is okay based on the check above */ @@ -1041,8 +1035,7 @@ const struct LongShort *findlongopt(const char *opt) sizeof(aliases[0]), findarg); } -static ParameterError add_url(struct GlobalConfig *global, - struct OperationConfig *config, +static ParameterError add_url(struct OperationConfig *config, const char *thisurl, bool remote_noglob) { @@ -1078,15 +1071,14 @@ static ParameterError add_url(struct GlobalConfig *global, url->useremote = url->noglob = TRUE; if(!err && (++config->num_urls > 1) && (config->etag_save_file || config->etag_compare_file)) { - errorf(global, "The etag options only work on a single URL"); + errorf("The etag options only work on a single URL"); return PARAM_BAD_USE; } } return err; } -static ParameterError parse_url(struct GlobalConfig *global, - struct OperationConfig *config, +static ParameterError parse_url(struct OperationConfig *config, const char *nextarg) { /* nextarg is never NULL here */ @@ -1106,7 +1098,7 @@ static ParameterError parse_url(struct GlobalConfig *global, curlx_dyn_init(&line, 8092); while(my_get_line(f, &line, &error)) { const char *ptr = curlx_dyn_ptr(&line); - err = add_url(global, config, ptr, TRUE); + err = add_url(config, ptr, TRUE); if(err) break; } @@ -1119,7 +1111,7 @@ static ParameterError parse_url(struct GlobalConfig *global, } return PARAM_READ_ERROR; /* file not found */ } - return add_url(global, config, nextarg, FALSE); + return add_url(config, nextarg, FALSE); } @@ -1159,23 +1151,20 @@ static ParameterError parse_localport(struct OperationConfig *config, return PARAM_OK; } -static ParameterError parse_continue_at(struct GlobalConfig *global, - struct OperationConfig *config, +static ParameterError parse_continue_at(struct OperationConfig *config, const char *nextarg) { ParameterError err = PARAM_OK; if(config->range) { - errorf(global, "--continue-at is mutually exclusive with --range"); + errorf("--continue-at is mutually exclusive with --range"); return PARAM_BAD_USE; } if(config->rm_partial) { - errorf(config->global, - "--continue-at is mutually exclusive with --remove-on-error"); + errorf("--continue-at is mutually exclusive with --remove-on-error"); return PARAM_BAD_USE; } if(config->file_clobber_mode == CLOBBER_NEVER) { - errorf(config->global, - "--continue-at is mutually exclusive with --no-clobber"); + errorf("--continue-at is mutually exclusive with --no-clobber"); return PARAM_BAD_USE; } /* This makes us continue an ftp transfer at given position */ @@ -1191,8 +1180,7 @@ static ParameterError parse_continue_at(struct GlobalConfig *global, return err; } -static ParameterError parse_ech(struct GlobalConfig *global, - struct OperationConfig *config, +static ParameterError parse_ech(struct OperationConfig *config, const char *nextarg) { ParameterError err = PARAM_OK; @@ -1220,8 +1208,7 @@ static ParameterError parse_ech(struct GlobalConfig *global, file = fopen(nextarg, FOPEN_READTEXT); } if(!file) { - warnf(global, - "Couldn't read file \"%s\" " + warnf("Couldn't read file \"%s\" " "specified for \"--ech ecl:\" option", nextarg); return PARAM_BAD_USE; /* */ @@ -1244,8 +1231,7 @@ static ParameterError parse_ech(struct GlobalConfig *global, return err; } -static ParameterError parse_header(struct GlobalConfig *global, - struct OperationConfig *config, +static ParameterError parse_header(struct OperationConfig *config, cmdline_t cmd, const char *nextarg) { @@ -1257,7 +1243,7 @@ static ParameterError parse_header(struct GlobalConfig *global, bool use_stdin = !strcmp(&nextarg[1], "-"); FILE *file = use_stdin ? stdin : fopen(&nextarg[1], FOPEN_READTEXT); if(!file) { - errorf(global, "Failed to open %s", &nextarg[1]); + errorf("Failed to open %s", &nextarg[1]); err = PARAM_READ_ERROR; } else { @@ -1318,9 +1304,13 @@ static ParameterError parse_output(struct OperationConfig *config, return PARAM_NO_MEM; /* fill in the outfile */ - err = getstr(&url->outfile, nextarg, DENY_BLANK); + if(nextarg) + err = getstr(&url->outfile, nextarg, DENY_BLANK); + else + url->outfile = NULL; url->useremote = FALSE; /* switch off */ url->outset = TRUE; + url->out_null = !nextarg; return err; } @@ -1359,6 +1349,7 @@ static ParameterError parse_remote_name(struct OperationConfig *config, url->outfile = NULL; /* leave it */ url->useremote = toggle; url->outset = TRUE; + url->out_null = FALSE; return PARAM_OK; } @@ -1386,8 +1377,7 @@ static ParameterError parse_quote(struct OperationConfig *config, return err; } -static ParameterError parse_range(struct GlobalConfig *global, - struct OperationConfig *config, +static ParameterError parse_range(struct OperationConfig *config, const char *nextarg) { ParameterError err = PARAM_OK; @@ -1395,7 +1385,7 @@ static ParameterError parse_range(struct GlobalConfig *global, const char *orig = nextarg; if(config->use_resume) { - errorf(global, "--continue-at is mutually exclusive with --range"); + errorf("--continue-at is mutually exclusive with --range"); return PARAM_BAD_USE; } if(!curlx_str_number(&nextarg, &value, CURL_OFF_T_MAX) && @@ -1405,7 +1395,7 @@ static ParameterError parse_range(struct GlobalConfig *global, claimed that to be a good way, why this code is added to work-around it. */ char buffer[32]; - warnf(global, "A specified range MUST include at least one dash (-). " + warnf("A specified range MUST include at least one dash (-). " "Appending one for you"); msnprintf(buffer, sizeof(buffer), "%" CURL_FORMAT_CURL_OFF_T "-", value); @@ -1418,7 +1408,7 @@ static ParameterError parse_range(struct GlobalConfig *global, /* byte range requested */ while(*nextarg) { if(!ISDIGIT(*nextarg) && *nextarg != '-' && *nextarg != ',') { - warnf(global, "Invalid character is found in given range. " + warnf("Invalid character is found in given range. " "A specified range MUST have only digits in " "\'start\'-\'stop\'. The server's response to this " "request is uncertain."); @@ -1471,8 +1461,7 @@ static ParameterError parse_upload_file(struct OperationConfig *config, static size_t verbose_nopts; -static ParameterError parse_verbose(struct GlobalConfig *global, - bool toggle) +static ParameterError parse_verbose(bool toggle) { ParameterError err = PARAM_OK; @@ -1480,7 +1469,7 @@ static ParameterError parse_verbose(struct GlobalConfig *global, * more than once in the same argument flag, like `-vvv`. */ if(!toggle) { global->verbosity = 0; - if(set_trace_config(global, "-all")) + if(set_trace_config("-all")) err = PARAM_NO_MEM; global->tracetype = TRACE_NONE; return err; @@ -1488,7 +1477,7 @@ static ParameterError parse_verbose(struct GlobalConfig *global, else if(!verbose_nopts) { /* fist `-v` in an argument resets to base verbosity */ global->verbosity = 0; - if(set_trace_config(global, "-all")) + if(set_trace_config("-all")) return PARAM_NO_MEM; } /* the '%' thing here will cause the trace get sent to stderr */ @@ -1501,25 +1490,24 @@ static ParameterError parse_verbose(struct GlobalConfig *global, err = PARAM_NO_MEM; else { if(global->tracetype && (global->tracetype != TRACE_PLAIN)) - warnf(global, - "-v, --verbose overrides an earlier trace option"); + warnf("-v, --verbose overrides an earlier trace option"); global->tracetype = TRACE_PLAIN; } break; case 1: global->verbosity = 2; - if(set_trace_config(global, "ids,time,protocol")) + if(set_trace_config("ids,time,protocol")) err = PARAM_NO_MEM; break; case 2: global->verbosity = 3; global->tracetype = TRACE_ASCII; - if(set_trace_config(global, "ssl,read,write")) + if(set_trace_config("ssl,read,write")) err = PARAM_NO_MEM; break; case 3: global->verbosity = 4; - if(set_trace_config(global, "network")) + if(set_trace_config("network")) err = PARAM_NO_MEM; break; default: @@ -1529,8 +1517,7 @@ static ParameterError parse_verbose(struct GlobalConfig *global, return err; } -static ParameterError parse_writeout(struct GlobalConfig *global, - struct OperationConfig *config, +static ParameterError parse_writeout(struct OperationConfig *config, const char *nextarg) { ParameterError err = PARAM_OK; @@ -1550,7 +1537,7 @@ static ParameterError parse_writeout(struct GlobalConfig *global, fname = nextarg; file = fopen(fname, FOPEN_READTEXT); if(!file) { - errorf(global, "Failed to open %s", fname); + errorf("Failed to open %s", fname); return PARAM_READ_ERROR; } } @@ -1561,7 +1548,7 @@ static ParameterError parse_writeout(struct GlobalConfig *global, if(err) return err; if(!config->writeout) - warnf(global, "Failed to read %s", fname); + warnf("Failed to read %s", fname); } else err = getstr(&config->writeout, nextarg, ALLOW_BLANK); @@ -1569,8 +1556,7 @@ static ParameterError parse_writeout(struct GlobalConfig *global, return err; } -static ParameterError parse_time_cond(struct GlobalConfig *global, - struct OperationConfig *config, +static ParameterError parse_time_cond(struct OperationConfig *config, const char *nextarg) { ParameterError err = PARAM_OK; @@ -1595,18 +1581,17 @@ static ParameterError parse_time_cond(struct GlobalConfig *global, break; } config->condtime = (curl_off_t)curl_getdate(nextarg, NULL); - if(-1 == config->condtime) { + if(config->condtime == -1) { curl_off_t value; /* now let's see if it is a filename to get the time from instead! */ - int rc = getfiletime(nextarg, global, &value); + int rc = getfiletime(nextarg, &value); if(!rc) /* pull the time out from the file */ config->condtime = value; else { /* failed, remove time condition */ config->timecond = CURL_TIMECOND_NONE; - warnf(global, - "Illegal date format for -z, --time-cond (and not " + warnf("Illegal date format for -z, --time-cond (and not " "a filename). Disabling time condition. " "See curl_getdate(3) for valid date syntax."); } @@ -1686,72 +1671,86 @@ static void togglebit(bool toggle, unsigned long *modify, unsigned long bits) } /* opt_depr is the function that handles ARG_DEPR options */ -static void opt_depr(struct GlobalConfig *global, - const struct LongShort *a) +static void opt_depr(const struct LongShort *a) { - warnf(global, "--%s is deprecated and has no function anymore", a->lname); + warnf("--%s is deprecated and has no function anymore", a->lname); +} + +static ParameterError opt_sslver(struct OperationConfig *config, + unsigned char ver) +{ + if(config->ssl_version_max && + (config->ssl_version_max < ver)) { + errorf("Minimum TLS version set higher than max"); + return PARAM_BAD_USE; + } + config->ssl_version = ver; + return PARAM_OK; } /* opt_none is the function that handles ARG_NONE options */ -static ParameterError opt_none(struct GlobalConfig *global, - struct OperationConfig *config, +static ParameterError opt_none(struct OperationConfig *config, const struct LongShort *a) { + ParameterError err = PARAM_OK; switch(a->cmd) { case C_ANYAUTH: /* --anyauth */ config->authtype = CURLAUTH_ANY; break; case C_DUMP_CA_EMBED: /* --dump-ca-embed */ return PARAM_CA_EMBED_REQUESTED; + case C_FTP_PASV: /* --ftp-pasv */ + tool_safefree(config->ftpport); + break; case C_HTTP1_0: /* --http1.0 */ /* HTTP version 1.0 */ - sethttpver(global, config, CURL_HTTP_VERSION_1_0); + sethttpver(config, CURL_HTTP_VERSION_1_0); break; case C_HTTP1_1: /* --http1.1 */ /* HTTP version 1.1 */ - sethttpver(global, config, CURL_HTTP_VERSION_1_1); + sethttpver(config, CURL_HTTP_VERSION_1_1); break; case C_HTTP2: /* --http2 */ /* HTTP version 2.0 */ if(!feature_http2) return PARAM_LIBCURL_DOESNT_SUPPORT; - sethttpver(global, config, CURL_HTTP_VERSION_2_0); + sethttpver(config, CURL_HTTP_VERSION_2_0); break; case C_HTTP2_PRIOR_KNOWLEDGE: /* --http2-prior-knowledge */ /* HTTP version 2.0 over clean TCP */ if(!feature_http2) return PARAM_LIBCURL_DOESNT_SUPPORT; - sethttpver(global, config, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE); + sethttpver(config, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE); break; case C_HTTP3: /* --http3: */ /* Try HTTP/3, allow fallback */ if(!feature_http3) return PARAM_LIBCURL_DOESNT_SUPPORT; else - sethttpver(global, config, CURL_HTTP_VERSION_3); + sethttpver(config, CURL_HTTP_VERSION_3); break; case C_HTTP3_ONLY: /* --http3-only */ /* Try HTTP/3 without fallback */ if(!feature_http3) return PARAM_LIBCURL_DOESNT_SUPPORT; else - sethttpver(global, config, CURL_HTTP_VERSION_3ONLY); + sethttpver(config, CURL_HTTP_VERSION_3ONLY); break; case C_TLSV1: /* --tlsv1 */ - config->ssl_version = CURL_SSLVERSION_TLSv1; + err = opt_sslver(config, 1); break; case C_TLSV1_0: /* --tlsv1.0 */ - config->ssl_version = CURL_SSLVERSION_TLSv1_0; + err = opt_sslver(config, 1); break; case C_TLSV1_1: /* --tlsv1.1 */ - config->ssl_version = CURL_SSLVERSION_TLSv1_1; + err = opt_sslver(config, 2); break; case C_TLSV1_2: /* --tlsv1.2 */ - config->ssl_version = CURL_SSLVERSION_TLSv1_2; + err = opt_sslver(config, 3); break; case C_TLSV1_3: /* --tlsv1.3 */ - config->ssl_version = CURL_SSLVERSION_TLSv1_3; + err = opt_sslver(config, 4); break; case C_IPV4: /* --ipv4 */ config->ip_version = CURL_IPRESOLVE_V4; @@ -1766,12 +1765,11 @@ static ParameterError opt_none(struct GlobalConfig *global, config->proxy_ssl_version = CURL_SSLVERSION_TLSv1; break; } - return PARAM_OK; + return err; } /* opt_bool is the function that handles boolean options */ -static ParameterError opt_bool(struct GlobalConfig *global, - struct OperationConfig *config, +static ParameterError opt_bool(struct OperationConfig *config, const struct LongShort *a, bool toggle) { @@ -1828,6 +1826,8 @@ static ParameterError opt_bool(struct GlobalConfig *global, return PARAM_LIBCURL_DOESNT_SUPPORT; togglebit(toggle, &config->authtype, CURLAUTH_NTLM); break; + case C_OUT_NULL: /* --out-null */ + return parse_output(config, NULL); case C_BASIC: /* --basic */ togglebit(toggle, &config->authtype, CURLAUTH_BASIC); break; @@ -1849,7 +1849,7 @@ static ParameterError opt_bool(struct GlobalConfig *global, case C_SSL: /* --ssl */ config->ftp_ssl = toggle; if(config->ftp_ssl) - warnf(global, "--%s is an insecure option, consider --ssl-reqd instead", + warnf("--%s is an insecure option, consider --ssl-reqd instead", a->lname); break; case C_FTP_SSL_CCC: /* --ftp-ssl-ccc */ @@ -1996,7 +1996,7 @@ static ParameterError opt_bool(struct GlobalConfig *global, config->doh_verifystatus = toggle; break; case C_FALSE_START: /* --false-start */ - config->falsestart = toggle; + opt_depr(a); break; case C_SSL_NO_REVOKE: /* --ssl-no-revoke */ config->ssl_no_revoke = toggle; @@ -2031,15 +2031,14 @@ static ParameterError opt_bool(struct GlobalConfig *global, case C_FAIL_WITH_BODY: /* --fail-with-body */ config->failwithbody = toggle; if(config->failonerror && config->failwithbody) { - errorf(config->global, "You must select either --fail or " + errorf("You must select either --fail or " "--fail-with-body, not both."); return PARAM_BAD_USE; } break; case C_REMOVE_ON_ERROR: /* --remove-on-error */ if(config->use_resume && toggle) { - errorf(config->global, - "--continue-at is mutually exclusive with --remove-on-error"); + errorf("--continue-at is mutually exclusive with --remove-on-error"); return PARAM_BAD_USE; } config->rm_partial = toggle; @@ -2047,7 +2046,7 @@ static ParameterError opt_bool(struct GlobalConfig *global, case C_FAIL: /* --fail */ config->failonerror = toggle; if(config->failonerror && config->failwithbody) { - errorf(config->global, "You must select either --fail or " + errorf("You must select either --fail or " "--fail-with-body, not both."); return PARAM_BAD_USE; } @@ -2068,7 +2067,7 @@ static ParameterError opt_bool(struct GlobalConfig *global, case C_HEAD: /* --head */ config->no_body = toggle; config->show_headers = toggle; - if(SetHTTPrequest(config, (config->no_body) ? TOOL_HTTPREQ_HEAD : + if(SetHTTPrequest((config->no_body) ? TOOL_HTTPREQ_HEAD : TOOL_HTTPREQ_GET, &config->httpreq)) return PARAM_BAD_USE; break; @@ -2084,12 +2083,6 @@ static ParameterError opt_bool(struct GlobalConfig *global, case C_LIST_ONLY: /* --list-only */ config->dirlistonly = toggle; /* only list the names of the FTP dir */ break; - case C_LOCATION_TRUSTED: /* --location-trusted */ - config->unrestricted_auth = toggle; - FALLTHROUGH(); - case C_LOCATION: /* --location */ - config->followlocation = toggle; /* Follow Location: HTTP headers */ - break; case C_MANUAL: /* --manual */ if(toggle) /* --no-manual shows no manual... */ return PARAM_MANUAL_REQUESTED; @@ -2108,8 +2101,7 @@ static ParameterError opt_bool(struct GlobalConfig *global, break; case C_CLOBBER: /* --clobber */ if(config->use_resume && !toggle) { - errorf(config->global, - "--continue-at is mutually exclusive with --no-clobber"); + errorf("--continue-at is mutually exclusive with --no-clobber"); return PARAM_BAD_USE; } config->file_clobber_mode = toggle ? CLOBBER_ALWAYS : CLOBBER_NEVER; @@ -2137,7 +2129,7 @@ static ParameterError opt_bool(struct GlobalConfig *global, global->showerror = toggle; break; case C_VERBOSE: /* --verbose */ - return parse_verbose(global, toggle); + return parse_verbose(toggle); break; case C_VERSION: /* --version */ if(toggle) /* --no-version yields no output! */ @@ -2152,6 +2144,19 @@ static ParameterError opt_bool(struct GlobalConfig *global, case C_MPTCP: /* --mptcp */ config->mptcp = toggle; break; + case C_LOCATION_TRUSTED: /* --location-trusted */ + config->unrestricted_auth = toggle; + FALLTHROUGH(); + case C_LOCATION: /* --location */ + if(config->followlocation == CURLFOLLOW_OBEYCODE) + warnf("--location overrides --follow"); + config->followlocation = toggle ? CURLFOLLOW_ALL : 0; + break; + case C_FOLLOW: /* --follow */ + if(config->followlocation == CURLFOLLOW_ALL) + warnf("--follow overrides --location"); + config->followlocation = toggle ? CURLFOLLOW_OBEYCODE : 0; + break; default: return PARAM_OPTION_UNKNOWN; } @@ -2160,13 +2165,13 @@ static ParameterError opt_bool(struct GlobalConfig *global, /* opt_filestring handles string and file options */ -static ParameterError opt_filestring(struct GlobalConfig *global, - struct OperationConfig *config, +static ParameterError opt_filestring(struct OperationConfig *config, const struct LongShort *a, const char *nextarg) { ParameterError err = PARAM_OK; curl_off_t value; + long val; static const char *redir_protos[] = { "http", "https", @@ -2226,7 +2231,7 @@ static ParameterError opt_filestring(struct GlobalConfig *global, err = getstr(&global->trace_dump, nextarg, DENY_BLANK); if(!err) { if(global->tracetype && (global->tracetype != TRACE_BIN)) - warnf(global, "--trace overrides an earlier trace/verbose option"); + warnf("--trace overrides an earlier trace/verbose option"); global->tracetype = TRACE_BIN; } break; @@ -2234,20 +2239,19 @@ static ParameterError opt_filestring(struct GlobalConfig *global, err = getstr(&global->trace_dump, nextarg, DENY_BLANK); if(!err) { if(global->tracetype && (global->tracetype != TRACE_ASCII)) - warnf(global, - "--trace-ascii overrides an earlier trace/verbose option"); + warnf("--trace-ascii overrides an earlier trace/verbose option"); global->tracetype = TRACE_ASCII; } break; case C_LIMIT_RATE: /* --limit-rate */ - err = GetSizeParameter(global, nextarg, "rate", &value); + err = GetSizeParameter(nextarg, "rate", &value); if(!err) { config->recvpersecond = value; config->sendpersecond = value; } break; case C_RATE: - err = set_rate(global, nextarg); + err = set_rate(nextarg); break; case C_CREATE_FILE_MODE: /* --create-file-mode */ err = oct2nummax(&config->create_file_mode, nextarg, 0777); @@ -2269,7 +2273,7 @@ static ParameterError opt_filestring(struct GlobalConfig *global, err = getstr(&config->aws_sigv4, nextarg, ALLOW_BLANK); break; case C_STDERR: /* --stderr */ - tool_set_stderr_file(global, nextarg); + tool_set_stderr_file(nextarg); break; case C_INTERFACE: /* --interface */ /* interface */ @@ -2286,15 +2290,12 @@ static ParameterError opt_filestring(struct GlobalConfig *global, err = getstr(&config->haproxy_clientip, nextarg, DENY_BLANK); break; case C_MAX_FILESIZE: /* --max-filesize */ - err = GetSizeParameter(global, nextarg, "max-filesize", &value); + err = GetSizeParameter(nextarg, "max-filesize", &value); if(!err) config->max_filesize = value; break; case C_URL: /* --url */ - err = parse_url(global, config, nextarg); - break; - case C_FTP_PASV: /* --ftp-pasv */ - tool_safefree(config->ftpport); + err = parse_url(config, nextarg); break; case C_SOCKS5: /* --socks5 */ /* socks5 proxy to use, and resolves the name locally and passes on the @@ -2334,16 +2335,16 @@ static ParameterError opt_filestring(struct GlobalConfig *global, err = str2unum(&config->req_retry, nextarg); break; case C_RETRY_DELAY: /* --retry-delay */ - err = str2unummax(&config->retry_delay, nextarg, LONG_MAX/1000); + err = secs2ms(&config->retry_delay_ms, nextarg); break; case C_RETRY_MAX_TIME: /* --retry-max-time */ - err = str2unummax(&config->retry_maxtime, nextarg, LONG_MAX/1000); + err = secs2ms(&config->retry_maxtime_ms, nextarg); break; case C_FTP_ACCOUNT: /* --ftp-account */ err = getstr(&config->ftp_account, nextarg, DENY_BLANK); break; case C_FTP_METHOD: /* --ftp-method */ - config->ftp_filemethod = ftpfilemethod(config, nextarg); + config->ftp_filemethod = ftpfilemethod(nextarg); break; case C_LOCAL_PORT: /* --local-port */ err = parse_localport(config, nextarg); @@ -2353,8 +2354,7 @@ static ParameterError opt_filestring(struct GlobalConfig *global, break; case C_LIBCURL: /* --libcurl */ #ifdef CURL_DISABLE_LIBCURL_OPTION - warnf(global, - "--libcurl option was disabled at build-time"); + warnf("--libcurl option was disabled at build-time"); err = PARAM_OPTION_UNKNOWN; #else err = getstr(&global->libcurl, nextarg, DENY_BLANK); @@ -2387,19 +2387,18 @@ static ParameterError opt_filestring(struct GlobalConfig *global, break; case C_PROTO: /* --proto */ config->proto_present = TRUE; - err = proto2num(config, built_in_protos, &config->proto_str, nextarg); + err = proto2num(built_in_protos, &config->proto_str, nextarg); break; case C_PROTO_REDIR: /* --proto-redir */ config->proto_redir_present = TRUE; - if(proto2num(config, redir_protos, &config->proto_redir_str, - nextarg)) + if(proto2num(redir_protos, &config->proto_redir_str, nextarg)) err = PARAM_BAD_USE; break; case C_RESOLVE: /* --resolve */ err = add2list(&config->resolve, nextarg); break; case C_DELEGATION: /* --delegation */ - config->gssapi_delegation = delegation(config, nextarg); + config->gssapi_delegation = delegation(nextarg); break; case C_MAIL_AUTH: /* --mail-auth */ err = getstr(&config->mail_auth, nextarg, DENY_BLANK); @@ -2434,17 +2433,21 @@ static ParameterError opt_filestring(struct GlobalConfig *global, break; case C_TLS_MAX: /* --tls-max */ err = str2tls_max(&config->ssl_version_max, nextarg); + if(!err && (config->ssl_version_max < config->ssl_version)) { + errorf("--tls-max set lower than minimum accepted version"); + err = PARAM_BAD_USE; + } break; case C_HAPPY_EYEBALLS_TIMEOUT_MS: /* --happy-eyeballs-timeout-ms */ err = str2unum(&config->happy_eyeballs_timeout_ms, nextarg); /* 0 is a valid value for this timeout */ break; case C_TRACE_CONFIG: /* --trace-config */ - if(set_trace_config(global, nextarg)) + if(set_trace_config(nextarg)) err = PARAM_NO_MEM; break; case C_VARIABLE: /* --variable */ - err = setvariable(global, nextarg); + err = setvariable(nextarg); break; case C_TLS13_CIPHERS: /* --tls13-ciphers */ err = getstr(&config->cipher13_list, nextarg, DENY_BLANK); @@ -2482,7 +2485,7 @@ static ParameterError opt_filestring(struct GlobalConfig *global, err = getstr(&config->cookiejar, nextarg, DENY_BLANK); break; case C_CONTINUE_AT: /* --continue-at */ - err = parse_continue_at(global, config, nextarg); + err = parse_continue_at(config, nextarg); break; case C_DATA: /* --data */ case C_DATA_ASCII: /* --data-ascii */ @@ -2490,10 +2493,10 @@ static ParameterError opt_filestring(struct GlobalConfig *global, case C_DATA_URLENCODE: /* --data-urlencode */ case C_JSON: /* --json */ case C_DATA_RAW: /* --data-raw */ - err = set_data((cmdline_t)a->cmd, nextarg, global, config); + err = set_data((cmdline_t)a->cmd, nextarg, config); break; case C_URL_QUERY: /* --url-query */ - err = url_query(nextarg, global, config); + err = url_query(nextarg, config); break; case C_DUMP_HEADER: /* --dump-header */ err = getstr(&config->headerfile, nextarg, DENY_BLANK); @@ -2542,7 +2545,7 @@ static ParameterError opt_filestring(struct GlobalConfig *global, } break; case C_ECH: /* --ech */ - err = parse_ech(global, config, nextarg); + err = parse_ech(config, nextarg); break; case C_CAPATH: /* --capath */ err = getstr(&config->capath, nextarg, DENY_BLANK); @@ -2654,7 +2657,7 @@ static ParameterError opt_filestring(struct GlobalConfig *global, break; case C_ETAG_SAVE: /* --etag-save */ if(config->num_urls > 1) { - errorf(global, "The etag options only work on a single URL"); + errorf("The etag options only work on a single URL"); err = PARAM_BAD_USE; } else @@ -2662,7 +2665,7 @@ static ParameterError opt_filestring(struct GlobalConfig *global, break; case C_ETAG_COMPARE: /* --etag-compare */ if(config->num_urls > 1) { - errorf(global, "The etag options only work on a single URL"); + errorf("The etag options only work on a single URL"); err = PARAM_BAD_USE; } else @@ -2678,13 +2681,10 @@ static ParameterError opt_filestring(struct GlobalConfig *global, case C_FORM_STRING: /* --form-string */ /* "form data" simulation, this is a little advanced so lets do our best to sort this out slowly and carefully */ - if(formparse(config, - nextarg, - &config->mimeroot, - &config->mimecurrent, + if(formparse(nextarg, &config->mimeroot, &config->mimecurrent, (a->cmd == C_FORM_STRING))) /* literal string */ err = PARAM_BAD_USE; - else if(SetHTTPrequest(config, TOOL_HTTPREQ_MIMEPOST, &config->httpreq)) + else if(SetHTTPrequest(TOOL_HTTPREQ_MIMEPOST, &config->httpreq)) err = PARAM_BAD_USE; break; case C_REQUEST_TARGET: /* --request-target */ @@ -2692,11 +2692,11 @@ static ParameterError opt_filestring(struct GlobalConfig *global, break; case C_HEADER: /* --header */ case C_PROXY_HEADER: /* --proxy-header */ - err = parse_header(global, config, (cmdline_t)a->cmd, nextarg); + err = parse_header(config, (cmdline_t)a->cmd, nextarg); break; case C_CONFIG: /* --config */ - if(parseconfig(nextarg, global)) { - errorf(global, "cannot read config from '%s'", nextarg); + if(parseconfig(nextarg)) { + errorf("cannot read config from '%s'", nextarg); err = PARAM_READ_ERROR; } break; @@ -2723,13 +2723,13 @@ static ParameterError opt_filestring(struct GlobalConfig *global, break; case C_FTP_SSL_CCC_MODE: /* --ftp-ssl-ccc-mode */ config->ftp_ssl_ccc = TRUE; - config->ftp_ssl_ccc_mode = ftpcccmethod(config, nextarg); + config->ftp_ssl_ccc_mode = ftpcccmethod(nextarg); break; case C_QUOTE: /* --quote */ err = parse_quote(config, nextarg); break; case C_RANGE: /* --range */ - err = parse_range(global, config, nextarg); + err = parse_range(config, nextarg); break; case C_TELNET_OPTION: /* --telnet-option */ /* Telnet options */ @@ -2747,7 +2747,7 @@ static ParameterError opt_filestring(struct GlobalConfig *global, err = getstr(&config->proxyuserpwd, nextarg, ALLOW_BLANK); break; case C_WRITE_OUT: /* --write-out */ - err = parse_writeout(global, config, nextarg); + err = parse_writeout(config, nextarg); break; case C_PREPROXY: /* --preproxy */ err = getstr(&config->preproxy, nextarg, DENY_BLANK); @@ -2774,8 +2774,19 @@ static ParameterError opt_filestring(struct GlobalConfig *global, if(!err && !config->low_speed_time) config->low_speed_time = 30; break; - case C_PARALLEL_MAX: { /* --parallel-max */ - long val; + case C_PARALLEL_HOST: /* --parallel-max-host */ + err = str2unum(&val, nextarg); + if(err) + break; + if(val > MAX_PARALLEL_HOST) + global->parallel_host = MAX_PARALLEL_HOST; + else if(val < 1) + global->parallel_host = PARALLEL_HOST_DEFAULT; + else + global->parallel_host = (unsigned short)val; + break; + break; + case C_PARALLEL_MAX: /* --parallel-max */ err = str2unum(&val, nextarg); if(err) break; @@ -2786,9 +2797,8 @@ static ParameterError opt_filestring(struct GlobalConfig *global, else global->parallel_max = (unsigned short)val; break; - } case C_TIME_COND: /* --time-cond */ - err = parse_time_cond(global, config, nextarg); + err = parse_time_cond(config, nextarg); break; case C_UPLOAD_FLAGS: /* --upload-flags */ err = parse_upload_flags(config, nextarg); @@ -2797,11 +2807,13 @@ static ParameterError opt_filestring(struct GlobalConfig *global, return err; } +/* the longest command line option, excluding the leading -- */ +#define MAX_OPTION_LEN 26 + ParameterError getparameter(const char *flag, /* f or -long-flag */ const char *nextarg, /* NULL if unset */ bool *usedarg, /* set to TRUE if the arg has been used */ - struct GlobalConfig *global, struct OperationConfig *config) { const char *parse = NULL; @@ -2811,6 +2823,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ bool toggle = TRUE; /* how to switch boolean options, on or off. Controlled by using --OPTION or --no-OPTION */ bool nextalloc = FALSE; /* if nextarg is allocated */ + bool consumearg = TRUE; /* the argument comes separate */ const struct LongShort *a = NULL; verbose_nopts = 0; /* options processed in `flag`*/ @@ -2821,6 +2834,8 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ const char *word = ('-' == flag[0]) ? flag + 2 : flag; bool noflagged = FALSE; bool expand = FALSE; + const char *p; + struct Curl_str out; if(!strncmp(word, "no-", 3)) { /* disable this option but ignore the "no-" part when looking for it */ @@ -2834,7 +2849,21 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ expand = TRUE; } - a = findlongopt(word); + p = word; + /* is there an '=' ? */ + if(!curlx_str_until(&p, &out, MAX_OPTION_LEN, '=') && + !curlx_str_single(&p, '=') ) { + /* there's an equal sign */ + char tempword[MAX_OPTION_LEN + 1]; + memcpy(tempword, curlx_str(&out), curlx_strlen(&out)); + tempword[curlx_strlen(&out)] = 0; + a = findlongopt(tempword); + nextarg = p; + consumearg = FALSE; /* it is not separate */ + } + else + a = findlongopt(word); + if(a) { longopt = TRUE; } @@ -2857,7 +2886,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ err = PARAM_EXPAND_ERROR; goto error; } - err = varexpand(global, nextarg, &nbuf, &replaced); + err = varexpand(nextarg, &nbuf, &replaced); if(err) { curlx_dyn_free(&nbuf); goto error; @@ -2904,39 +2933,39 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ break; } else { - *usedarg = TRUE; /* mark it as used */ + *usedarg = consumearg; /* mark it as used */ } if(a->desc & ARG_DEPR) { - opt_depr(global, a); + opt_depr(a); break; } if((ARGTYPE(a->desc) == ARG_FILE) && (nextarg[0] == '-') && nextarg[1]) { /* if the filename looks like a command line option */ - warnf(global, "The filename argument '%s' looks like a flag.", + warnf("The filename argument '%s' looks like a flag.", nextarg); } else if(!strncmp("\xe2\x80\x9c", nextarg, 3)) { - warnf(global, "The argument '%s' starts with a Unicode quote where " + warnf("The argument '%s' starts with a Unicode quote where " "maybe an ASCII \" was intended?", nextarg); } /* ARG_FILE | ARG_STRG */ - err = opt_filestring(global, config, a, nextarg); + err = opt_filestring(config, a, nextarg); if(a->desc & ARG_CLEAR) cleanarg(CURL_UNCONST(nextarg)); } else { if(a->desc & ARG_DEPR) { - opt_depr(global, a); + opt_depr(a); break; } /* ARG_NONE | ARG_BOOL */ if(ARGTYPE(a->desc) == ARG_BOOL) - err = opt_bool(global, config, a, toggle); + err = opt_bool(config, a, toggle); else - err = opt_none(global, config, a); + err = opt_none(config, a); } ++verbose_nopts; /* processed one option from `flag` input, loop for @@ -2949,8 +2978,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ return err; } -ParameterError parse_args(struct GlobalConfig *global, int argc, - argv_item_t argv[]) +ParameterError parse_args(int argc, argv_item_t argv[]) { int i; bool stillflags; @@ -2980,7 +3008,7 @@ ParameterError parse_args(struct GlobalConfig *global, int argc, } } - result = getparameter(orig_opt, nextarg, &passarg, global, config); + result = getparameter(orig_opt, nextarg, &passarg, config); unicodefree(nextarg); config = global->last; @@ -2991,14 +3019,8 @@ ParameterError parse_args(struct GlobalConfig *global, int argc, if(config->url_list && config->url_list->url) { /* Allocate the next config */ - config->next = malloc(sizeof(struct OperationConfig)); + config->next = config_alloc(); if(config->next) { - /* Initialise the newly created config */ - config_init(config->next); - - /* Set the global config pointer */ - config->next->global = global; - /* Update the last config pointer */ global->last = config->next; @@ -3010,7 +3032,7 @@ ParameterError parse_args(struct GlobalConfig *global, int argc, result = PARAM_NO_MEM; } else { - errorf(global, "missing URL before --next"); + errorf("missing URL before --next"); result = PARAM_BAD_USE; } } @@ -3022,7 +3044,7 @@ ParameterError parse_args(struct GlobalConfig *global, int argc, bool used; /* Just add the URL please */ - result = getparameter("--url", orig_opt, &used, global, config); + result = getparameter("--url", orig_opt, &used, config); } if(!result) { @@ -3044,9 +3066,9 @@ ParameterError parse_args(struct GlobalConfig *global, int argc, const char *reason = param2text(result); if(orig_opt && strcmp(":", orig_opt)) - helpf(tool_stderr, "option %s: %s", orig_opt, reason); + helpf("option %s: %s", orig_opt, reason); else - helpf(tool_stderr, "%s", reason); + helpf("%s", reason); } unicodefree(orig_opt); diff --git a/vendor/curl/src/tool_getparam.h b/vendor/curl/src/tool_getparam.h index d84e8522257..a08bbac7b64 100644 --- a/vendor/curl/src/tool_getparam.h +++ b/vendor/curl/src/tool_getparam.h @@ -90,6 +90,7 @@ typedef enum { C_FAIL_EARLY, C_FAIL_WITH_BODY, C_FALSE_START, + C_FOLLOW, C_FORM, C_FORM_ESCAPE, C_FORM_STRING, @@ -167,9 +168,11 @@ typedef enum { C_NTLM, C_NTLM_WB, C_OAUTH2_BEARER, + C_OUT_NULL, C_OUTPUT, C_OUTPUT_DIR, C_PARALLEL, + C_PARALLEL_HOST, C_PARALLEL_IMMEDIATE, C_PARALLEL_MAX, C_PASS, @@ -357,7 +360,6 @@ typedef enum { PARAM_LAST } ParameterError; -struct GlobalConfig; struct OperationConfig; const struct LongShort *findlongopt(const char *opt); @@ -365,8 +367,7 @@ const struct LongShort *findshortopt(char letter); ParameterError getparameter(const char *flag, const char *nextarg, bool *usedarg, - struct GlobalConfig *global, - struct OperationConfig *operation); + struct OperationConfig *config); #ifdef UNITTESTS void parse_cert_parameter(const char *cert_parameter, @@ -374,8 +375,7 @@ void parse_cert_parameter(const char *cert_parameter, char **passphrase); #endif -ParameterError parse_args(struct GlobalConfig *config, int argc, - argv_item_t argv[]); +ParameterError parse_args(int argc, argv_item_t argv[]); #if defined(UNICODE) && defined(_WIN32) && !defined(UNDER_CE) diff --git a/vendor/curl/src/tool_getpass.c b/vendor/curl/src/tool_getpass.c index bb0692083d2..fc59accc07a 100644 --- a/vendor/curl/src/tool_getpass.c +++ b/vendor/curl/src/tool_getpass.c @@ -55,7 +55,7 @@ #endif #include "tool_getpass.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ #ifdef __VMS /* VMS implementation */ @@ -179,7 +179,7 @@ char *getpass_r(const char *prompt, /* prompt to display */ ssize_t nread; bool disabled; int fd = open("/dev/tty", O_RDONLY); - if(-1 == fd) + if(fd == -1) fd = STDIN_FILENO; /* use stdin if the tty could not be used */ disabled = ttyecho(FALSE, fd); /* disable terminal echo */ diff --git a/vendor/curl/src/tool_help.c b/vendor/curl/src/tool_help.c index 3d0336f22dd..3cdd522c29d 100644 --- a/vendor/curl/src/tool_help.c +++ b/vendor/curl/src/tool_help.c @@ -23,8 +23,6 @@ ***************************************************************************/ #include "tool_setup.h" -#include - #include "tool_help.h" #include "tool_libinfo.h" #include "tool_util.h" @@ -35,7 +33,7 @@ #include "tool_cfgable.h" #include "terminal.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ struct category_descriptors { const char *opt; diff --git a/vendor/curl/src/tool_helpers.c b/vendor/curl/src/tool_helpers.c index 5026fcf1c67..fbf3f1c932e 100644 --- a/vendor/curl/src/tool_helpers.c +++ b/vendor/curl/src/tool_helpers.c @@ -23,13 +23,11 @@ ***************************************************************************/ #include "tool_setup.h" -#include - #include "tool_cfgable.h" #include "tool_msgs.h" #include "tool_getparam.h" #include "tool_helpers.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ /* ** Helper functions that are used from more than one source file. @@ -77,7 +75,7 @@ const char *param2text(ParameterError error) } } -int SetHTTPrequest(struct OperationConfig *config, HttpReq req, HttpReq *store) +int SetHTTPrequest(HttpReq req, HttpReq *store) { /* this mirrors the HttpReq enum in tool_sdecls.h */ const char *reqname[]= { @@ -94,15 +92,14 @@ int SetHTTPrequest(struct OperationConfig *config, HttpReq req, HttpReq *store) *store = req; return 0; } - warnf(config->global, "You can only select one HTTP request method! " + warnf("You can only select one HTTP request method! " "You asked for both %s and %s.", reqname[req], reqname[*store]); return 1; } -void customrequest_helper(struct OperationConfig *config, HttpReq req, - char *method) +void customrequest_helper(HttpReq req, char *method) { /* this mirrors the HttpReq enum in tool_sdecls.h */ const char *dflt[]= { @@ -117,12 +114,11 @@ void customrequest_helper(struct OperationConfig *config, HttpReq req, if(!method) ; else if(curl_strequal(method, dflt[req])) { - notef(config->global, "Unnecessary use of -X or --request, %s is already " + notef("Unnecessary use of -X or --request, %s is already " "inferred.", dflt[req]); } else if(curl_strequal(method, "head")) { - warnf(config->global, - "Setting custom HTTP method to HEAD with -X/--request may not work " + warnf("Setting custom HTTP method to HEAD with -X/--request may not work " "the way you want. Consider using -I/--head instead."); } } diff --git a/vendor/curl/src/tool_helpers.h b/vendor/curl/src/tool_helpers.h index dd085e2cc79..fab026b05d4 100644 --- a/vendor/curl/src/tool_helpers.h +++ b/vendor/curl/src/tool_helpers.h @@ -26,11 +26,7 @@ #include "tool_setup.h" const char *param2text(ParameterError error); - -int SetHTTPrequest(struct OperationConfig *config, HttpReq req, - HttpReq *store); - -void customrequest_helper(struct OperationConfig *config, HttpReq req, - char *method); +int SetHTTPrequest(HttpReq req, HttpReq *store); +void customrequest_helper(HttpReq req, char *method); #endif /* HEADER_CURL_TOOL_HELPERS_H */ diff --git a/vendor/curl/src/tool_ipfs.c b/vendor/curl/src/tool_ipfs.c index 0d870bef308..dd030f09bc9 100644 --- a/vendor/curl/src/tool_ipfs.c +++ b/vendor/curl/src/tool_ipfs.c @@ -24,12 +24,11 @@ #include "tool_setup.h" #ifndef CURL_DISABLE_IPFS -#include #include "tool_cfgable.h" #include "tool_msgs.h" #include "tool_ipfs.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ /* ensure input ends in slash */ static CURLcode ensure_trailing_slash(char **input) @@ -272,13 +271,13 @@ CURLcode ipfs_url_rewrite(CURLU *uh, const char *protocol, char **url, { switch(result) { case CURLE_URL_MALFORMAT: - helpf(tool_stderr, "malformed target URL"); + helpf("malformed target URL"); break; case CURLE_FILE_COULDNT_READ_FILE: - helpf(tool_stderr, "IPFS automatic gateway detection failed"); + helpf("IPFS automatic gateway detection failed"); break; case CURLE_BAD_FUNCTION_ARGUMENT: - helpf(tool_stderr, "--ipfs-gateway was given a malformed URL"); + helpf("--ipfs-gateway was given a malformed URL"); break; default: break; diff --git a/vendor/curl/src/tool_libinfo.c b/vendor/curl/src/tool_libinfo.c index 4f9485350fc..d755532652c 100644 --- a/vendor/curl/src/tool_libinfo.c +++ b/vendor/curl/src/tool_libinfo.c @@ -23,9 +23,8 @@ ***************************************************************************/ #include "tool_setup.h" -#include #include "tool_libinfo.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ /* global variable definitions, for libcurl runtime info */ diff --git a/vendor/curl/src/tool_listhelp.c b/vendor/curl/src/tool_listhelp.c index 785f4cd936e..ecbd8bf4595 100644 --- a/vendor/curl/src/tool_listhelp.c +++ b/vendor/curl/src/tool_listhelp.c @@ -200,7 +200,10 @@ const struct helptxt helptext[] = { CURLHELP_HTTP | CURLHELP_OUTPUT}, {" --false-start", "Enable TLS False Start", - CURLHELP_TLS}, + CURLHELP_DEPRECATED}, + {" --follow", + "Follow redirects per spec", + CURLHELP_HTTP}, {"-F, --form ", "Specify multipart MIME data", CURLHELP_HTTP | CURLHELP_UPLOAD | CURLHELP_POST | CURLHELP_IMAP | @@ -442,6 +445,9 @@ const struct helptxt helptext[] = { "OAuth 2 Bearer Token", CURLHELP_AUTH | CURLHELP_IMAP | CURLHELP_POP3 | CURLHELP_SMTP | CURLHELP_LDAP}, + {" --out-null", + "Discard response data into the void", + CURLHELP_OUTPUT}, {"-o, --output ", "Write to file instead of stdout", CURLHELP_IMPORTANT | CURLHELP_OUTPUT}, @@ -457,6 +463,9 @@ const struct helptxt helptext[] = { {" --parallel-max ", "Maximum concurrency for parallel transfers", CURLHELP_CONNECTION | CURLHELP_CURL | CURLHELP_GLOBAL}, + {" --parallel-max-host ", + "Maximum connections to a single host", + CURLHELP_CONNECTION | CURLHELP_CURL | CURLHELP_GLOBAL}, {" --pass ", "Passphrase for the private key", CURLHELP_SSH | CURLHELP_TLS | CURLHELP_AUTH}, diff --git a/vendor/curl/src/tool_main.c b/vendor/curl/src/tool_main.c index b78fe28b50f..0ad40dc29d8 100644 --- a/vendor/curl/src/tool_main.c +++ b/vendor/curl/src/tool_main.c @@ -23,8 +23,6 @@ ***************************************************************************/ #include "tool_setup.h" -#include - #ifdef _WIN32 #include #endif @@ -37,8 +35,6 @@ #include #endif -#include - #include "tool_cfgable.h" #include "tool_doswin.h" #include "tool_msgs.h" @@ -53,7 +49,7 @@ * the library level code from this client-side is ugly, but we do this * anyway for convenience. */ -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ #ifdef __VMS /* @@ -65,8 +61,8 @@ int vms_show = 0; #endif -#if defined(__AMIGA__) -#if defined(__GNUC__) +#ifdef __AMIGA__ +#ifdef __GNUC__ #define CURL_USED __attribute__((used)) #else #define CURL_USED @@ -120,9 +116,9 @@ static void memory_tracking_init(void) env = curl_getenv("CURL_MEMDEBUG"); if(env) { /* use the value as filename */ - char fname[CURL_MT_LOGFNAME_BUFSIZE]; - if(strlen(env) >= CURL_MT_LOGFNAME_BUFSIZE) - env[CURL_MT_LOGFNAME_BUFSIZE-1] = '\0'; + char fname[512]; + if(strlen(env) >= sizeof(fname)) + env[sizeof(fname)-1] = '\0'; strcpy(fname, env); curl_free(env); curl_dbg_memdebug(fname); @@ -144,85 +140,6 @@ static void memory_tracking_init(void) # define memory_tracking_init() tool_nop_stmt #endif -/* - * This is the main global constructor for the app. Call this before - * _any_ libcurl usage. If this fails, *NO* libcurl functions may be - * used, or havoc may be the result. - */ -static CURLcode main_init(struct GlobalConfig *config) -{ - CURLcode result = CURLE_OK; - -#ifdef __DJGPP__ - /* stop stat() wasting time */ - _djstat_flags |= _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE; -#endif - - /* Initialise the global config */ - config->showerror = FALSE; /* show errors when silent */ - config->styled_output = TRUE; /* enable detection */ - config->parallel_max = PARALLEL_DEFAULT; - - /* Allocate the initial operate config */ - config->first = config->last = malloc(sizeof(struct OperationConfig)); - if(config->first) { - /* Perform the libcurl initialization */ - result = curl_global_init(CURL_GLOBAL_DEFAULT); - if(!result) { - /* Get information about libcurl */ - result = get_libcurl_info(); - - if(!result) { - /* Initialise the config */ - config_init(config->first); - config->first->global = config; - } - else { - errorf(config, "error retrieving curl library information"); - free(config->first); - } - } - else { - errorf(config, "error initializing curl library"); - free(config->first); - } - } - else { - errorf(config, "error initializing curl"); - result = CURLE_FAILED_INIT; - } - - return result; -} - -static void free_globalconfig(struct GlobalConfig *config) -{ - tool_safefree(config->trace_dump); - - if(config->trace_fopened && config->trace_stream) - fclose(config->trace_stream); - config->trace_stream = NULL; - - tool_safefree(config->libcurl); -} - -/* - * This is the main global destructor for the app. Call this after - * _all_ libcurl usage is done. - */ -static void main_free(struct GlobalConfig *config) -{ - /* Cleanup the easy handle */ - /* Main cleanup */ - curl_global_cleanup(); - free_globalconfig(config); - - /* Free the config structures */ - config_free(config->last); - config->first = NULL; - config->last = NULL; -} - /* ** curl tool main function. */ @@ -239,8 +156,6 @@ int main(int argc, char *argv[]) #endif { CURLcode result = CURLE_OK; - struct GlobalConfig global; - memset(&global, 0, sizeof(global)); tool_init_stderr(); @@ -259,13 +174,13 @@ int main(int argc, char *argv[]) /* win32_init must be called before other init routines. */ result = win32_init(); if(result) { - errorf(&global, "(%d) Windows-specific init failed", result); + errorf("(%d) Windows-specific init failed", result); return (int)result; } #endif if(main_checkfds()) { - errorf(&global, "out of file descriptors"); + errorf("out of file descriptors"); return CURLE_FAILED_INIT; } @@ -278,13 +193,13 @@ int main(int argc, char *argv[]) /* Initialize the curl library - do not call any libcurl functions before this point */ - result = main_init(&global); + result = globalconf_init(); if(!result) { /* Start our curl operation */ - result = operate(&global, argc, argv); + result = operate(argc, argv); /* Perform the main cleanup */ - main_free(&global); + globalconf_free(); } #ifdef _WIN32 diff --git a/vendor/curl/src/tool_main.h b/vendor/curl/src/tool_main.h index 95d603f4a05..53ee9a3702a 100644 --- a/vendor/curl/src/tool_main.h +++ b/vendor/curl/src/tool_main.h @@ -30,7 +30,10 @@ #define RETRY_SLEEP_DEFAULT 1000L /* ms */ #define RETRY_SLEEP_MAX 600000L /* ms == 10 minutes */ -#define MAX_PARALLEL 300 /* conservative */ +#define MAX_PARALLEL 65535 #define PARALLEL_DEFAULT 50 +#define MAX_PARALLEL_HOST 65535 +#define PARALLEL_HOST_DEFAULT 0 /* means not used */ + #endif /* HEADER_CURL_TOOL_MAIN_H */ diff --git a/vendor/curl/src/tool_msgs.c b/vendor/curl/src/tool_msgs.c index 520bb908727..de0c1431e2a 100644 --- a/vendor/curl/src/tool_msgs.c +++ b/vendor/curl/src/tool_msgs.c @@ -23,32 +23,28 @@ ***************************************************************************/ #include "tool_setup.h" -#include - #include "tool_cfgable.h" #include "tool_msgs.h" #include "tool_cb_prg.h" #include "terminal.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ #define WARN_PREFIX "Warning: " #define NOTE_PREFIX "Note: " #define ERROR_PREFIX "curl: " -static void voutf(struct GlobalConfig *config, - const char *prefix, +static void voutf(const char *prefix, const char *fmt, - va_list ap) CURL_PRINTF(3, 0); + va_list ap) CURL_PRINTF(2, 0); -static void voutf(struct GlobalConfig *config, - const char *prefix, +static void voutf(const char *prefix, const char *fmt, va_list ap) { size_t width = (get_terminal_columns() - strlen(prefix)); DEBUGASSERT(!strchr(fmt, '\n')); - if(!config->silent) { + if(!global->silent) { size_t len; char *ptr; char *print_buffer; @@ -68,7 +64,7 @@ static void voutf(struct GlobalConfig *config, while(!ISBLANK(ptr[cut]) && cut) { cut--; } - if(0 == cut) + if(cut == 0) /* not a single cutting position was found, just cut it at the max text width then! */ cut = width-1; @@ -92,12 +88,12 @@ static void voutf(struct GlobalConfig *config, * Emit 'note' formatted message on configured 'errors' stream, if verbose was * selected. */ -void notef(struct GlobalConfig *config, const char *fmt, ...) +void notef(const char *fmt, ...) { va_list ap; va_start(ap, fmt); - if(config->tracetype) - voutf(config, NOTE_PREFIX, fmt, ap); + if(global->tracetype) + voutf(NOTE_PREFIX, fmt, ap); va_end(ap); } @@ -105,11 +101,11 @@ void notef(struct GlobalConfig *config, const char *fmt, ...) * Emit warning formatted message on configured 'errors' stream unless * mute (--silent) was selected. */ -void warnf(struct GlobalConfig *config, const char *fmt, ...) +void warnf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); - voutf(config, WARN_PREFIX, fmt, ap); + voutf(WARN_PREFIX, fmt, ap); va_end(ap); } @@ -117,18 +113,18 @@ void warnf(struct GlobalConfig *config, const char *fmt, ...) * Emit help formatted message on given stream. This is for errors with or * related to command line arguments. */ -void helpf(FILE *errors, const char *fmt, ...) +void helpf(const char *fmt, ...) { if(fmt) { va_list ap; va_start(ap, fmt); DEBUGASSERT(!strchr(fmt, '\n')); - fputs("curl: ", errors); /* prefix it */ - vfprintf(errors, fmt, ap); + fputs("curl: ", tool_stderr); /* prefix it */ + vfprintf(tool_stderr, fmt, ap); va_end(ap); - fputs("\n", errors); /* newline it */ + fputs("\n", tool_stderr); /* newline it */ } - fprintf(errors, "curl: try 'curl --help' " + fprintf(tool_stderr, "curl: try 'curl --help' " #ifdef USE_MANUAL "or 'curl --manual' " #endif @@ -139,12 +135,12 @@ void helpf(FILE *errors, const char *fmt, ...) * Emit error message on error stream if not muted. When errors are not tied * to command line arguments, use helpf() for such errors. */ -void errorf(struct GlobalConfig *config, const char *fmt, ...) +void errorf(const char *fmt, ...) { - if(!config->silent || config->showerror) { + if(!global->silent || global->showerror) { va_list ap; va_start(ap, fmt); - voutf(config, ERROR_PREFIX, fmt, ap); + voutf(ERROR_PREFIX, fmt, ap); va_end(ap); } } diff --git a/vendor/curl/src/tool_msgs.h b/vendor/curl/src/tool_msgs.h index e963efaa0b1..99a980234a2 100644 --- a/vendor/curl/src/tool_msgs.h +++ b/vendor/curl/src/tool_msgs.h @@ -26,13 +26,13 @@ #include "tool_setup.h" #include "tool_cfgable.h" -void warnf(struct GlobalConfig *config, const char *fmt, ...) - CURL_PRINTF(2, 3); -void notef(struct GlobalConfig *config, const char *fmt, ...) - CURL_PRINTF(2, 3); -void helpf(FILE *errors, const char *fmt, ...) - CURL_PRINTF(2, 3); -void errorf(struct GlobalConfig *config, const char *fmt, ...) - CURL_PRINTF(2, 3); +void warnf(const char *fmt, ...) + CURL_PRINTF(1, 2); +void notef(const char *fmt, ...) + CURL_PRINTF(1, 2); +void helpf(const char *fmt, ...) + CURL_PRINTF(1, 2); +void errorf(const char *fmt, ...) + CURL_PRINTF(1, 2); #endif /* HEADER_CURL_TOOL_MSGS_H */ diff --git a/vendor/curl/src/tool_operate.c b/vendor/curl/src/tool_operate.c index 24e79e6f61f..90e1fbf860d 100644 --- a/vendor/curl/src/tool_operate.c +++ b/vendor/curl/src/tool_operate.c @@ -54,9 +54,6 @@ #include #endif -#include - -#include "tool_binmode.h" #include "tool_cfgable.h" #include "tool_cb_dbg.h" #include "tool_cb_hdr.h" @@ -80,7 +77,6 @@ #include "tool_paramhlp.h" #include "tool_parsecfg.h" #include "tool_setopt.h" -#include "tool_sleep.h" #include "tool_ssls.h" #include "tool_urlglob.h" #include "tool_util.h" @@ -98,7 +94,7 @@ CURL_EXTERN CURLcode curl_easy_perform_ev(CURL *easy); #endif -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ #ifdef CURL_CA_EMBED #ifndef CURL_DECLARED_CURL_CA_EMBED @@ -114,13 +110,7 @@ extern const unsigned char curl_ca_embed[]; "this situation and\nhow to fix it, please visit the webpage mentioned " \ "above.\n" -static CURLcode single_transfer(struct GlobalConfig *global, - struct OperationConfig *config, - CURLSH *share, - bool *added, - bool *skipped); -static CURLcode create_transfer(struct GlobalConfig *global, - CURLSH *share, +static CURLcode create_transfer(CURLSH *share, bool *added, bool *skipped); @@ -212,7 +202,6 @@ static curl_off_t VmsSpecialSize(const char *name, struct per_transfer *transfers; /* first node */ static struct per_transfer *transfersl; /* last node */ -static curl_off_t all_pers; /* add_per_transfer creates a new 'per_transfer' node in the linked list of transfers */ @@ -234,8 +223,6 @@ static CURLcode add_per_transfer(struct per_transfer **per) transfersl = p; } *per = p; - all_xfers++; /* count total number of transfers added */ - all_pers++; return CURLE_OK; } @@ -264,20 +251,15 @@ static struct per_transfer *del_per_transfer(struct per_transfer *per) transfersl = p; free(per); - all_pers--; return n; } -static CURLcode pre_transfer(struct GlobalConfig *global, - struct per_transfer *per) +static CURLcode pre_transfer(struct per_transfer *per) { curl_off_t uploadfilesize = -1; struct_stat fileinfo; CURLcode result = CURLE_OK; -#ifdef CURL_DISABLE_LIBCURL_OPTION - (void)global; /* otherwise used in the my_setopt macros */ -#endif if(per->uploadfile && !stdin_upload(per->uploadfile)) { /* VMS Note: @@ -316,7 +298,7 @@ static CURLcode pre_transfer(struct GlobalConfig *global, if((per->infd == -1) || fstat(per->infd, &fileinfo)) #endif { - helpf(tool_stderr, "cannot open '%s'", per->uploadfile); + helpf("cannot open '%s'", per->uploadfile); if(per->infd != -1) { close(per->infd); per->infd = STDIN_FILENO; @@ -348,17 +330,14 @@ static CURLcode pre_transfer(struct GlobalConfig *global, return result; } -void single_transfer_cleanup(struct OperationConfig *config) +void single_transfer_cleanup(void) { - if(config) { - struct State *state = &config->state; - /* Free list of remaining URLs */ - glob_cleanup(&state->urls); - tool_safefree(state->outfiles); - tool_safefree(state->uploadfile); - /* Free list of globbed upload files */ - glob_cleanup(&state->inglob); - } + struct State *state = &global->state; + /* Free list of remaining URLs */ + glob_cleanup(&state->urlglob); + tool_safefree(state->uploadfile); + /* Free list of globbed upload files */ + glob_cleanup(&state->inglob); } static CURLcode retrycheck(struct OperationConfig *config, @@ -471,13 +450,12 @@ static CURLcode retrycheck(struct OperationConfig *config, /* if adding retry_after seconds to the process would exceed the maximum time allowed for retrying, then exit the retries right away */ - if(config->retry_maxtime) { - curl_off_t seconds = curlx_timediff(curlx_now(), - per->retrystart)/1000; + if(config->retry_maxtime_ms) { + timediff_t ms = curlx_timediff(curlx_now(), per->retrystart); - if((CURL_OFF_T_MAX - retry_after < seconds) || - (seconds + retry_after > config->retry_maxtime)) { - warnf(config->global, "The Retry-After: time would " + if((CURL_OFF_T_MAX - sleeptime < ms) || + (ms + sleeptime > config->retry_maxtime_ms)) { + warnf("The Retry-After: time would " "make this command line exceed the maximum allowed time " "for retries."); *retryp = FALSE; @@ -486,7 +464,7 @@ static CURLcode retrycheck(struct OperationConfig *config, } } } - warnf(config->global, "Problem %s. " + warnf("Problem %s. " "Will retry in %ld second%s. " "%ld retr%s left.", m[retry], sleeptime/1000L, @@ -495,7 +473,7 @@ static CURLcode retrycheck(struct OperationConfig *config, (per->retry_remaining > 1 ? "ies" : "y")); per->retry_remaining--; - if(!config->retry_delay) { + if(!config->retry_delay_ms) { per->retry_sleep *= 2; if(per->retry_sleep > RETRY_SLEEP_MAX) per->retry_sleep = RETRY_SLEEP_MAX; @@ -516,8 +494,7 @@ static CURLcode retrycheck(struct OperationConfig *config, int rc; /* We have written data to an output file, we truncate file */ fflush(outs->stream); - notef(config->global, - "Throwing away %" CURL_FORMAT_CURL_OFF_T " bytes", + notef("Throwing away %" CURL_FORMAT_CURL_OFF_T " bytes", outs->bytes); /* truncate file at the position where we started appending */ #if defined(HAVE_FTRUNCATE) && !defined(__DJGPP__) && !defined(__AMIGA__) && \ @@ -525,7 +502,7 @@ static CURLcode retrycheck(struct OperationConfig *config, if(ftruncate(fileno(outs->stream), outs->init)) { /* when truncate fails, we cannot just append as then we will create something strange, bail out */ - errorf(config->global, "Failed to truncate file"); + errorf("Failed to truncate file"); return CURLE_WRITE_ERROR; } /* now seek to the end of the file, the position where we @@ -539,7 +516,7 @@ static CURLcode retrycheck(struct OperationConfig *config, rc = fseek(outs->stream, (long)outs->init, SEEK_SET); #endif if(rc) { - errorf(config->global, "Failed seeking to end of file"); + errorf("Failed seeking to end of file"); return CURLE_WRITE_ERROR; } outs->bytes = 0; /* clear for next round */ @@ -548,16 +525,16 @@ static CURLcode retrycheck(struct OperationConfig *config, *retryp = TRUE; per->num_retries++; *delayms = sleeptime; + result = CURLE_OK; } - return CURLE_OK; + return result; } /* * Call this after a transfer has completed. */ -static CURLcode post_per_transfer(struct GlobalConfig *global, - struct per_transfer *per, +static CURLcode post_per_transfer(struct per_transfer *per, CURLcode result, bool *retryp, long *delay) /* milliseconds! */ @@ -573,8 +550,22 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, if(!curl || !config) return result; - if(per->infdopen) - close(per->infd); + if(per->uploadfile) { + if(!strcmp(per->uploadfile, ".") && per->infd > 0) { +#if defined(_WIN32) && !defined(CURL_WINDOWS_UWP) && !defined(UNDER_CE) + sclose(per->infd); +#else + warnf("Closing per->infd != 0: FD == " + "%d. This behavior is only supported on desktop " + " Windows", per->infd); +#endif + } + } + else { + if(per->infdopen) { + close(per->infd); + } + } if(per->skip) goto skip; @@ -611,7 +602,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, if(!result && config->xattr && outs->fopened && outs->stream) { rc = fwrite_xattr(curl, per->url, fileno(outs->stream)); if(rc) - warnf(config->global, "Error setting extended attributes on '%s': %s", + warnf("Error setting extended attributes on '%s': %s", outs->filename, strerror(errno)); } @@ -633,7 +624,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, if(!result && rc) { /* something went wrong in the writing process */ result = CURLE_WRITE_ERROR; - errorf(global, "Failed writing body"); + errorf("Failed writing body"); } } @@ -646,9 +637,9 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, /* if retry-max-time is non-zero, make sure we have not exceeded the time */ if(per->retry_remaining && - (!config->retry_maxtime || + (!config->retry_maxtime_ms || (curlx_timediff(curlx_now(), per->retrystart) < - config->retry_maxtime*1000L)) ) { + config->retry_maxtime_ms)) ) { result = retrycheck(config, per, result, retryp, delay); if(!result && *retryp) return CURLE_OK; /* retry! */ @@ -666,19 +657,19 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, if(!result && rc) { /* something went wrong in the writing process */ result = CURLE_WRITE_ERROR; - errorf(config->global, "curl: (%d) Failed writing body", result); + errorf("curl: (%d) Failed writing body", result); } if(result && config->rm_partial) { struct_stat st; if(!stat(outs->filename, &st) && S_ISREG(st.st_mode)) { if(!unlink(outs->filename)) - notef(global, "Removed output file: %s", outs->filename); + notef("Removed output file: %s", outs->filename); else - warnf(global, "Failed removing: %s", outs->filename); + warnf("Failed removing: %s", outs->filename); } else - warnf(global, "Skipping removal; not a regular file: %s", + warnf("Skipping removal; not a regular file: %s", outs->filename); } } @@ -688,7 +679,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, /* Ask libcurl if we got a remote file time */ curl_off_t filetime = -1; curl_easy_getinfo(curl, CURLINFO_FILETIME_T, &filetime); - setfiletime(filetime, outs->filename, global); + setfiletime(filetime, outs->filename); } skip: /* Write the --write-out data before cleanup but after result is final */ @@ -761,8 +752,7 @@ static CURLcode set_cert_types(struct OperationConfig *config) return CURLE_OK; } -static CURLcode append2query(struct GlobalConfig *global, - struct OperationConfig *config, +static CURLcode append2query(struct OperationConfig *config, struct per_transfer *per, const char *q) { @@ -774,7 +764,7 @@ static CURLcode append2query(struct GlobalConfig *global, CURLU_GUESS_SCHEME); if(uerr) { result = urlerr_cvt(uerr); - errorf(global, "(%d) Could not parse the URL, " + errorf("(%d) Could not parse the URL, " "failed to set query", result); config->synthetic_error = TRUE; } @@ -796,8 +786,7 @@ static CURLcode append2query(struct GlobalConfig *global, return result; } -static CURLcode etag_compare(struct GlobalConfig *global, - struct OperationConfig *config) +static CURLcode etag_compare(struct OperationConfig *config) { CURLcode result = CURLE_OK; char *etag_from_file = NULL; @@ -807,7 +796,7 @@ static CURLcode etag_compare(struct GlobalConfig *global, /* open file for reading: */ FILE *file = fopen(config->etag_compare_file, FOPEN_READTEXT); if(!file) - warnf(global, "Failed to open %s: %s", config->etag_compare_file, + warnf("Failed to open %s: %s", config->etag_compare_file, strerror(errno)); if((PARAM_OK == file2string(&etag_from_file, file)) && @@ -821,8 +810,7 @@ static CURLcode etag_compare(struct GlobalConfig *global, if(!header) { if(file) fclose(file); - errorf(global, - "Failed to allocate memory for custom etag header"); + errorf("Failed to allocate memory for custom etag header"); return CURLE_OUT_OF_MEMORY; } @@ -837,13 +825,12 @@ static CURLcode etag_compare(struct GlobalConfig *global, return result; } -static CURLcode etag_store(struct GlobalConfig *global, - struct OperationConfig *config, +static CURLcode etag_store(struct OperationConfig *config, struct OutStruct *etag_save, bool *skip) { if(config->create_dirs) { - CURLcode result = create_dir_hierarchy(config->etag_save_file, global); + CURLcode result = create_dir_hierarchy(config->etag_save_file); if(result) return result; } @@ -852,11 +839,8 @@ static CURLcode etag_store(struct GlobalConfig *global, if(strcmp(config->etag_save_file, "-")) { FILE *newfile = fopen(config->etag_save_file, "ab"); if(!newfile) { - struct State *state = &config->state; - warnf(global, "Failed creating file for saving etags: \"%s\". " + warnf("Failed creating file for saving etags: \"%s\". " "Skip this transfer", config->etag_save_file); - tool_safefree(state->outfiles); - glob_cleanup(&state->urls); *skip = TRUE; return CURLE_OK; } @@ -869,13 +853,12 @@ static CURLcode etag_store(struct GlobalConfig *global, } else { /* always use binary mode for protocol header output */ - CURL_SET_BINMODE(etag_save->stream); + CURLX_SET_BINMODE(etag_save->stream); } return CURLE_OK; } -static CURLcode setup_headerfile(struct GlobalConfig *global, - struct OperationConfig *config, +static CURLcode setup_headerfile(struct OperationConfig *config, struct per_transfer *per, struct OutStruct *heads) { @@ -883,7 +866,7 @@ static CURLcode setup_headerfile(struct GlobalConfig *global, if(!strcmp(config->headerfile, "%")) { heads->stream = stderr; /* use binary mode for protocol header output */ - CURL_SET_BINMODE(heads->stream); + CURLX_SET_BINMODE(heads->stream); } else if(strcmp(config->headerfile, "-")) { FILE *newfile; @@ -898,7 +881,7 @@ static CURLcode setup_headerfile(struct GlobalConfig *global, * that it does not need to be opened/closed for every transfer. */ if(config->create_dirs) { - CURLcode result = create_dir_hierarchy(config->headerfile, global); + CURLcode result = create_dir_hierarchy(config->headerfile); /* create_dir_hierarchy shows error upon CURLE_WRITE_ERROR */ if(result) return result; @@ -911,7 +894,7 @@ static CURLcode setup_headerfile(struct GlobalConfig *global, newfile = fopen(config->headerfile, "ab"); if(!newfile) { - errorf(global, "Failed to open %s", config->headerfile); + errorf("Failed to open %s", config->headerfile); return CURLE_WRITE_ERROR; } else { @@ -923,13 +906,12 @@ static CURLcode setup_headerfile(struct GlobalConfig *global, } else { /* always use binary mode for protocol header output */ - CURL_SET_BINMODE(heads->stream); + CURLX_SET_BINMODE(heads->stream); } return CURLE_OK; } -static CURLcode setup_outfile(struct GlobalConfig *global, - struct OperationConfig *config, +static CURLcode setup_outfile(struct OperationConfig *config, struct per_transfer *per, struct OutStruct *outs, bool *skipped) @@ -938,29 +920,30 @@ static CURLcode setup_outfile(struct GlobalConfig *global, * We have specified a filename to store the result in, or we have * decided we want to use the remote filename. */ - struct State *state = &config->state; + struct State *state = &global->state; if(!per->outfile) { /* extract the filename from the URL */ - CURLcode result = get_url_file_name(global, &per->outfile, per->url); + CURLcode result = get_url_file_name(&per->outfile, per->url); if(result) { - errorf(global, "Failed to extract a filename" + errorf("Failed to extract a filename" " from the URL to use for storage"); return result; } } - else if(state->urls) { + else if(glob_inuse(&state->urlglob)) { /* fill '#1' ... '#9' terms from URL pattern */ char *storefile = per->outfile; - CURLcode result = glob_match_url(&per->outfile, storefile, state->urls); + CURLcode result = + glob_match_url(&per->outfile, storefile, &state->urlglob); tool_safefree(storefile); if(result) { /* bad globbing */ - warnf(global, "bad output glob"); + warnf("bad output glob"); return result; } if(!*per->outfile) { - warnf(global, "output glob produces empty string"); + warnf("output glob produces empty string"); return CURLE_WRITE_ERROR; } } @@ -977,7 +960,7 @@ static CURLcode setup_outfile(struct GlobalConfig *global, file output call */ if(config->create_dirs) { - CURLcode result = create_dir_hierarchy(per->outfile, global); + CURLcode result = create_dir_hierarchy(per->outfile); /* create_dir_hierarchy shows error upon CURLE_WRITE_ERROR */ if(result) return result; @@ -987,8 +970,7 @@ static CURLcode setup_outfile(struct GlobalConfig *global, struct_stat fileinfo; if(!stat(per->outfile, &fileinfo)) { /* file is present */ - notef(global, "skips transfer, \"%s\" exists locally", - per->outfile); + notef("skips transfer, \"%s\" exists locally", per->outfile); per->skip = TRUE; *skipped = TRUE; } @@ -999,7 +981,7 @@ static CURLcode setup_outfile(struct GlobalConfig *global, of the file as it is now and open it for append instead */ struct_stat fileinfo; /* VMS -- Danger, the filesize is only valid for stream files */ - if(0 == stat(per->outfile, &fileinfo)) + if(stat(per->outfile, &fileinfo) == 0) /* set offset to current file size: */ config->resume_from = fileinfo.st_size; else @@ -1018,7 +1000,7 @@ static CURLcode setup_outfile(struct GlobalConfig *global, FILE *file = fopen(per->outfile, "ab"); #endif if(!file) { - errorf(global, "cannot open '%s'", per->outfile); + errorf("cannot open '%s'", per->outfile); return CURLE_WRITE_ERROR; } outs->fopened = TRUE; @@ -1033,8 +1015,7 @@ static CURLcode setup_outfile(struct GlobalConfig *global, return CURLE_OK; } -static void check_stdin_upload(struct GlobalConfig *global, - struct OperationConfig *config, +static void check_stdin_upload(struct OperationConfig *config, struct per_transfer *per) { /* count to see if there are more than one auth bit set @@ -1056,8 +1037,7 @@ static void check_stdin_upload(struct GlobalConfig *global, * we should warn them. */ if(config->proxyanyauth || (authbits > 1)) { - warnf(global, - "Using --anyauth or --proxy-anyauth with upload from stdin" + warnf("Using --anyauth or --proxy-anyauth with upload from stdin" " involves a big risk of it not working. Use a temporary" " file or a fixed auth type instead"); } @@ -1065,26 +1045,41 @@ static void check_stdin_upload(struct GlobalConfig *global, DEBUGASSERT(per->infdopen == FALSE); DEBUGASSERT(per->infd == STDIN_FILENO); - CURL_SET_BINMODE(stdin); + CURLX_SET_BINMODE(stdin); if(!strcmp(per->uploadfile, ".")) { +#if defined(_WIN32) && !defined(CURL_WINDOWS_UWP) && !defined(UNDER_CE) + /* non-blocking stdin behavior on Windows is challenging + Spawn a new thread that will read from stdin and write + out to a socket */ + curl_socket_t f = win32_stdin_read_thread(); + + if(f == CURL_SOCKET_BAD) + warnf("win32_stdin_read_thread returned INVALID_SOCKET " + "falling back to blocking mode"); + else if(f > INT_MAX) { + warnf("win32_stdin_read_thread returned identifier " + "larger than INT_MAX. This should not happen unless " + "the upper 32 bits of a Windows socket have started " + "being used for something... falling back to blocking " + "mode"); + sclose(f); + } + else + per->infd = (int)f; +#endif if(curlx_nonblock((curl_socket_t)per->infd, TRUE) < 0) - warnf(global, - "fcntl failed on fd=%d: %s", per->infd, strerror(errno)); + warnf("fcntl failed on fd=%d: %s", per->infd, strerror(errno)); } } /* create the next (singular) transfer */ -static CURLcode single_transfer(struct GlobalConfig *global, - struct OperationConfig *config, - CURLSH *share, - bool *added, - bool *skipped) +static CURLcode single_transfer(struct OperationConfig *config, + CURLSH *share, bool *added, bool *skipped) { CURLcode result = CURLE_OK; - struct getout *urlnode; bool orig_noprogress = global->noprogress; bool orig_isatty = global->isatty; - struct State *state = &config->state; + struct State *state = &global->state; char *httpgetfields = state->httpgetfields; *skipped = *added = FALSE; /* not yet */ @@ -1095,318 +1090,245 @@ static CURLcode single_transfer(struct GlobalConfig *global, /* Use the postfields data for an HTTP get */ httpgetfields = state->httpgetfields = config->postfields; config->postfields = NULL; - if(SetHTTPrequest(config, (config->no_body ? TOOL_HTTPREQ_HEAD : - TOOL_HTTPREQ_GET), &config->httpreq)) { - result = CURLE_FAILED_INIT; - } + if(SetHTTPrequest((config->no_body ? TOOL_HTTPREQ_HEAD : + TOOL_HTTPREQ_GET), &config->httpreq)) + return CURLE_FAILED_INIT; } } - else { - if(SetHTTPrequest(config, TOOL_HTTPREQ_SIMPLEPOST, &config->httpreq)) - result = CURLE_FAILED_INIT; - } - if(result) - goto fail; - } - if(!state->urlnode) { - /* first time caller, setup things */ - state->urlnode = config->url_list; - state->infilenum = 1; + else if(SetHTTPrequest(TOOL_HTTPREQ_SIMPLEPOST, &config->httpreq)) + return CURLE_FAILED_INIT; } result = set_cert_types(config); if(result) - goto fail; - - for(; state->urlnode; state->urlnode = urlnode->next) { - static bool warn_more_options = FALSE; - curl_off_t urlnum; - - urlnode = state->urlnode; - /* urlnode->url is the full URL or NULL */ - if(!urlnode->url) { - /* This node has no URL. Free node data without destroying the - node itself nor modifying next pointer and continue to next */ - urlnode->outset = urlnode->urlset = urlnode->useremote = - urlnode->uploadset = urlnode->noupload = urlnode->noglob = FALSE; - state->up = 0; - if(!warn_more_options) { - /* only show this once */ - warnf(config->global, "Got more output options than URLs"); - warn_more_options = TRUE; - } - continue; /* next URL please */ - } - - /* save outfile pattern before expansion */ - if(urlnode->outfile && !state->outfiles) { - state->outfiles = strdup(urlnode->outfile); - if(!state->outfiles) { - errorf(global, "out of memory"); - result = CURLE_OUT_OF_MEMORY; - break; - } - } - - if(!config->globoff && urlnode->infile && !state->inglob) { - /* Unless explicitly shut off */ - result = glob_url(&state->inglob, urlnode->infile, &state->infilenum, - (!global->silent || global->showerror) ? - tool_stderr : NULL); - if(result) - break; - } - + return result; - if(state->up || urlnode->infile) { + if(!state->urlnode) { + /* first time caller, setup things */ + state->urlnode = config->url_list; + state->upnum = 1; + } + + while(state->urlnode) { + struct per_transfer *per = NULL; + struct OutStruct *outs; + struct OutStruct *heads; + struct HdrCbData *hdrcbdata = NULL; + struct OutStruct etag_first; + CURL *curl; + struct getout *u = state->urlnode; + FILE *err = (!global->silent || global->showerror) ? tool_stderr : NULL; + + if(u->infile) { + if(!config->globoff && !glob_inuse(&state->inglob)) + result = glob_url(&state->inglob, u->infile, &state->upnum, err); if(!state->uploadfile) { - if(state->inglob) { - result = glob_next_url(&state->uploadfile, state->inglob); - if(result == CURLE_OUT_OF_MEMORY) - errorf(global, "out of memory"); - } - else if(!state->up) { + if(glob_inuse(&state->inglob)) + result = glob_next_url(&state->uploadfile, &state->inglob); + else if(!state->upidx) { /* copy the allocated string */ - state->uploadfile = urlnode->infile; - urlnode->infile = NULL; + state->uploadfile = u->infile; + u->infile = NULL; } } if(result) + return result; + } + + if(state->upidx >= state->upnum) { + state->urlnum = 0; + tool_safefree(state->uploadfile); + glob_cleanup(&state->inglob); + state->upidx = 0; + state->urlnode = u->next; /* next node */ + if(state->urlnode && !state->urlnode->url) { + /* This node has no URL. End of the road. */ + warnf("Got more output options than URLs"); break; + } + continue; } if(!state->urlnum) { - if(!config->globoff && !urlnode->noglob) { + if(!config->globoff && !u->noglob) { /* Unless explicitly shut off, we expand '{...}' and '[...]' expressions and return total number of URLs in pattern set */ - result = glob_url(&state->urls, urlnode->url, &state->urlnum, - (!global->silent || global->showerror) ? - tool_stderr : NULL); + result = glob_url(&state->urlglob, u->url, &state->urlnum, err); if(result) - break; - urlnum = state->urlnum; + return result; } else - urlnum = 1; /* without globbing, this is a single URL */ + state->urlnum = 1; /* without globbing, this is a single URL */ } - else - urlnum = state->urlnum; - - if(state->up < state->infilenum) { - struct per_transfer *per = NULL; - struct OutStruct *outs; - struct OutStruct *heads; - struct OutStruct *etag_save; - struct HdrCbData *hdrcbdata = NULL; - struct OutStruct etag_first; - CURL *curl; - - /* --etag-save */ - memset(&etag_first, 0, sizeof(etag_first)); - etag_save = &etag_first; - etag_save->stream = stdout; - - /* --etag-compare */ - if(config->etag_compare_file) { - result = etag_compare(global, config); - if(result) - break; - } - if(config->etag_save_file) { - bool badetag = FALSE; - result = etag_store(global, config, etag_save, &badetag); - if(result || badetag) - break; - } + /* --etag-save */ + memset(&etag_first, 0, sizeof(etag_first)); + etag_first.stream = stdout; - curl = curl_easy_init(); - if(curl) - result = add_per_transfer(&per); - else - result = CURLE_OUT_OF_MEMORY; - if(result) { - curl_easy_cleanup(curl); - if(etag_save->fopened) - fclose(etag_save->stream); + /* --etag-compare */ + if(config->etag_compare_file) { + result = etag_compare(config); + if(result) + return result; + } + + if(config->etag_save_file) { + bool badetag = FALSE; + result = etag_store(config, &etag_first, &badetag); + if(result || badetag) break; + } + + curl = curl_easy_init(); + if(curl) + result = add_per_transfer(&per); + else + result = CURLE_OUT_OF_MEMORY; + if(result) { + curl_easy_cleanup(curl); + if(etag_first.fopened) + fclose(etag_first.stream); + return result; + } + per->etag_save = etag_first; /* copy the whole struct */ + if(state->uploadfile) { + per->uploadfile = strdup(state->uploadfile); + if(!per->uploadfile || + SetHTTPrequest(TOOL_HTTPREQ_PUT, &config->httpreq)) { + tool_safefree(per->uploadfile); + curl_easy_cleanup(curl); + return CURLE_FAILED_INIT; } - per->etag_save = etag_first; /* copy the whole struct */ - if(state->uploadfile) { - per->uploadfile = strdup(state->uploadfile); - if(!per->uploadfile) { - curl_easy_cleanup(curl); - result = CURLE_OUT_OF_MEMORY; - break; - } - if(SetHTTPrequest(config, TOOL_HTTPREQ_PUT, &config->httpreq)) { - tool_safefree(per->uploadfile); - curl_easy_cleanup(curl); - result = CURLE_FAILED_INIT; - break; - } - } - *added = TRUE; - per->config = config; - per->curl = curl; - per->urlnum = (unsigned int)urlnode->num; - - /* default headers output stream is stdout */ - heads = &per->heads; - heads->stream = stdout; - - /* Single header file for all URLs */ - if(config->headerfile) { - result = setup_headerfile(global, config, per, heads); - if(result) - break; - } - hdrcbdata = &per->hdrcbdata; + } + per->config = config; + per->curl = curl; + per->urlnum = u->num; - outs = &per->outs; + /* default headers output stream is stdout */ + heads = &per->heads; + heads->stream = stdout; - per->outfile = NULL; - per->infdopen = FALSE; - per->infd = STDIN_FILENO; + /* Single header file for all URLs */ + if(config->headerfile) { + result = setup_headerfile(config, per, heads); + if(result) + return result; + } + hdrcbdata = &per->hdrcbdata; - /* default output stream is stdout */ - outs->stream = stdout; + outs = &per->outs; - if(state->urls) { - result = glob_next_url(&per->url, state->urls); - if(result) - break; - } - else if(!state->li) { - per->url = strdup(urlnode->url); - if(!per->url) { - result = CURLE_OUT_OF_MEMORY; - break; - } - } - else - per->url = NULL; - if(!per->url) - break; + per->outfile = NULL; + per->infdopen = FALSE; + per->infd = STDIN_FILENO; - if(state->outfiles) { - per->outfile = strdup(state->outfiles); - if(!per->outfile) { - result = CURLE_OUT_OF_MEMORY; - break; - } - } + /* default output stream is stdout */ + outs->stream = stdout; - if((urlnode->useremote || - (per->outfile && strcmp("-", per->outfile)))) { - result = setup_outfile(global, config, per, outs, skipped); - if(result) - break; - } + if(glob_inuse(&state->urlglob)) + result = glob_next_url(&per->url, &state->urlglob); + else if(!state->urlidx) { + per->url = strdup(u->url); + if(!per->url) + result = CURLE_OUT_OF_MEMORY; + } + else { + per->url = NULL; + break; + } + if(result) + return result; - if(per->uploadfile) { - - if(stdin_upload(per->uploadfile)) - check_stdin_upload(global, config, per); - else { - /* - * We have specified a file to upload and it is not "-". - */ - result = add_file_name_to_url(per->curl, &per->url, - per->uploadfile); - if(result) - break; - } - } + if(u->outfile) { + per->outfile = strdup(u->outfile); + if(!per->outfile) + return CURLE_OUT_OF_MEMORY; + } - if(per->uploadfile && config->resume_from_current) - config->resume_from = -1; /* -1 will then force get-it-yourself */ + outs->out_null = u->out_null; + if(!outs->out_null && + (u->useremote || (per->outfile && strcmp("-", per->outfile)))) { + result = setup_outfile(config, per, outs, skipped); + if(result) + return result; + } - if(output_expected(per->url, per->uploadfile) && outs->stream && - isatty(fileno(outs->stream))) - /* we send the output to a tty, therefore we switch off the progress - meter */ - per->noprogress = global->noprogress = global->isatty = TRUE; - else { - /* progress meter is per download, so restore config - values */ - per->noprogress = global->noprogress = orig_noprogress; - global->isatty = orig_isatty; - } + if(per->uploadfile) { - if(httpgetfields || config->query) { - result = append2query(global, config, per, - httpgetfields ? httpgetfields : config->query); + if(stdin_upload(per->uploadfile)) + check_stdin_upload(config, per); + else { + /* + * We have specified a file to upload and it is not "-". + */ + result = add_file_name_to_url(per->curl, &per->url, + per->uploadfile); if(result) - break; + return result; } - if((!per->outfile || !strcmp(per->outfile, "-")) && - !config->use_ascii) { - /* We get the output to stdout and we have not got the ASCII/text - flag, then set stdout to be binary */ - CURL_SET_BINMODE(stdout); - } - - /* explicitly passed to stdout means okaying binary gunk */ - config->terminal_binary_ok = - (per->outfile && !strcmp(per->outfile, "-")); - - if(config->content_disposition && urlnode->useremote) - hdrcbdata->honor_cd_filename = TRUE; - else - hdrcbdata->honor_cd_filename = FALSE; + if(config->resume_from_current) + config->resume_from = -1; /* -1 will then force get-it-yourself */ + } - hdrcbdata->outs = outs; - hdrcbdata->heads = heads; - hdrcbdata->etag_save = etag_save; - hdrcbdata->global = global; - hdrcbdata->config = config; + if(output_expected(per->url, per->uploadfile) && outs->stream && + isatty(fileno(outs->stream))) + /* we send the output to a tty, therefore we switch off the progress + meter */ + per->noprogress = global->noprogress = global->isatty = TRUE; + else { + /* progress meter is per download, so restore config + values */ + per->noprogress = global->noprogress = orig_noprogress; + global->isatty = orig_isatty; + } - result = config2setopts(global, config, per, curl, share); + if(httpgetfields || config->query) { + result = append2query(config, per, + httpgetfields ? httpgetfields : config->query); if(result) - break; + return result; + } - /* initialize retry vars for loop below */ - per->retry_sleep_default = (config->retry_delay) ? - config->retry_delay*1000L : RETRY_SLEEP_DEFAULT; /* ms */ - per->retry_remaining = config->req_retry; - per->retry_sleep = per->retry_sleep_default; /* ms */ - per->retrystart = curlx_now(); - - state->li++; - /* Here's looping around each globbed URL */ - if(state->li >= urlnum) { - state->li = 0; - state->urlnum = 0; /* forced reglob of URLs */ - glob_cleanup(&state->urls); - state->up++; - tool_safefree(state->uploadfile); /* clear it to get the next */ - } + if((!per->outfile || !strcmp(per->outfile, "-")) && + !config->use_ascii) { + /* We get the output to stdout and we have not got the ASCII/text flag, + then set stdout to be binary */ + CURLX_SET_BINMODE(stdout); } - else { - /* Free this URL node data without destroying the - node itself nor modifying next pointer. */ - urlnode->outset = urlnode->urlset = urlnode->useremote = - urlnode->uploadset = urlnode->noupload = urlnode->noglob = FALSE; - glob_cleanup(&state->urls); - state->urlnum = 0; - tool_safefree(state->outfiles); - tool_safefree(state->uploadfile); - /* Free list of globbed upload files */ - glob_cleanup(&state->inglob); - state->up = 0; - continue; + /* explicitly passed to stdout means okaying binary gunk */ + config->terminal_binary_ok = + (per->outfile && !strcmp(per->outfile, "-")); + + hdrcbdata->honor_cd_filename = + (config->content_disposition && u->useremote); + hdrcbdata->outs = outs; + hdrcbdata->heads = heads; + hdrcbdata->etag_save = &etag_first; + hdrcbdata->config = config; + + result = config2setopts(config, per, curl, share); + if(result) + return result; + + /* initialize retry vars for loop below */ + per->retry_sleep_default = config->retry_delay_ms; + per->retry_remaining = config->req_retry; + per->retry_sleep = per->retry_sleep_default; /* ms */ + per->retrystart = curlx_now(); + + state->urlidx++; + /* Here's looping around each globbed URL */ + if(state->urlidx >= state->urlnum) { + state->urlidx = state->urlnum = 0; + glob_cleanup(&state->urlglob); + state->upidx++; + tool_safefree(state->uploadfile); /* clear it to get the next */ } + *added = TRUE; break; } - tool_safefree(state->outfiles); -fail: - if(!*added || result) { - *added = FALSE; - single_transfer_cleanup(config); - } return result; } @@ -1417,23 +1339,28 @@ static long all_added; /* number of easy handles currently added */ * to add even after this call returns. sets 'addedp' to TRUE if one or more * transfers were added. */ -static CURLcode add_parallel_transfers(struct GlobalConfig *global, - CURLM *multi, - CURLSH *share, - bool *morep, - bool *addedp) +static CURLcode add_parallel_transfers(CURLM *multi, CURLSH *share, + bool *morep, bool *addedp) { struct per_transfer *per; CURLcode result = CURLE_OK; CURLMcode mcode; bool sleeping = FALSE; char *errorbuf; + curl_off_t nxfers; + *addedp = FALSE; *morep = FALSE; - if(all_pers < (global->parallel_max*2)) { + mcode = curl_multi_get_offt(multi, CURLMINFO_XFERS_CURRENT, &nxfers); + if(mcode) { + DEBUGASSERT(0); + return CURLE_UNKNOWN_OPTION; + } + + if(nxfers < (curl_off_t)(global->parallel_max*2)) { bool skipped = FALSE; do { - result = create_transfer(global, share, addedp, &skipped); + result = create_transfer(share, addedp, &skipped); if(result) return result; } while(skipped); @@ -1450,7 +1377,7 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global, } per->added = TRUE; - result = pre_transfer(global, per); + result = pre_transfer(per); if(result) return result; @@ -1463,6 +1390,8 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global, (void)curl_easy_setopt(per->curl, CURLOPT_PIPEWAIT, global->parallel_connect ? 0L : 1L); (void)curl_easy_setopt(per->curl, CURLOPT_PRIVATE, per); + /* curl does not use signals, switching this on saves some system calls */ + (void)curl_easy_setopt(per->curl, CURLOPT_NOSIGNAL, 1L); (void)curl_easy_setopt(per->curl, CURLOPT_XFERINFOFUNCTION, xferinfo_cb); (void)curl_easy_setopt(per->curl, CURLOPT_XFERINFODATA, per); (void)curl_easy_setopt(per->curl, CURLOPT_NOPROGRESS, 0L); @@ -1481,7 +1410,7 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global, bool getadded = FALSE; bool skipped = FALSE; do { - result = create_transfer(global, share, &getadded, &skipped); + result = create_transfer(share, &getadded, &skipped); if(result) break; } while(skipped); @@ -1502,7 +1431,6 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global, } struct parastate { - struct GlobalConfig *global; CURLM *multi; CURLSH *share; CURLMcode mcode; @@ -1546,8 +1474,7 @@ static void check_multi_info(struct datauv *uv) uv->s->result = result; if(uv->s->more_transfers) { - result = add_parallel_transfers(uv->s->global, uv->s->multi, - uv->s->share, + result = add_parallel_transfers(uv->s->multi, uv->s->share, &uv->s->more_transfers, &uv->s->added_transfers); if(result && !uv->s->result) @@ -1695,6 +1622,8 @@ static CURLcode parallel_event(struct parastate *s) curl_multi_setopt(s->multi, CURLMOPT_SOCKETDATA, &uv); curl_multi_setopt(s->multi, CURLMOPT_TIMERFUNCTION, cb_timeout); curl_multi_setopt(s->multi, CURLMOPT_TIMERDATA, &uv); + curl_multi_setopt(s->multi, CURLMOPT_MAX_HOST_CONNECTIONS, + global->parallel_host); /* kickstart the thing */ curl_multi_socket_action(s->multi, CURL_SOCKET_TIMEOUT, 0, @@ -1728,8 +1657,8 @@ static CURLcode parallel_event(struct parastate *s) } if(s->more_transfers) { - result = add_parallel_transfers(s->global, s->multi, s->share, - &s->more_transfers, &s->added_transfers); + result = add_parallel_transfers(s->multi, s->share, &s->more_transfers, + &s->added_transfers); if(result && !s->result) s->result = result; } @@ -1765,8 +1694,7 @@ static CURLcode check_finished(struct parastate *s) int rc; CURLMsg *msg; bool checkmore = FALSE; - struct GlobalConfig *global = s->global; - progress_meter(global, &s->start, FALSE); + progress_meter(s->multi, &s->start, FALSE); do { msg = curl_multi_info_read(s->multi, &rc); if(msg) { @@ -1784,7 +1712,7 @@ static CURLcode check_finished(struct parastate *s) "Transfer aborted due to critical error " "in another transfer"); } - tres = post_per_transfer(global, ended, tres, &retry, &delay); + tres = post_per_transfer(ended, tres, &retry, &delay); progress_finalize(ended); /* before it goes away */ all_added--; /* one fewer added */ checkmore = TRUE; @@ -1814,7 +1742,7 @@ static CURLcode check_finished(struct parastate *s) } if(checkmore) { /* one or more transfers completed, add more! */ - CURLcode tres = add_parallel_transfers(global, s->multi, s->share, + CURLcode tres = add_parallel_transfers(s->multi, s->share, &s->more_transfers, &s->added_transfers); if(tres) @@ -1829,8 +1757,7 @@ static CURLcode check_finished(struct parastate *s) return result; } -static CURLcode parallel_transfers(struct GlobalConfig *global, - CURLSH *share) +static CURLcode parallel_transfers(CURLSH *share) { CURLcode result; struct parastate p; @@ -1843,12 +1770,11 @@ static CURLcode parallel_transfers(struct GlobalConfig *global, s->wrapitup = FALSE; s->wrapitup_processed = FALSE; s->tick = time(NULL); - s->global = global; s->multi = curl_multi_init(); if(!s->multi) return CURLE_OUT_OF_MEMORY; - result = add_parallel_transfers(global, s->multi, s->share, + result = add_parallel_transfers(s->multi, s->share, &s->more_transfers, &s->added_transfers); if(result) { curl_multi_cleanup(s->multi); @@ -1860,7 +1786,7 @@ static CURLcode parallel_transfers(struct GlobalConfig *global, #ifdef USE_LIBUV return parallel_event(s); #else - errorf(global, "Testing --parallel event-based requires libuv"); + errorf("Testing --parallel event-based requires libuv"); #endif else #endif @@ -1890,7 +1816,7 @@ static CURLcode parallel_transfers(struct GlobalConfig *global, result = check_finished(s); } - (void)progress_meter(global, &s->start, TRUE); + (void)progress_meter(s->multi, &s->start, TRUE); } /* Make sure to return some kind of error if there was a multi problem */ @@ -1906,8 +1832,7 @@ static CURLcode parallel_transfers(struct GlobalConfig *global, return result; } -static CURLcode serial_transfers(struct GlobalConfig *global, - CURLSH *share) +static CURLcode serial_transfers(CURLSH *share) { CURLcode returncode = CURLE_OK; CURLcode result = CURLE_OK; @@ -1915,11 +1840,11 @@ static CURLcode serial_transfers(struct GlobalConfig *global, bool added = FALSE; bool skipped = FALSE; - result = create_transfer(global, share, &added, &skipped); + result = create_transfer(share, &added, &skipped); if(result) return result; if(!added) { - errorf(global, "no transfer performed"); + errorf("no transfer performed"); return CURLE_READ_ERROR; } for(per = transfers; per;) { @@ -1930,7 +1855,7 @@ static CURLcode serial_transfers(struct GlobalConfig *global, start = curlx_now(); if(!per->skip) { - result = pre_transfer(global, per); + result = pre_transfer(per); if(result) break; @@ -1962,9 +1887,9 @@ static CURLcode serial_transfers(struct GlobalConfig *global, result = curl_easy_perform(per->curl); } - returncode = post_per_transfer(global, per, result, &retry, &delay_ms); + returncode = post_per_transfer(per, result, &retry, &delay_ms); if(retry) { - tool_go_sleep(delay_ms); + curlx_wait_ms(delay_ms); continue; } @@ -1974,7 +1899,7 @@ static CURLcode serial_transfers(struct GlobalConfig *global, else { do { /* setup the next one just before we delete this */ - result = create_transfer(global, share, &added, &skipped); + result = create_transfer(share, &added, &skipped); if(result) { returncode = result; bailout = TRUE; @@ -1993,11 +1918,11 @@ static CURLcode serial_transfers(struct GlobalConfig *global, milliseconds */ timediff_t milli = curlx_timediff(curlx_now(), start); if(milli < global->ms_per_transfer) { - notef(global, "Transfer took %" CURL_FORMAT_CURL_OFF_T " ms, " - "waits %ldms as set by --rate", + notef("Transfer took %" CURL_FORMAT_CURL_OFF_T " ms, " + "waits %ldms as set by --rate", milli, (long)(global->ms_per_transfer - milli)); /* The transfer took less time than wanted. Wait a little. */ - tool_go_sleep((long)(global->ms_per_transfer - milli)); + curlx_wait_ms((long)(global->ms_per_transfer - milli)); } } } @@ -2006,7 +1931,7 @@ static CURLcode serial_transfers(struct GlobalConfig *global, result = returncode; if(result) - single_transfer_cleanup(global->current); + single_transfer_cleanup(); return result; } @@ -2077,7 +2002,7 @@ static CURLcode cacertpaths(struct OperationConfig *config) #ifdef _WIN32 if(!env) { -#if defined(CURL_CA_SEARCH_SAFE) +#ifdef CURL_CA_SEARCH_SAFE char *cacert = NULL; FILE *cafile = tool_execpath("curl-ca-bundle.crt", &cacert); if(cafile) { @@ -2099,8 +2024,7 @@ static CURLcode cacertpaths(struct OperationConfig *config) } /* setup a transfer for the given config */ -static CURLcode transfer_per_config(struct GlobalConfig *global, - struct OperationConfig *config, +static CURLcode transfer_per_config(struct OperationConfig *config, CURLSH *share, bool *added, bool *skipped) @@ -2110,7 +2034,7 @@ static CURLcode transfer_per_config(struct GlobalConfig *global, /* Check we have a url */ if(!config->url_list || !config->url_list->url) { - helpf(tool_stderr, "(%d) no URL specified", CURLE_FAILED_INIT); + helpf("(%d) no URL specified", CURLE_FAILED_INIT); return CURLE_FAILED_INIT; } @@ -2139,8 +2063,11 @@ static CURLcode transfer_per_config(struct GlobalConfig *global, result = cacertpaths(config); } - if(!result) - result = single_transfer(global, config, share, added, skipped); + if(!result) { + result = single_transfer(config, share, added, skipped); + if(!*added || result) + single_transfer_cleanup(); + } return result; } @@ -2149,16 +2076,14 @@ static CURLcode transfer_per_config(struct GlobalConfig *global, * 'create_transfer' gets the details and sets up a new transfer if 'added' * returns TRUE. */ -static CURLcode create_transfer(struct GlobalConfig *global, - CURLSH *share, +static CURLcode create_transfer(CURLSH *share, bool *added, bool *skipped) { CURLcode result = CURLE_OK; *added = FALSE; while(global->current) { - result = transfer_per_config(global, global->current, share, added, - skipped); + result = transfer_per_config(global->current, share, added, skipped); if(!result && !*added) { /* when one set is drained, continue to next */ global->current = global->current->next; @@ -2169,8 +2094,7 @@ static CURLcode create_transfer(struct GlobalConfig *global, return result; } -static CURLcode run_all_transfers(struct GlobalConfig *global, - CURLSH *share, +static CURLcode run_all_transfers(CURLSH *share, CURLcode result) { /* Save the values of noprogress and isatty to restore them later on */ @@ -2181,16 +2105,16 @@ static CURLcode run_all_transfers(struct GlobalConfig *global, /* Time to actually do the transfers */ if(!result) { if(global->parallel) - result = parallel_transfers(global, share); + result = parallel_transfers(share); else - result = serial_transfers(global, share); + result = serial_transfers(share); } /* cleanup if there are any left */ for(per = transfers; per;) { bool retry; long delay; - CURLcode result2 = post_per_transfer(global, per, result, &retry, &delay); + CURLcode result2 = post_per_transfer(per, result, &retry, &delay); if(!result) /* do not overwrite the original error */ result = result2; @@ -2209,7 +2133,7 @@ static CURLcode run_all_transfers(struct GlobalConfig *global, return result; } -CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) +CURLcode operate(int argc, argv_item_t argv[]) { CURLcode result = CURLE_OK; const char *first_arg; @@ -2229,11 +2153,11 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) if((argc == 1) || (first_arg && strncmp(first_arg, "-q", 2) && strcmp(first_arg, "--disable"))) { - parseconfig(NULL, global); /* ignore possible failure */ + parseconfig(NULL); /* ignore possible failure */ /* If we had no arguments then make sure a url was specified in .curlrc */ if((argc < 2) && (!global->first->url_list)) { - helpf(tool_stderr, NULL); + helpf(NULL); result = CURLE_FAILED_INIT; } } @@ -2242,7 +2166,7 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) if(!result) { /* Parse the command line arguments */ - ParameterError res = parse_args(global, argc, argv); + ParameterError res = parse_args(argc, argv); if(res) { result = CURLE_OK; @@ -2254,8 +2178,7 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) #ifdef USE_MANUAL hugehelp(); #else - warnf(global, - "built-in manual was disabled at build-time"); + warnf("built-in manual was disabled at build-time"); #endif } /* Check if we were asked for the version information */ @@ -2308,7 +2231,7 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_HSTS); if(global->ssl_sessions && feature_ssls_export) - result = tool_ssls_load(global, global->first, share, + result = tool_ssls_load(global->first, share, global->ssl_sessions); if(!result) { @@ -2323,10 +2246,10 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) global->current = global->first; /* now run! */ - result = run_all_transfers(global, share, result); + result = run_all_transfers(share, result); if(global->ssl_sessions && feature_ssls_export) { - CURLcode r2 = tool_ssls_save(global, global->first, share, + CURLcode r2 = tool_ssls_save(global->first, share, global->ssl_sessions); if(r2 && !result) result = r2; @@ -2339,16 +2262,16 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) easysrc_cleanup(); /* Dump the libcurl code if previously enabled */ - dumpeasysrc(global); + dumpeasysrc(); } } } else - errorf(global, "out of memory"); + errorf("out of memory"); } } - varcleanup(global); + varcleanup(); curl_free(global->knownhosts); return result; diff --git a/vendor/curl/src/tool_operate.h b/vendor/curl/src/tool_operate.h index 88fb5f98961..a323271b76d 100644 --- a/vendor/curl/src/tool_operate.h +++ b/vendor/curl/src/tool_operate.h @@ -42,7 +42,7 @@ struct per_transfer { struct curltime start; /* start of this transfer */ struct curltime retrystart; char *url; - unsigned int urlnum; /* the index of the given URL */ + curl_off_t urlnum; /* the index of the given URL */ char *outfile; int infd; struct ProgressData progressbar; @@ -79,8 +79,8 @@ struct per_transfer { BIT(skip); /* considered already done */ }; -CURLcode operate(struct GlobalConfig *config, int argc, argv_item_t argv[]); -void single_transfer_cleanup(struct OperationConfig *config); +CURLcode operate(int argc, argv_item_t argv[]); +void single_transfer_cleanup(void); extern struct per_transfer *transfers; /* first node */ diff --git a/vendor/curl/src/tool_operhlp.c b/vendor/curl/src/tool_operhlp.c index 6a6cf202c8b..fdf64723697 100644 --- a/vendor/curl/src/tool_operhlp.c +++ b/vendor/curl/src/tool_operhlp.c @@ -24,12 +24,11 @@ #include "tool_setup.h" #include "tool_operate.h" -#include #include "tool_cfgable.h" #include "tool_doswin.h" #include "tool_operhlp.h" #include "tool_msgs.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ void clean_getout(struct OperationConfig *config) { @@ -46,8 +45,8 @@ void clean_getout(struct OperationConfig *config) node = next; } config->url_list = NULL; + single_transfer_cleanup(); } - single_transfer_cleanup(config); } bool output_expected(const char *url, const char *uploadfile) @@ -174,8 +173,7 @@ CURLcode add_file_name_to_url(CURL *curl, char **inurlp, const char *filename) * Returns a pointer to a heap-allocated string or NULL if * no name part, at location indicated by first argument. */ -CURLcode get_url_file_name(struct GlobalConfig *global, - char **filename, const char *url) +CURLcode get_url_file_name(char **filename, const char *url) { CURLU *uh = curl_url(); char *path = NULL; @@ -213,7 +211,7 @@ CURLcode get_url_file_name(struct GlobalConfig *global, else { /* no slash => empty string, use default */ *filename = strdup("curl_response"); - warnf(global, "No remote file name, uses \"%s\"", *filename); + warnf("No remote file name, uses \"%s\"", *filename); } curl_free(path); diff --git a/vendor/curl/src/tool_operhlp.h b/vendor/curl/src/tool_operhlp.h index 19daa8e430e..c83c10a591e 100644 --- a/vendor/curl/src/tool_operhlp.h +++ b/vendor/curl/src/tool_operhlp.h @@ -28,16 +28,10 @@ struct OperationConfig; void clean_getout(struct OperationConfig *config); - bool output_expected(const char *url, const char *uploadfile); - bool stdin_upload(const char *uploadfile); - CURLcode add_file_name_to_url(CURL *curl, char **inurlp, const char *filename); - -CURLcode get_url_file_name(struct GlobalConfig *global, - char **filename, const char *url); - +CURLcode get_url_file_name(char **filename, const char *url); CURLcode urlerr_cvt(CURLUcode ucode); #endif /* HEADER_CURL_TOOL_OPERHLP_H */ diff --git a/vendor/curl/src/tool_paramhlp.c b/vendor/curl/src/tool_paramhlp.c index 0a3bc91fb93..a1505115b3f 100644 --- a/vendor/curl/src/tool_paramhlp.c +++ b/vendor/curl/src/tool_paramhlp.c @@ -23,8 +23,6 @@ ***************************************************************************/ #include "tool_setup.h" -#include - #include "tool_cfgable.h" #include "tool_getparam.h" #include "tool_getpass.h" @@ -34,7 +32,7 @@ #include "tool_util.h" #include "tool_version.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ struct getout *new_getout(struct OperationConfig *config) { @@ -323,7 +321,7 @@ ParameterError secs2ms(long *valp, const char *str) { curl_off_t secs; long ms = 0; - const unsigned int digs[] = { 1, 10, 100, 1000, 10000, 1000000, + const unsigned int digs[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 }; if(!str || curlx_str_number(&str, &secs, LONG_MAX/1000 - 1)) @@ -336,7 +334,7 @@ ParameterError secs2ms(long *valp, const char *str) return PARAM_NUMBER_TOO_LARGE; /* how many milliseconds are in fracs ? */ len = (str - s); - while((len > sizeof(CURL_ARRAYSIZE(digs)) || (fracs > LONG_MAX/100))) { + while((len > CURL_ARRAYSIZE(digs) || (fracs > LONG_MAX/100))) { fracs /= 10; len--; } @@ -407,8 +405,7 @@ static void protoset_clear(const char **protoset, const char *proto) #define MAX_PROTOSTRING (64*11) /* Enough room for 64 10-chars proto names. */ -ParameterError proto2num(struct OperationConfig *config, - const char * const *val, char **ostr, const char *str) +ParameterError proto2num(const char * const *val, char **ostr, const char *str) { const char **protoset; struct dynbuf obuf; @@ -499,7 +496,7 @@ ParameterError proto2num(struct OperationConfig *config, if no protocols are allowed */ if(action == set) protoset[0] = NULL; - warnf(config->global, "unrecognized protocol '%s'", buffer); + warnf("unrecognized protocol '%s'", buffer); } } if(next) @@ -622,7 +619,7 @@ ParameterError add2list(struct curl_slist **list, const char *ptr) return PARAM_OK; } -int ftpfilemethod(struct OperationConfig *config, const char *str) +long ftpfilemethod(const char *str) { if(curl_strequal("singlecwd", str)) return CURLFTPMETHOD_SINGLECWD; @@ -631,26 +628,24 @@ int ftpfilemethod(struct OperationConfig *config, const char *str) if(curl_strequal("multicwd", str)) return CURLFTPMETHOD_MULTICWD; - warnf(config->global, "unrecognized ftp file method '%s', using default", - str); + warnf("unrecognized ftp file method '%s', using default", str); return CURLFTPMETHOD_MULTICWD; } -int ftpcccmethod(struct OperationConfig *config, const char *str) +long ftpcccmethod(const char *str) { if(curl_strequal("passive", str)) return CURLFTPSSL_CCC_PASSIVE; if(curl_strequal("active", str)) return CURLFTPSSL_CCC_ACTIVE; - warnf(config->global, "unrecognized ftp CCC method '%s', using default", - str); + warnf("unrecognized ftp CCC method '%s', using default", str); return CURLFTPSSL_CCC_PASSIVE; } -long delegation(struct OperationConfig *config, const char *str) +long delegation(const char *str) { if(curl_strequal("none", str)) return CURLGSSAPI_DELEGATION_NONE; @@ -659,8 +654,7 @@ long delegation(struct OperationConfig *config, const char *str) if(curl_strequal("always", str)) return CURLGSSAPI_DELEGATION_FLAG; - warnf(config->global, "unrecognized delegation method '%s', using none", - str); + warnf("unrecognized delegation method '%s', using none", str); return CURLGSSAPI_DELEGATION_NONE; } @@ -712,25 +706,19 @@ CURLcode get_args(struct OperationConfig *config, const size_t i) return CURLE_OUT_OF_MEMORY; } - /* Check we have a password for the given host user */ - if(config->userpwd && !config->oauth_bearer) { + /* Check if we have a password for the given host user */ + if(config->userpwd && !config->oauth_bearer) result = checkpasswd("host", i, last, &config->userpwd); - if(result) - return result; - } - /* Check we have a password for the given proxy user */ - if(config->proxyuserpwd) { + /* Check if we have a password for the given proxy user */ + if(!result && config->proxyuserpwd) result = checkpasswd("proxy", i, last, &config->proxyuserpwd); - if(result) - return result; - } - /* Check we have a user agent */ - if(!config->useragent) { + /* Check if we have a user agent */ + if(!result && !config->useragent) { config->useragent = my_useragent(); if(!config->useragent) { - errorf(config->global, "out of memory"); + errorf("out of memory"); result = CURLE_OUT_OF_MEMORY; } } @@ -747,17 +735,17 @@ CURLcode get_args(struct OperationConfig *config, const size_t i) * data. */ -ParameterError str2tls_max(long *val, const char *str) +ParameterError str2tls_max(unsigned char *val, const char *str) { - static struct s_tls_max { + static struct s_tls_max { const char *tls_max_str; - long tls_max; + unsigned char tls_max; } const tls_max_array[] = { - { "default", CURL_SSLVERSION_MAX_DEFAULT }, - { "1.0", CURL_SSLVERSION_MAX_TLSv1_0 }, - { "1.1", CURL_SSLVERSION_MAX_TLSv1_1 }, - { "1.2", CURL_SSLVERSION_MAX_TLSv1_2 }, - { "1.3", CURL_SSLVERSION_MAX_TLSv1_3 } + { "default", 0 }, /* lets the library decide */ + { "1.0", 1 }, + { "1.1", 2 }, + { "1.2", 3 }, + { "1.3", 4 } }; size_t i = 0; if(!str) diff --git a/vendor/curl/src/tool_paramhlp.h b/vendor/curl/src/tool_paramhlp.h index 136214bb203..a9e8539cf57 100644 --- a/vendor/curl/src/tool_paramhlp.h +++ b/vendor/curl/src/tool_paramhlp.h @@ -45,25 +45,16 @@ ParameterError str2unum(long *val, const char *str); ParameterError oct2nummax(long *val, const char *str, long max); ParameterError str2unummax(long *val, const char *str, long max); ParameterError secs2ms(long *val, const char *str); - -ParameterError proto2num(struct OperationConfig *config, - const char * const *val, char **obuf, +ParameterError proto2num(const char * const *val, char **obuf, const char *str); - ParameterError check_protocol(const char *str); - ParameterError str2offset(curl_off_t *val, const char *str); - CURLcode get_args(struct OperationConfig *config, const size_t i); - ParameterError add2list(struct curl_slist **list, const char *ptr); +long ftpfilemethod(const char *str); +long ftpcccmethod(const char *str); +long delegation(const char *str); -int ftpfilemethod(struct OperationConfig *config, const char *str); - -int ftpcccmethod(struct OperationConfig *config, const char *str); - -long delegation(struct OperationConfig *config, const char *str); - -ParameterError str2tls_max(long *val, const char *str); +ParameterError str2tls_max(unsigned char *val, const char *str); #endif /* HEADER_CURL_TOOL_PARAMHLP_H */ diff --git a/vendor/curl/src/tool_parsecfg.c b/vendor/curl/src/tool_parsecfg.c index d5f144274a3..bc22b9d5b7b 100644 --- a/vendor/curl/src/tool_parsecfg.c +++ b/vendor/curl/src/tool_parsecfg.c @@ -23,7 +23,6 @@ ***************************************************************************/ #include "tool_setup.h" -#include #include "tool_cfgable.h" #include "tool_getparam.h" #include "tool_helpers.h" @@ -31,23 +30,63 @@ #include "tool_msgs.h" #include "tool_parsecfg.h" #include "tool_util.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ /* only acknowledge colon or equals as separators if the option was not specified with an initial dash! */ #define ISSEP(x,dash) (!dash && (((x) == '=') || ((x) == ':'))) -static const char *unslashquote(const char *line, char *param); +/* + * Copies the string from line to the param dynbuf, unquoting backslash-quoted + * characters and null-terminating the output string. Stops at the first + * non-backslash-quoted double quote character or the end of the input string. + * param must be at least as long as the input string. Returns 0 on success. + */ +static int unslashquote(const char *line, struct dynbuf *param) +{ + curlx_dyn_reset(param); + + while(*line && (*line != '\"')) { + if(*line == '\\') { + char out; + line++; + + /* default is to output the letter after the backslash */ + switch(out = *line) { + case '\0': + continue; /* this'll break out of the loop */ + case 't': + out = '\t'; + break; + case 'n': + out = '\n'; + break; + case 'r': + out = '\r'; + break; + case 'v': + out = '\v'; + break; + } + if(curlx_dyn_addn(param, &out, 1)) + return 1; + line++; + } + else if(curlx_dyn_addn(param, line++, 1)) + return 1; + } + return 0; /* ok */ +} #define MAX_CONFIG_LINE_LENGTH (10*1024*1024) /* return 0 on everything-is-fine, and non-zero otherwise */ -int parseconfig(const char *filename, struct GlobalConfig *global) +int parseconfig(const char *filename) { FILE *file = NULL; bool usedarg = FALSE; int rc = 0; - struct OperationConfig *operation = global->last; + struct OperationConfig *config = global->last; char *pathalloc = NULL; if(!filename) { @@ -88,13 +127,14 @@ int parseconfig(const char *filename, struct GlobalConfig *global) int lineno = 0; bool dashed_option; struct dynbuf buf; + struct dynbuf pbuf; bool fileerror = FALSE; curlx_dyn_init(&buf, MAX_CONFIG_LINE_LENGTH); + curlx_dyn_init(&pbuf, MAX_CONFIG_LINE_LENGTH); DEBUGASSERT(filename); while(!rc && my_get_line(file, &buf, &fileerror)) { ParameterError res; - bool alloced_param = FALSE; lineno++; line = curlx_dyn_ptr(&buf); if(!line) { @@ -126,15 +166,10 @@ int parseconfig(const char *filename, struct GlobalConfig *global) /* the parameter starts here (unless quoted) */ if(*line == '\"') { /* quoted parameter, do the quote dance */ - line++; - param = malloc(strlen(line) + 1); /* parameter */ - if(!param) { - /* out of memory */ - rc = 1; + rc = unslashquote(++line, &pbuf); + if(rc) break; - } - alloced_param = TRUE; - (void)unslashquote(line, param); + param = curlx_dyn_len(&pbuf) ? curlx_dyn_ptr(&pbuf) : CURL_UNCONST(""); } else { param = line; /* parameter starts here */ @@ -157,10 +192,9 @@ int parseconfig(const char *filename, struct GlobalConfig *global) case '#': /* comment */ break; default: - warnf(operation->global, "%s:%d: warning: '%s' uses unquoted " - "whitespace", filename, lineno, option); - warnf(operation->global, "This may cause side-effects. " - "Consider using double quotes?"); + warnf("%s:%d: warning: '%s' uses unquoted whitespace. " + "This may cause side-effects. Consider double quotes.", + filename, lineno, option); } } if(!*param) @@ -172,30 +206,24 @@ int parseconfig(const char *filename, struct GlobalConfig *global) #ifdef DEBUG_CONFIG fprintf(tool_stderr, "PARAM: \"%s\"\n",(param ? param : "(null)")); #endif - res = getparameter(option, param, &usedarg, global, operation); - operation = global->last; + res = getparameter(option, param, &usedarg, config); + config = global->last; if(!res && param && *param && !usedarg) /* we passed in a parameter that was not used! */ res = PARAM_GOT_EXTRA_PARAMETER; if(res == PARAM_NEXT_OPERATION) { - if(operation->url_list && operation->url_list->url) { + if(config->url_list && config->url_list->url) { /* Allocate the next config */ - operation->next = malloc(sizeof(struct OperationConfig)); - if(operation->next) { - /* Initialise the newly created config */ - config_init(operation->next); - - /* Set the global config pointer */ - operation->next->global = global; - + config->next = config_alloc(); + if(config->next) { /* Update the last operation pointer */ - global->last = operation->next; + global->last = config->next; /* Move onto the new config */ - operation->next->prev = operation; - operation = operation->next; + config->next->prev = config; + config = config->next; } else res = PARAM_NO_MEM; @@ -213,16 +241,14 @@ int parseconfig(const char *filename, struct GlobalConfig *global) res != PARAM_ENGINES_REQUESTED && res != PARAM_CA_EMBED_REQUESTED) { const char *reason = param2text(res); - errorf(operation->global, "%s:%d: '%s' %s", + errorf("%s:%d: '%s' %s", filename, lineno, option, reason); rc = (int)res; } } - - if(alloced_param) - tool_safefree(param); } curlx_dyn_free(&buf); + curlx_dyn_free(&pbuf); if(file != stdin) fclose(file); if(fileerror) @@ -235,46 +261,6 @@ int parseconfig(const char *filename, struct GlobalConfig *global) return rc; } -/* - * Copies the string from line to the buffer at param, unquoting - * backslash-quoted characters and null-terminating the output string. Stops - * at the first non-backslash-quoted double quote character or the end of the - * input string. param must be at least as long as the input string. Returns - * the pointer after the last handled input character. - */ -static const char *unslashquote(const char *line, char *param) -{ - while(*line && (*line != '\"')) { - if(*line == '\\') { - char out; - line++; - - /* default is to output the letter after the backslash */ - switch(out = *line) { - case '\0': - continue; /* this'll break out of the loop */ - case 't': - out = '\t'; - break; - case 'n': - out = '\n'; - break; - case 'r': - out = '\r'; - break; - case 'v': - out = '\v'; - break; - } - *param++ = out; - line++; - } - else - *param++ = *line++; - } - *param = '\0'; /* always null-terminate */ - return line; -} static bool get_line(FILE *input, struct dynbuf *buf, bool *error) { diff --git a/vendor/curl/src/tool_parsecfg.h b/vendor/curl/src/tool_parsecfg.h index 07a34621ae3..46977d8eddc 100644 --- a/vendor/curl/src/tool_parsecfg.h +++ b/vendor/curl/src/tool_parsecfg.h @@ -25,8 +25,7 @@ ***************************************************************************/ #include "tool_setup.h" -int parseconfig(const char *filename, struct GlobalConfig *config); - +int parseconfig(const char *filename); bool my_get_line(FILE *fp, struct dynbuf *db, bool *error); #endif /* HEADER_CURL_TOOL_PARSECFG_H */ diff --git a/vendor/curl/src/tool_progress.c b/vendor/curl/src/tool_progress.c index 8f74253e961..666fe9869cd 100644 --- a/vendor/curl/src/tool_progress.c +++ b/vendor/curl/src/tool_progress.c @@ -25,46 +25,45 @@ #include "tool_operate.h" #include "tool_progress.h" #include "tool_util.h" -#include /* The point of this function would be to return a string of the input data, but never longer than 5 columns (+ one zero byte). Add suffix k, M, G when suitable... */ static char *max5data(curl_off_t bytes, char *max5) { -#define ONE_KILOBYTE CURL_OFF_T_C(1024) -#define ONE_MEGABYTE (CURL_OFF_T_C(1024) * ONE_KILOBYTE) -#define ONE_GIGABYTE (CURL_OFF_T_C(1024) * ONE_MEGABYTE) -#define ONE_TERABYTE (CURL_OFF_T_C(1024) * ONE_GIGABYTE) -#define ONE_PETABYTE (CURL_OFF_T_C(1024) * ONE_TERABYTE) +#define ONE_KILOBYTE (curl_off_t)1024 +#define ONE_MEGABYTE (1024 * ONE_KILOBYTE) +#define ONE_GIGABYTE (1024 * ONE_MEGABYTE) +#define ONE_TERABYTE (1024 * ONE_GIGABYTE) +#define ONE_PETABYTE (1024 * ONE_TERABYTE) - if(bytes < CURL_OFF_T_C(100000)) + if(bytes < 100000) msnprintf(max5, 6, "%5" CURL_FORMAT_CURL_OFF_T, bytes); - else if(bytes < CURL_OFF_T_C(10000) * ONE_KILOBYTE) + else if(bytes < 10000 * ONE_KILOBYTE) msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "k", bytes/ONE_KILOBYTE); - else if(bytes < CURL_OFF_T_C(100) * ONE_MEGABYTE) + else if(bytes < 100 * ONE_MEGABYTE) /* 'XX.XM' is good as long as we are less than 100 megs */ msnprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE, - (bytes%ONE_MEGABYTE) / (ONE_MEGABYTE/CURL_OFF_T_C(10)) ); + (bytes%ONE_MEGABYTE) / (ONE_MEGABYTE/10) ); - else if(bytes < CURL_OFF_T_C(10000) * ONE_MEGABYTE) + else if(bytes < 10000 * ONE_MEGABYTE) /* 'XXXXM' is good until we are at 10000MB or above */ msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE); - else if(bytes < CURL_OFF_T_C(100) * ONE_GIGABYTE) + else if(bytes < 100 * ONE_GIGABYTE) /* 10000 MB - 100 GB, we show it as XX.XG */ msnprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0" CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE, - (bytes%ONE_GIGABYTE) / (ONE_GIGABYTE/CURL_OFF_T_C(10)) ); + (bytes%ONE_GIGABYTE) / (ONE_GIGABYTE/10) ); - else if(bytes < CURL_OFF_T_C(10000) * ONE_GIGABYTE) + else if(bytes < 10000 * ONE_GIGABYTE) /* up to 10000GB, display without decimal: XXXXG */ msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE); - else if(bytes < CURL_OFF_T_C(10000) * ONE_TERABYTE) + else if(bytes < 10000 * ONE_TERABYTE) /* up to 10000TB, display without decimal: XXXXT */ msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "T", bytes/ONE_TERABYTE); @@ -110,19 +109,19 @@ static void time2str(char *r, curl_off_t seconds) strcpy(r, "--:--:--"); return; } - h = seconds / CURL_OFF_T_C(3600); - if(h <= CURL_OFF_T_C(99)) { - curl_off_t m = (seconds - (h*CURL_OFF_T_C(3600))) / CURL_OFF_T_C(60); - curl_off_t s = (seconds - (h*CURL_OFF_T_C(3600))) - (m*CURL_OFF_T_C(60)); + h = seconds / 3600; + if(h <= 99) { + curl_off_t m = (seconds - (h * 3600)) / 60; + curl_off_t s = (seconds - (h * 3600)) - (m * 60); msnprintf(r, 9, "%2" CURL_FORMAT_CURL_OFF_T ":%02" CURL_FORMAT_CURL_OFF_T ":%02" CURL_FORMAT_CURL_OFF_T, h, m, s); } else { /* this equals to more than 99 hours, switch to a more suitable output format to fit within the limits. */ - curl_off_t d = seconds / CURL_OFF_T_C(86400); - h = (seconds - (d*CURL_OFF_T_C(86400))) / CURL_OFF_T_C(3600); - if(d <= CURL_OFF_T_C(999)) + curl_off_t d = seconds / 86400; + h = (seconds - (d * 86400)) / 3600; + if(d <= 999) msnprintf(r, 9, "%3" CURL_FORMAT_CURL_OFF_T "d %02" CURL_FORMAT_CURL_OFF_T "h", d, h); else @@ -135,8 +134,6 @@ static curl_off_t all_ultotal = 0; static curl_off_t all_dlalready = 0; static curl_off_t all_ulalready = 0; -curl_off_t all_xfers = 0; /* current total */ - struct speedcount { curl_off_t dl; curl_off_t ul; @@ -151,7 +148,7 @@ static struct speedcount speedstore[SPEEDCNT]; |DL% UL% Dled Uled Xfers Live Total Current Left Speed | 6 -- 9.9G 0 2 2 0:00:40 0:00:02 0:00:37 4087M */ -bool progress_meter(struct GlobalConfig *global, +bool progress_meter(CURLM *multi, struct curltime *start, bool final) { @@ -183,9 +180,10 @@ bool progress_meter(struct GlobalConfig *global, struct per_transfer *per; curl_off_t all_dlnow = 0; curl_off_t all_ulnow = 0; + curl_off_t xfers_added = 0; + curl_off_t xfers_running = 0; bool dlknown = TRUE; bool ulknown = TRUE; - curl_off_t all_running = 0; /* in progress */ curl_off_t speed = 0; unsigned int i; stamp = now; @@ -211,8 +209,6 @@ bool progress_meter(struct GlobalConfig *global, all_ultotal += per->ultotal; per->ultotal_added = TRUE; } - if(per->added) - all_running++; } if(dlknown && all_dltotal) msnprintf(dlpercen, sizeof(dlpercen), "%3" CURL_FORMAT_CURL_OFF_T, @@ -275,6 +271,8 @@ bool progress_meter(struct GlobalConfig *global, } time2str(time_spent, spent); + (void)curl_multi_get_offt(multi, CURLMINFO_XFERS_ADDED, &xfers_added); + (void)curl_multi_get_offt(multi, CURLMINFO_XFERS_RUNNING, &xfers_running); fprintf(tool_stderr, "\r" "%-3s " /* percent downloaded */ @@ -293,8 +291,8 @@ bool progress_meter(struct GlobalConfig *global, ulpercen, /* 3 letters */ max5data(all_dlnow, buffer[0]), max5data(all_ulnow, buffer[1]), - all_xfers, - all_running, + xfers_added, + xfers_running, time_total, time_spent, time_left, diff --git a/vendor/curl/src/tool_progress.h b/vendor/curl/src/tool_progress.h index 02c34d42eee..41b36ca024a 100644 --- a/vendor/curl/src/tool_progress.h +++ b/vendor/curl/src/tool_progress.h @@ -31,11 +31,9 @@ int xferinfo_cb(void *clientp, curl_off_t ultotal, curl_off_t ulnow); -bool progress_meter(struct GlobalConfig *global, +bool progress_meter(CURLM *multi, struct curltime *start, bool final); void progress_finalize(struct per_transfer *per); -extern curl_off_t all_xfers; /* total number */ - #endif /* HEADER_CURL_TOOL_PROGRESS_H */ diff --git a/vendor/curl/src/tool_sdecls.h b/vendor/curl/src/tool_sdecls.h index fc0c6a546e6..45b7bd0c205 100644 --- a/vendor/curl/src/tool_sdecls.h +++ b/vendor/curl/src/tool_sdecls.h @@ -74,6 +74,7 @@ struct OutStruct { BIT(is_cd_filename); BIT(s_isreg); BIT(fopened); + BIT(out_null); }; /* @@ -87,7 +88,7 @@ struct getout { char *url; /* the URL we deal with */ char *outfile; /* where to store the output */ char *infile; /* file to upload, if GETOUT_UPLOAD is set */ - int num; /* which URL number in an invocation */ + curl_off_t num; /* which URL number in an invocation */ BIT(outset); /* when outfile is set */ BIT(urlset); /* when URL is set */ @@ -95,6 +96,7 @@ struct getout { BIT(useremote); /* use remote filename locally */ BIT(noupload); /* if set, -T "" has been used */ BIT(noglob); /* disable globbing for this URL */ + BIT(out_null); /* discard output for this URL */ }; /* * 'trace' enumeration represents curl's output look'n feel possibilities. diff --git a/vendor/curl/src/tool_setopt.c b/vendor/curl/src/tool_setopt.c index a782b33ea22..b1b3f0a8b74 100644 --- a/vendor/curl/src/tool_setopt.c +++ b/vendor/curl/src/tool_setopt.c @@ -25,12 +25,11 @@ #ifndef CURL_DISABLE_LIBCURL_OPTION -#include #include "tool_cfgable.h" #include "tool_easysrc.h" #include "tool_setopt.h" #include "tool_msgs.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ /* Lookup tables for converting setopt values back to symbols */ /* For enums, values may be in any order. */ @@ -102,7 +101,7 @@ const struct NameValue setopt_nv_CURL_SSLVERSION[] = { }; const struct NameValue setopt_nv_CURL_SSLVERSION_MAX[] = { - NV(CURL_SSLVERSION_MAX_NONE), + {"", CURL_SSLVERSION_MAX_NONE}, NV(CURL_SSLVERSION_MAX_DEFAULT), NV(CURL_SSLVERSION_MAX_TLSv1_0), NV(CURL_SSLVERSION_MAX_TLSv1_1), @@ -151,6 +150,14 @@ const struct NameValue setopt_nv_CURL_NETRC[] = { NVEND, }; +const struct NameValue setopt_nv_CURLOPT_FOLLOWLOCATION[] = { + NV(0L), + NV(CURLFOLLOW_ALL), + NV(CURLFOLLOW_OBEYCODE), + NV(CURLFOLLOW_FIRSTONLY), + NVEND, +}; + /* These options have non-zero default values. */ static const struct NameValue setopt_nv_CURLNONZERODEFAULTS[] = { NV1(CURLOPT_SSL_VERIFYPEER, 1), @@ -218,14 +225,13 @@ static char *c_escape(const char *str, curl_off_t len) result = curlx_dyn_addn(&escaped, str, s - str); if(!result) - (void) !curlx_dyn_addn(&escaped, "...", cutoff); + (void)!curlx_dyn_addn(&escaped, "...", cutoff); return curlx_dyn_ptr(&escaped); } /* setopt wrapper for enum types */ -CURLcode tool_setopt_enum(CURL *curl, struct GlobalConfig *config, - const char *name, CURLoption tag, +CURLcode tool_setopt_enum(CURL *curl, const char *name, CURLoption tag, const struct NameValue *nvlist, long lval) { CURLcode ret = CURLE_OK; @@ -235,7 +241,7 @@ CURLcode tool_setopt_enum(CURL *curl, struct GlobalConfig *config, if(!lval) skip = TRUE; - if(config->libcurl && !skip && !ret) { + if(global->libcurl && !skip && !ret) { /* we only use this for real if --libcurl was used */ const struct NameValue *nv = NULL; for(nv = nvlist; nv->name; nv++) { @@ -257,14 +263,13 @@ CURLcode tool_setopt_enum(CURL *curl, struct GlobalConfig *config, #ifdef DEBUGBUILD if(ret) - warnf(config, "option %s returned error (%d)", name, (int)ret); + warnf("option %s returned error (%d)", name, (int)ret); #endif return ret; } /* setopt wrapper for CURLOPT_SSLVERSION */ -CURLcode tool_setopt_SSLVERSION(CURL *curl, struct GlobalConfig *config, - const char *name, CURLoption tag, +CURLcode tool_setopt_SSLVERSION(CURL *curl, const char *name, CURLoption tag, long lval) { CURLcode ret = CURLE_OK; @@ -274,7 +279,7 @@ CURLcode tool_setopt_SSLVERSION(CURL *curl, struct GlobalConfig *config, if(!lval) skip = TRUE; - if(config->libcurl && !skip && !ret) { + if(global->libcurl && !skip && !ret) { /* we only use this for real if --libcurl was used */ const struct NameValue *nv = NULL; const struct NameValue *nv2 = NULL; @@ -294,22 +299,28 @@ CURLcode tool_setopt_SSLVERSION(CURL *curl, struct GlobalConfig *config, name, lval); } else { - ret = easysrc_addf(&easysrc_code, - "curl_easy_setopt(hnd, %s, (long)(%s | %s));", - name, nv->name, nv2->name); + if(nv2->name && *nv2->name) + /* if max is set */ + ret = easysrc_addf(&easysrc_code, + "curl_easy_setopt(hnd, %s, (long)(%s | %s));", + name, nv->name, nv2->name); + else + /* without a max */ + ret = easysrc_addf(&easysrc_code, + "curl_easy_setopt(hnd, %s, (long)%s);", + name, nv->name); } } #ifdef DEBUGBUILD if(ret) - warnf(config, "option %s returned error (%d)", name, (int)ret); + warnf("option %s returned error (%d)", name, (int)ret); #endif return ret; } /* setopt wrapper for bitmasks */ -CURLcode tool_setopt_bitmask(CURL *curl, struct GlobalConfig *config, - const char *name, CURLoption tag, +CURLcode tool_setopt_bitmask(CURL *curl, const char *name, CURLoption tag, const struct NameValueUnsigned *nvlist, long lval) { @@ -318,7 +329,7 @@ CURLcode tool_setopt_bitmask(CURL *curl, struct GlobalConfig *config, if(!lval) skip = TRUE; - if(config->libcurl && !skip && !ret) { + if(global->libcurl && !skip && !ret) { /* we only use this for real if --libcurl was used */ char preamble[80]; unsigned long rest = (unsigned long)lval; @@ -380,13 +391,13 @@ static CURLcode libcurl_generate_slist(struct curl_slist *slist, int *slistno) } static CURLcode libcurl_generate_mime(CURL *curl, - struct GlobalConfig *config, + struct OperationConfig *config, struct tool_mime *toolmime, int *mimeno); /* Forward. */ /* Wrapper to generate source code for a mime part. */ static CURLcode libcurl_generate_mime_part(CURL *curl, - struct GlobalConfig *config, + struct OperationConfig *config, struct tool_mime *part, int mimeno) { @@ -498,8 +509,7 @@ static CURLcode libcurl_generate_mime_part(CURL *curl, "curl_mime_headers(part%d, slist%d, 1);", mimeno, slistno); if(!ret) - ret = easysrc_addf(&easysrc_code, - "slist%d = NULL;", slistno); /* Prevent CLEANing. */ + ret = easysrc_addf(&easysrc_code, "slist%d = NULL;", slistno); } } @@ -508,7 +518,7 @@ static CURLcode libcurl_generate_mime_part(CURL *curl, /* Wrapper to generate source code for a mime structure. */ static CURLcode libcurl_generate_mime(CURL *curl, - struct GlobalConfig *config, + struct OperationConfig *config, struct tool_mime *toolmime, int *mimeno) { @@ -538,16 +548,15 @@ static CURLcode libcurl_generate_mime(CURL *curl, } /* setopt wrapper for CURLOPT_MIMEPOST */ -CURLcode tool_setopt_mimepost(CURL *curl, struct GlobalConfig *config, +CURLcode tool_setopt_mimepost(CURL *curl, struct OperationConfig *config, const char *name, CURLoption tag, curl_mime *mimepost) { CURLcode ret = curl_easy_setopt(curl, tag, mimepost); int mimeno = 0; - if(!ret && config->libcurl) { - ret = libcurl_generate_mime(curl, config, - config->current->mimeroot, &mimeno); + if(!ret && global->libcurl) { + ret = libcurl_generate_mime(curl, config, config->mimeroot, &mimeno); if(!ret) ret = easysrc_addf(&easysrc_code, "curl_easy_setopt(hnd, %s, mime%d);", @@ -558,15 +567,14 @@ CURLcode tool_setopt_mimepost(CURL *curl, struct GlobalConfig *config, } /* setopt wrapper for curl_slist options */ -CURLcode tool_setopt_slist(CURL *curl, struct GlobalConfig *config, - const char *name, CURLoption tag, +CURLcode tool_setopt_slist(CURL *curl, const char *name, CURLoption tag, struct curl_slist *list) { CURLcode ret = CURLE_OK; ret = curl_easy_setopt(curl, tag, list); - if(config->libcurl && list && !ret) { + if(global->libcurl && list && !ret) { int i; ret = libcurl_generate_slist(list, &i); @@ -579,8 +587,7 @@ CURLcode tool_setopt_slist(CURL *curl, struct GlobalConfig *config, } /* options that set long */ -CURLcode tool_setopt_long(CURL *curl, struct GlobalConfig *global, - const char *name, CURLoption tag, +CURLcode tool_setopt_long(CURL *curl, const char *name, CURLoption tag, long lval) { long defval = 0L; @@ -605,8 +612,7 @@ CURLcode tool_setopt_long(CURL *curl, struct GlobalConfig *global, } /* options that set curl_off_t */ -CURLcode tool_setopt_offt(CURL *curl, struct GlobalConfig *global, - const char *name, CURLoption tag, +CURLcode tool_setopt_offt(CURL *curl, const char *name, CURLoption tag, curl_off_t lval) { CURLcode ret = CURLE_OK; @@ -623,9 +629,9 @@ CURLcode tool_setopt_offt(CURL *curl, struct GlobalConfig *global, } /* setopt wrapper for setting object and function pointer options */ -CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *global, - struct OperationConfig *config, - const char *name, CURLoption tag, ...) +CURLcode tool_setopt(CURL *curl, struct OperationConfig *config, + bool str, const char *name, CURLoption tag, + ...) { va_list arg; CURLcode ret = CURLE_OK; diff --git a/vendor/curl/src/tool_setopt.h b/vendor/curl/src/tool_setopt.h index 14ac18cdc90..4f28df980ec 100644 --- a/vendor/curl/src/tool_setopt.h +++ b/vendor/curl/src/tool_setopt.h @@ -54,6 +54,7 @@ extern const struct NameValue setopt_nv_CURLFTPSSL_CCC[]; extern const struct NameValue setopt_nv_CURLUSESSL[]; extern const struct NameValueUnsigned setopt_nv_CURLSSLOPT[]; extern const struct NameValue setopt_nv_CURL_NETRC[]; +extern const struct NameValue setopt_nv_CURLOPT_FOLLOWLOCATION[]; extern const struct NameValueUnsigned setopt_nv_CURLAUTH[]; extern const struct NameValueUnsigned setopt_nv_CURLHSTS[]; @@ -75,60 +76,55 @@ extern const struct NameValueUnsigned setopt_nv_CURLHSTS[]; /* Intercept setopt calls for --libcurl */ -CURLcode tool_setopt_enum(CURL *curl, struct GlobalConfig *config, - const char *name, CURLoption tag, +CURLcode tool_setopt_enum(CURL *curl, const char *name, CURLoption tag, const struct NameValue *nv, long lval); -CURLcode tool_setopt_SSLVERSION(CURL *curl, struct GlobalConfig *config, - const char *name, CURLoption tag, +CURLcode tool_setopt_SSLVERSION(CURL *curl, const char *name, CURLoption tag, long lval); -CURLcode tool_setopt_flags(CURL *curl, struct GlobalConfig *config, +CURLcode tool_setopt_flags(CURL *curl, struct OperationConfig *config, const char *name, CURLoption tag, const struct NameValue *nv, long lval); -CURLcode tool_setopt_bitmask(CURL *curl, struct GlobalConfig *config, +CURLcode tool_setopt_bitmask(CURL *curl, const char *name, CURLoption tag, const struct NameValueUnsigned *nv, long lval); -CURLcode tool_setopt_mimepost(CURL *curl, struct GlobalConfig *config, +CURLcode tool_setopt_mimepost(CURL *curl, struct OperationConfig *config, const char *name, CURLoption tag, curl_mime *mimepost); -CURLcode tool_setopt_slist(CURL *curl, struct GlobalConfig *config, - const char *name, CURLoption tag, +CURLcode tool_setopt_slist(CURL *curl, const char *name, CURLoption tag, struct curl_slist *list); -CURLcode tool_setopt_long(CURL *curl, struct GlobalConfig *global, - const char *name, CURLoption tag, +CURLcode tool_setopt_long(CURL *curl, const char *name, CURLoption tag, long lval); -CURLcode tool_setopt_offt(CURL *curl, struct GlobalConfig *global, - const char *name, CURLoption tag, +CURLcode tool_setopt_offt(CURL *curl, const char *name, CURLoption tag, curl_off_t lval); -CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *global, - struct OperationConfig *config, - const char *name, CURLoption tag, ...); +CURLcode tool_setopt(CURL *curl, struct OperationConfig *config, + bool str, const char *name, CURLoption tag, + ...); #define my_setopt(x,y,z) \ - tool_setopt(x, FALSE, global, config, #y, y, z) + tool_setopt(x, config, FALSE, #y, y, z) #define my_setopt_long(x,y,z) \ - tool_setopt_long(x, global, #y, y, z) + tool_setopt_long(x, #y, y, z) #define my_setopt_offt(x,y,z) \ - tool_setopt_offt(x, global, #y, y, z) + tool_setopt_offt(x, #y, y, z) #define my_setopt_str(x,y,z) \ - tool_setopt(x, TRUE, global, config, #y, y, z) + tool_setopt(x, config, TRUE, #y, y, z) #define my_setopt_enum(x,y,z) \ - tool_setopt_enum(x, global, #y, y, setopt_nv_ ## y, z) + tool_setopt_enum(x, #y, y, setopt_nv_ ## y, z) #define my_setopt_SSLVERSION(x,y,z) \ - tool_setopt_SSLVERSION(x, global, #y, y, z) + tool_setopt_SSLVERSION(x, #y, y, z) #define my_setopt_bitmask(x,y,z) \ - tool_setopt_bitmask(x, global, #y, y, setopt_nv_ ## y, z) + tool_setopt_bitmask(x, #y, y, setopt_nv_ ## y, z) #define my_setopt_mimepost(x,y,z) \ - tool_setopt_mimepost(x, global, #y, y, z) + tool_setopt_mimepost(x, config, #y, y, z) #define my_setopt_slist(x,y,z) \ - tool_setopt_slist(x, global, #y, y, z) + tool_setopt_slist(x, #y, y, z) #else /* CURL_DISABLE_LIBCURL_OPTION */ @@ -143,7 +139,7 @@ CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *global, #define my_setopt_offt(x,y,z) \ curl_easy_setopt(x, y, (curl_off_t)(z)) -#define my_setopt_str(x,y,z) \ +#define my_setopt_str(x,y,z) \ curl_easy_setopt(x, y, z) #define my_setopt_enum(x,y,z) \ diff --git a/vendor/curl/src/tool_setup.h b/vendor/curl/src/tool_setup.h index b198d89dee1..a661040737b 100644 --- a/vendor/curl/src/tool_setup.h +++ b/vendor/curl/src/tool_setup.h @@ -24,7 +24,9 @@ * ***************************************************************************/ +#ifndef CURL_NO_OLDIES #define CURL_NO_OLDIES +#endif /* * curl_setup.h may define preprocessor macros such as _FILE_OFFSET_BITS and @@ -45,7 +47,7 @@ extern FILE *tool_stderr; #include /* external interface */ -#include "timeval.h" +#include /* * Platform specific stuff. @@ -56,16 +58,16 @@ extern FILE *tool_stderr; #endif #ifndef CURL_OS -# define CURL_OS "unknown" +#define CURL_OS "unknown" #endif #ifndef UNPRINTABLE_CHAR - /* define what to use for unprintable characters */ -# define UNPRINTABLE_CHAR '.' +/* define what to use for unprintable characters */ +#define UNPRINTABLE_CHAR '.' #endif #ifndef HAVE_STRDUP -# include "tool_strdup.h" +#include "tool_strdup.h" #endif #ifndef tool_nop_stmt @@ -76,7 +78,7 @@ extern FILE *tool_stderr; # define CURL_STRICMP(p1, p2) _stricmp(p1, p2) #elif defined(HAVE_STRCASECMP) # ifdef HAVE_STRINGS_H -# include +# include # endif # define CURL_STRICMP(p1, p2) strcasecmp(p1, p2) #elif defined(HAVE_STRCMPI) @@ -113,5 +115,4 @@ int tool_ftruncate64(int fd, curl_off_t where); #endif /* ! HAVE_FTRUNCATE */ #endif /* _WIN32 */ - #endif /* HEADER_CURL_TOOL_SETUP_H */ diff --git a/vendor/curl/src/tool_ssls.c b/vendor/curl/src/tool_ssls.c index 20768ed54b9..edf8d6095a9 100644 --- a/vendor/curl/src/tool_ssls.c +++ b/vendor/curl/src/tool_ssls.c @@ -23,7 +23,6 @@ ***************************************************************************/ #include "tool_setup.h" -#include #include "tool_cfgable.h" #include "tool_cb_dbg.h" #include "tool_msgs.h" @@ -35,8 +34,7 @@ #define MAX_SSLS_LINE (64 * 1024) -static CURLcode tool_ssls_easy(struct GlobalConfig *global, - struct OperationConfig *config, +static CURLcode tool_ssls_easy(struct OperationConfig *config, CURLSH *share, CURL **peasy) { CURLcode result = CURLE_OK; @@ -54,8 +52,7 @@ static CURLcode tool_ssls_easy(struct GlobalConfig *global, return result; } -CURLcode tool_ssls_load(struct GlobalConfig *global, - struct OperationConfig *config, +CURLcode tool_ssls_load(struct OperationConfig *config, CURLSH *share, const char *filename) { FILE *fp; @@ -71,11 +68,11 @@ CURLcode tool_ssls_load(struct GlobalConfig *global, curlx_dyn_init(&buf, MAX_SSLS_LINE); fp = fopen(filename, FOPEN_READTEXT); if(!fp) { /* ok if it does not exist */ - notef(global, "SSL session file does not exist (yet?): %s", filename); + notef("SSL session file does not exist (yet?): %s", filename); goto out; } - r = tool_ssls_easy(global, config, share, &easy); + r = tool_ssls_easy(config, share, &easy); if(r) goto out; @@ -88,14 +85,13 @@ CURLcode tool_ssls_load(struct GlobalConfig *global, c = memchr(line, ':', strlen(line)); if(!c) { - warnf(global, "unrecognized line %d in ssl session file %s", - i, filename); + warnf("unrecognized line %d in ssl session file %s", i, filename); continue; } *c = '\0'; r = curlx_base64_decode(line, &shmac, &shmac_len); if(r) { - warnf(global, "invalid shmax base64 encoding in line %d", i); + warnf("invalid shmax base64 encoding in line %d", i); continue; } line = c + 1; @@ -106,13 +102,13 @@ CURLcode tool_ssls_load(struct GlobalConfig *global, } r = curlx_base64_decode(line, &sdata, &sdata_len); if(r) { - warnf(global, "invalid sdata base64 encoding in line %d: %s", i, line); + warnf("invalid sdata base64 encoding in line %d: %s", i, line); continue; } r = curl_easy_ssls_import(easy, NULL, shmac, shmac_len, sdata, sdata_len); if(r) { - warnf(global, "import of session from line %d rejected(%d)", i, r); + warnf("import of session from line %d rejected(%d)", i, r); continue; } ++imported; @@ -134,7 +130,6 @@ CURLcode tool_ssls_load(struct GlobalConfig *global, } struct tool_ssls_ctx { - struct GlobalConfig *global; FILE *fp; int exported; }; @@ -182,29 +177,27 @@ static CURLcode tool_ssls_exp(CURL *easy, void *userptr, ctx->exported++; out: if(r) - warnf(ctx->global, "Warning: error saving SSL session for '%s': %d", - session_key, r); + warnf("Warning: error saving SSL session for '%s': %d", session_key, r); curl_free(enc); return r; } -CURLcode tool_ssls_save(struct GlobalConfig *global, - struct OperationConfig *config, +CURLcode tool_ssls_save(struct OperationConfig *config, CURLSH *share, const char *filename) { struct tool_ssls_ctx ctx; CURL *easy = NULL; CURLcode r = CURLE_OK; - ctx.global = global; ctx.exported = 0; ctx.fp = fopen(filename, FOPEN_WRITETEXT); if(!ctx.fp) { - warnf(global, "Warning: Failed to create SSL session file %s", filename); + warnf("Warning: Failed to create SSL session file %s", + filename); goto out; } - r = tool_ssls_easy(global, config, share, &easy); + r = tool_ssls_easy(config, share, &easy); if(r) goto out; diff --git a/vendor/curl/src/tool_ssls.h b/vendor/curl/src/tool_ssls.h index b8a6a5e0534..7a1b95194d3 100644 --- a/vendor/curl/src/tool_ssls.h +++ b/vendor/curl/src/tool_ssls.h @@ -27,11 +27,9 @@ #include "tool_operate.h" -CURLcode tool_ssls_load(struct GlobalConfig *global, - struct OperationConfig *config, +CURLcode tool_ssls_load(struct OperationConfig *config, CURLSH *share, const char *filename); -CURLcode tool_ssls_save(struct GlobalConfig *global, - struct OperationConfig *config, +CURLcode tool_ssls_save(struct OperationConfig *config, CURLSH *share, const char *filename); #endif /* HEADER_CURL_TOOL_SSLS_H */ diff --git a/vendor/curl/src/tool_stderr.c b/vendor/curl/src/tool_stderr.c index 1285f04a8ed..b023d6c8020 100644 --- a/vendor/curl/src/tool_stderr.c +++ b/vendor/curl/src/tool_stderr.c @@ -26,7 +26,7 @@ #include "tool_stderr.h" #include "tool_msgs.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ FILE *tool_stderr; @@ -36,7 +36,7 @@ void tool_init_stderr(void) tool_stderr = stderr; } -void tool_set_stderr_file(struct GlobalConfig *global, const char *filename) +void tool_set_stderr_file(const char *filename) { FILE *fp; @@ -52,7 +52,7 @@ void tool_set_stderr_file(struct GlobalConfig *global, const char *filename) subsequent freopen will fail. */ fp = fopen(filename, FOPEN_WRITETEXT); if(!fp) { - warnf(global, "Warning: Failed to open %s", filename); + warnf("Warning: Failed to open %s", filename); return; } fclose(fp); diff --git a/vendor/curl/src/tool_stderr.h b/vendor/curl/src/tool_stderr.h index 8edc8ab65ea..94c50857920 100644 --- a/vendor/curl/src/tool_stderr.h +++ b/vendor/curl/src/tool_stderr.h @@ -27,6 +27,6 @@ #include "tool_cfgable.h" void tool_init_stderr(void); -void tool_set_stderr_file(struct GlobalConfig *global, const char *filename); +void tool_set_stderr_file(const char *filename); #endif /* HEADER_CURL_TOOL_STDERR_H */ diff --git a/vendor/curl/src/tool_strdup.c b/vendor/curl/src/tool_strdup.c index a5725d6d406..ff80b56b926 100644 --- a/vendor/curl/src/tool_strdup.c +++ b/vendor/curl/src/tool_strdup.c @@ -22,6 +22,7 @@ * ***************************************************************************/ #include "tool_strdup.h" +#include "memdebug.h" /* keep this as LAST include */ #ifndef HAVE_STRDUP char *strdup(const char *str) @@ -42,3 +43,14 @@ char *strdup(const char *str) return newstr; } #endif + +char *memdup0(const char *data, size_t len) +{ + char *p = malloc(len + 1); + if(!p) + return NULL; + if(len) + memcpy(p, data, len); + p[len] = 0; + return p; +} diff --git a/vendor/curl/src/tool_strdup.h b/vendor/curl/src/tool_strdup.h index 9b216189627..275be7c5d90 100644 --- a/vendor/curl/src/tool_strdup.h +++ b/vendor/curl/src/tool_strdup.h @@ -28,5 +28,6 @@ #ifndef HAVE_STRDUP extern char *strdup(const char *str); #endif +char *memdup0(const char *data, size_t len); #endif /* HEADER_TOOL_STRDUP_H */ diff --git a/vendor/curl/src/tool_urlglob.c b/vendor/curl/src/tool_urlglob.c index c8fa301b994..63d3a7c72a5 100644 --- a/vendor/curl/src/tool_urlglob.c +++ b/vendor/curl/src/tool_urlglob.c @@ -23,35 +23,37 @@ ***************************************************************************/ #include "tool_setup.h" -#include #include "tool_cfgable.h" #include "tool_doswin.h" #include "tool_urlglob.h" #include "tool_vms.h" -#include /* keep this as LAST include */ +#include "tool_strdup.h" +#include "memdebug.h" /* keep this as LAST include */ -#define GLOBERROR(string, column, code) \ - glob->error = string, glob->pos = column, code +static CURLcode globerror(struct URLGlob *glob, const char *err, + size_t pos, CURLcode error) +{ + glob->error = err; + glob->pos = pos; + return error; +} static CURLcode glob_fixed(struct URLGlob *glob, char *fixed, size_t len) { struct URLPattern *pat = &glob->pattern[glob->size]; - pat->type = UPTSet; - pat->content.Set.size = 1; - pat->content.Set.ptr_s = 0; + pat->type = GLOB_SET; + pat->c.set.size = 1; + pat->c.set.idx = 0; pat->globindex = -1; - pat->content.Set.elements = malloc(sizeof(char *)); + pat->c.set.elem = malloc(sizeof(char *)); - if(!pat->content.Set.elements) - return GLOBERROR("out of memory", 0, CURLE_OUT_OF_MEMORY); + if(!pat->c.set.elem) + return globerror(glob, NULL, 0, CURLE_OUT_OF_MEMORY); - pat->content.Set.elements[0] = malloc(len + 1); - if(!pat->content.Set.elements[0]) - return GLOBERROR("out of memory", 0, CURLE_OUT_OF_MEMORY); - - memcpy(pat->content.Set.elements[0], fixed, len); - pat->content.Set.elements[0][len] = 0; + pat->c.set.elem[0] = memdup0(fixed, len); + if(!pat->c.set.elem[0]) + return globerror(glob, NULL, 0, CURLE_OUT_OF_MEMORY); return CURLE_OK; } @@ -69,8 +71,9 @@ static int multiply(curl_off_t *amount, curl_off_t with) sum = 0; } else { -#if defined(__GNUC__) && \ - ((__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 1))) +#if (defined(__GNUC__) && \ + ((__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 1)))) || \ + (defined(__clang__) && __clang_major__ >= 8) if(__builtin_mul_overflow(*amount, with, &sum)) return 1; #else @@ -92,61 +95,58 @@ static CURLcode glob_set(struct URLGlob *glob, const char **patternp, */ struct URLPattern *pat; bool done = FALSE; - char *buf = glob->glob_buffer; const char *pattern = *patternp; const char *opattern = pattern; size_t opos = *posp-1; pat = &glob->pattern[glob->size]; /* patterns 0,1,2,... correspond to size=1,3,5,... */ - pat->type = UPTSet; - pat->content.Set.size = 0; - pat->content.Set.ptr_s = 0; - pat->content.Set.elements = NULL; + pat->type = GLOB_SET; + pat->c.set.size = 0; + pat->c.set.idx = 0; + pat->c.set.elem = NULL; pat->globindex = globindex; while(!done) { switch(*pattern) { case '\0': /* URL ended while set was still open */ - return GLOBERROR("unmatched brace", opos, CURLE_URL_MALFORMAT); + return globerror(glob, "unmatched brace", opos, CURLE_URL_MALFORMAT); case '{': case '[': /* no nested expressions at this time */ - return GLOBERROR("nested brace", *posp, CURLE_URL_MALFORMAT); + return globerror(glob, "nested brace", *posp, CURLE_URL_MALFORMAT); case '}': /* set element completed */ if(opattern == pattern) - return GLOBERROR("empty string within braces", *posp, + return globerror(glob, "empty string within braces", *posp, CURLE_URL_MALFORMAT); /* add 1 to size since it will be incremented below */ - if(multiply(amount, pat->content.Set.size + 1)) - return GLOBERROR("range overflow", 0, CURLE_URL_MALFORMAT); + if(multiply(amount, pat->c.set.size + 1)) + return globerror(glob, "range overflow", 0, CURLE_URL_MALFORMAT); FALLTHROUGH(); case ',': - - *buf = '\0'; - if(pat->content.Set.elements) { - char **new_arr = realloc(pat->content.Set.elements, - (size_t)(pat->content.Set.size + 1) * + if(pat->c.set.elem) { + char **new_arr = realloc(pat->c.set.elem, + (size_t)(pat->c.set.size + 1) * sizeof(char *)); if(!new_arr) - return GLOBERROR("out of memory", 0, CURLE_OUT_OF_MEMORY); + return globerror(glob, NULL, 0, CURLE_OUT_OF_MEMORY); - pat->content.Set.elements = new_arr; + pat->c.set.elem = new_arr; } else - pat->content.Set.elements = malloc(sizeof(char *)); + pat->c.set.elem = malloc(sizeof(char *)); - if(!pat->content.Set.elements) - return GLOBERROR("out of memory", 0, CURLE_OUT_OF_MEMORY); + if(!pat->c.set.elem) + return globerror(glob, NULL, 0, CURLE_OUT_OF_MEMORY); - pat->content.Set.elements[pat->content.Set.size] = - strdup(glob->glob_buffer); - if(!pat->content.Set.elements[pat->content.Set.size]) - return GLOBERROR("out of memory", 0, CURLE_OUT_OF_MEMORY); - ++pat->content.Set.size; + pat->c.set.elem[pat->c.set.size] = strdup(curlx_dyn_ptr(&glob->buf)); + if(!pat->c.set.elem[pat->c.set.size]) + return globerror(glob, NULL, 0, CURLE_OUT_OF_MEMORY); + ++pat->c.set.size; + curlx_dyn_reset(&glob->buf); if(*pattern == '}') { pattern++; /* pass the closing brace */ @@ -154,13 +154,13 @@ static CURLcode glob_set(struct URLGlob *glob, const char **patternp, continue; } - buf = glob->glob_buffer; ++pattern; ++(*posp); break; case ']': /* illegal closing bracket */ - return GLOBERROR("unexpected close bracket", *posp, CURLE_URL_MALFORMAT); + return globerror(glob, "unexpected close bracket", *posp, + CURLE_URL_MALFORMAT); case '\\': /* escaped character, skip '\' */ if(pattern[1]) { @@ -169,7 +169,9 @@ static CURLcode glob_set(struct URLGlob *glob, const char **patternp, } FALLTHROUGH(); default: - *buf++ = *pattern++; /* copy character to set element */ + /* copy character to set element */ + if(curlx_dyn_addn(&glob->buf, pattern++, 1)) + return CURLE_OUT_OF_MEMORY; ++(*posp); } } @@ -201,9 +203,9 @@ static CURLcode glob_range(struct URLGlob *glob, const char **patternp, char min_c = 0; char max_c = 0; char end_c = 0; - unsigned long step = 1; + unsigned char step = 1; - pat->type = UPTCharRange; + pat->type = GLOB_ASCII; if((pattern[1] == '-') && pattern[2] && pattern[3]) { min_c = pattern[0]; @@ -217,7 +219,7 @@ static CURLcode glob_range(struct URLGlob *glob, const char **patternp, if(curlx_str_number(&p, &num, 256) || curlx_str_single(&p, ']')) step = 0; else - step = (unsigned long)num; + step = (unsigned char)num; pattern = p; } else if(end_c != ']') @@ -235,50 +237,49 @@ static CURLcode glob_range(struct URLGlob *glob, const char **patternp, (min_c != max_c && (min_c > max_c || step > (unsigned)(max_c - min_c) || (max_c - min_c) > ('z' - 'a')))) /* the pattern is not well-formed */ - return GLOBERROR("bad range", *posp, CURLE_URL_MALFORMAT); + return globerror(glob, "bad range", *posp, CURLE_URL_MALFORMAT); /* if there was a ":[num]" thing, use that as step or else use 1 */ - pat->content.CharRange.step = (int)step; - pat->content.CharRange.ptr_c = pat->content.CharRange.min_c = min_c; - pat->content.CharRange.max_c = max_c; - - if(multiply(amount, ((pat->content.CharRange.max_c - - pat->content.CharRange.min_c) / - pat->content.CharRange.step + 1))) - return GLOBERROR("range overflow", *posp, CURLE_URL_MALFORMAT); + pat->c.ascii.step = step; + pat->c.ascii.letter = pat->c.ascii.min = min_c; + pat->c.ascii.max = max_c; + + if(multiply(amount, ((pat->c.ascii.max - pat->c.ascii.min) / + pat->c.ascii.step + 1))) + return globerror(glob, "range overflow", *posp, CURLE_URL_MALFORMAT); } else if(ISDIGIT(*pattern)) { /* numeric range detected */ - unsigned long min_n = 0; - unsigned long max_n = 0; - unsigned long step_n = 0; + curl_off_t min_n = 0; + curl_off_t max_n = 0; + curl_off_t step_n = 0; curl_off_t num; - pat->type = UPTNumRange; - pat->content.NumRange.padlength = 0; + pat->type = GLOB_NUM; + pat->c.num.npad = 0; if(*pattern == '0') { /* leading zero specified, count them! */ c = pattern; while(ISDIGIT(*c)) { c++; - ++pat->content.NumRange.padlength; /* padding length is set for all - instances of this pattern */ + ++pat->c.num.npad; /* padding length is set for all instances of this + pattern */ } } if(!curlx_str_number(&pattern, &num, CURL_OFF_T_MAX)) { - min_n = (unsigned long)num; + min_n = num; if(!curlx_str_single(&pattern, '-')) { curlx_str_passblanks(&pattern); if(!curlx_str_number(&pattern, &num, CURL_OFF_T_MAX)) { - max_n = (unsigned long)num; + max_n = num; if(!curlx_str_single(&pattern, ']')) step_n = 1; else if(!curlx_str_single(&pattern, ':') && !curlx_str_number(&pattern, &num, CURL_OFF_T_MAX) && !curlx_str_single(&pattern, ']')) { - step_n = (unsigned long)num; + step_n = num; } /* else bad syntax */ } @@ -291,21 +292,21 @@ static CURLcode glob_range(struct URLGlob *glob, const char **patternp, (min_n == max_n && step_n != 1) || (min_n != max_n && (min_n > max_n || step_n > (max_n - min_n)))) /* the pattern is not well-formed */ - return GLOBERROR("bad range", *posp, CURLE_URL_MALFORMAT); + return globerror(glob, "bad range", *posp, CURLE_URL_MALFORMAT); /* typecasting to ints are fine here since we make sure above that we are within 31 bits */ - pat->content.NumRange.ptr_n = pat->content.NumRange.min_n = min_n; - pat->content.NumRange.max_n = max_n; - pat->content.NumRange.step = step_n; - - if(multiply(amount, ((pat->content.NumRange.max_n - - pat->content.NumRange.min_n) / - pat->content.NumRange.step + 1))) - return GLOBERROR("range overflow", *posp, CURLE_URL_MALFORMAT); + pat->c.num.idx = pat->c.num.min = min_n; + pat->c.num.max = max_n; + pat->c.num.step = step_n; + + if(multiply(amount, ((pat->c.num.max - pat->c.num.min) / + pat->c.num.step + 1))) + return globerror(glob, "range overflow", *posp, CURLE_URL_MALFORMAT); } else - return GLOBERROR("bad range specification", *posp, CURLE_URL_MALFORMAT); + return globerror(glob, "bad range specification", *posp, + CURLE_URL_MALFORMAT); *patternp = pattern; return CURLE_OK; @@ -360,8 +361,6 @@ static CURLcode glob_parse(struct URLGlob *glob, const char *pattern, *amount = 1; while(*pattern && !res) { - char *buf = glob->glob_buffer; - size_t sublen = 0; while(*pattern && *pattern != '{') { if(*pattern == '[') { /* skip over IPv6 literals and [] */ @@ -369,16 +368,15 @@ static CURLcode glob_parse(struct URLGlob *glob, const char *pattern, if(!peek_ipv6(pattern, &skip) && (pattern[1] == ']')) skip = 2; if(skip) { - memcpy(buf, pattern, skip); - buf += skip; + if(curlx_dyn_addn(&glob->buf, pattern, skip)) + return CURLE_OUT_OF_MEMORY; pattern += skip; - sublen += skip; continue; } break; } if(*pattern == '}' || *pattern == ']') - return GLOBERROR("unmatched close brace/bracket", pos, + return globerror(glob, "unmatched close brace/bracket", pos, CURLE_URL_MALFORMAT); /* only allow \ to escape known "special letters" */ @@ -390,14 +388,16 @@ static CURLcode glob_parse(struct URLGlob *glob, const char *pattern, ++pattern; ++pos; } - *buf++ = *pattern++; /* copy character to literal */ + /* copy character to literal */ + if(curlx_dyn_addn(&glob->buf, pattern++, 1)) + return CURLE_OUT_OF_MEMORY; ++pos; - sublen++; } - if(sublen) { + if(curlx_dyn_len(&glob->buf)) { /* we got a literal string, add it as a single-item list */ - *buf = '\0'; - res = glob_fixed(glob, glob->glob_buffer, sublen); + res = glob_fixed(glob, curlx_dyn_ptr(&glob->buf), + curlx_dyn_len(&glob->buf)); + curlx_dyn_reset(&glob->buf); } else { switch(*pattern) { @@ -420,102 +420,96 @@ static CURLcode glob_parse(struct URLGlob *glob, const char *pattern, } } - if(++glob->size >= GLOB_PATTERN_NUM) - return GLOBERROR("too many globs", pos, CURLE_URL_MALFORMAT); + if(++glob->size >= glob->palloc) { + struct URLPattern *np = NULL; + glob->palloc *= 2; + if(glob->size < 10000) /* avoid ridiculous amounts */ + np = realloc(glob->pattern, glob->palloc * sizeof(struct URLPattern)); + if(!np) + return globerror(glob, NULL, pos, CURLE_OUT_OF_MEMORY); + glob->pattern = np; + } } return res; } -CURLcode glob_url(struct URLGlob **glob, char *url, curl_off_t *urlnum, +bool glob_inuse(struct URLGlob *glob) +{ + return glob->palloc ? TRUE : FALSE; +} + +CURLcode glob_url(struct URLGlob *glob, char *url, curl_off_t *urlnum, FILE *error) { /* * We can deal with any-size, just make a buffer with the same length * as the specified URL! */ - struct URLGlob *glob_expand; curl_off_t amount = 0; - char *glob_buffer; CURLcode res; - *glob = NULL; - - glob_buffer = malloc(strlen(url) + 1); - if(!glob_buffer) + memset(glob, 0, sizeof(struct URLGlob)); + curlx_dyn_init(&glob->buf, 1024*1024); + glob->pattern = malloc(2 * sizeof(struct URLPattern)); + if(!glob->pattern) return CURLE_OUT_OF_MEMORY; - glob_buffer[0] = 0; + glob->palloc = 2; - glob_expand = calloc(1, sizeof(struct URLGlob)); - if(!glob_expand) { - tool_safefree(glob_buffer); - return CURLE_OUT_OF_MEMORY; - } - glob_expand->urllen = strlen(url); - glob_expand->glob_buffer = glob_buffer; - - res = glob_parse(glob_expand, url, 1, &amount); + res = glob_parse(glob, url, 1, &amount); if(!res) *urlnum = amount; else { - if(error && glob_expand->error) { + if(error && glob->error) { char text[512]; const char *t; - if(glob_expand->pos) { + if(glob->pos) { msnprintf(text, sizeof(text), "%s in URL position %zu:\n%s\n%*s^", - glob_expand->error, - glob_expand->pos, url, (int)glob_expand->pos - 1, " "); + glob->error, + glob->pos, url, (int)glob->pos - 1, " "); t = text; } else - t = glob_expand->error; + t = glob->error; /* send error description to the error-stream */ fprintf(error, "curl: (%d) %s\n", res, t); } /* it failed, we cleanup */ - glob_cleanup(&glob_expand); + glob_cleanup(glob); *urlnum = 1; return res; } - *glob = glob_expand; return CURLE_OK; } -void glob_cleanup(struct URLGlob **globp) +void glob_cleanup(struct URLGlob *glob) { size_t i; curl_off_t elem; - struct URLGlob *glob = *globp; - - if(!glob) - return; - - for(i = 0; i < glob->size; i++) { - if((glob->pattern[i].type == UPTSet) && - (glob->pattern[i].content.Set.elements)) { - for(elem = glob->pattern[i].content.Set.size - 1; - elem >= 0; - --elem) { - tool_safefree(glob->pattern[i].content.Set.elements[elem]); + + if(glob->pattern) { + for(i = 0; i < glob->size; i++) { + if((glob->pattern[i].type == GLOB_SET) && + (glob->pattern[i].c.set.elem)) { + for(elem = glob->pattern[i].c.set.size - 1; elem >= 0; --elem) + tool_safefree(glob->pattern[i].c.set.elem[elem]); + tool_safefree(glob->pattern[i].c.set.elem); } - tool_safefree(glob->pattern[i].content.Set.elements); } + tool_safefree(glob->pattern); + glob->palloc = 0; + curlx_dyn_free(&glob->buf); } - tool_safefree(glob->glob_buffer); - tool_safefree(glob); - *globp = NULL; } CURLcode glob_next_url(char **globbed, struct URLGlob *glob) { struct URLPattern *pat; size_t i; - size_t len; - size_t buflen = glob->urllen + 1; - char *buf = glob->glob_buffer; *globbed = NULL; + curlx_dyn_reset(&glob->buf); if(!glob->beenhere) glob->beenhere = 1; @@ -528,31 +522,28 @@ CURLcode glob_next_url(char **globbed, struct URLGlob *glob) carry = FALSE; pat = &glob->pattern[glob->size - 1 - i]; switch(pat->type) { - case UPTSet: - if((pat->content.Set.elements) && - (++pat->content.Set.ptr_s == pat->content.Set.size)) { - pat->content.Set.ptr_s = 0; + case GLOB_SET: + if((pat->c.set.elem) && (++pat->c.set.idx == pat->c.set.size)) { + pat->c.set.idx = 0; carry = TRUE; } break; - case UPTCharRange: - pat->content.CharRange.ptr_c = - (char)(pat->content.CharRange.step + - (int)((unsigned char)pat->content.CharRange.ptr_c)); - if(pat->content.CharRange.ptr_c > pat->content.CharRange.max_c) { - pat->content.CharRange.ptr_c = pat->content.CharRange.min_c; + case GLOB_ASCII: + pat->c.ascii.letter += pat->c.ascii.step; + if(pat->c.ascii.letter > pat->c.ascii.max) { + pat->c.ascii.letter = pat->c.ascii.min; carry = TRUE; } break; - case UPTNumRange: - pat->content.NumRange.ptr_n += pat->content.NumRange.step; - if(pat->content.NumRange.ptr_n > pat->content.NumRange.max_n) { - pat->content.NumRange.ptr_n = pat->content.NumRange.min_n; + case GLOB_NUM: + pat->c.num.idx += pat->c.num.step; + if(pat->c.num.idx > pat->c.num.max) { + pat->c.num.idx = pat->c.num.min; carry = TRUE; } break; default: - printf("internal error: invalid pattern type (%d)\n", (int)pat->type); + DEBUGASSERT(0); return CURLE_FAILED_INIT; } } @@ -564,68 +555,55 @@ CURLcode glob_next_url(char **globbed, struct URLGlob *glob) for(i = 0; i < glob->size; ++i) { pat = &glob->pattern[i]; switch(pat->type) { - case UPTSet: - if(pat->content.Set.elements) { - msnprintf(buf, buflen, "%s", - pat->content.Set.elements[pat->content.Set.ptr_s]); - len = strlen(buf); - buf += len; - buflen -= len; + case GLOB_SET: + if(pat->c.set.elem) { + if(curlx_dyn_add(&glob->buf, pat->c.set.elem[pat->c.set.idx])) + return CURLE_OUT_OF_MEMORY; } break; - case UPTCharRange: - if(buflen) { - *buf++ = pat->content.CharRange.ptr_c; - *buf = '\0'; - buflen--; - } + case GLOB_ASCII: { + char letter = (char)pat->c.ascii.letter; + if(curlx_dyn_addn(&glob->buf, &letter, 1)) + return CURLE_OUT_OF_MEMORY; break; - case UPTNumRange: - msnprintf(buf, buflen, "%0*" CURL_FORMAT_CURL_OFF_T, - pat->content.NumRange.padlength, - pat->content.NumRange.ptr_n); - len = strlen(buf); - buf += len; - buflen -= len; + } + case GLOB_NUM: + if(curlx_dyn_addf(&glob->buf, "%0*" CURL_FORMAT_CURL_OFF_T, + pat->c.num.npad, pat->c.num.idx)) + return CURLE_OUT_OF_MEMORY; break; default: - printf("internal error: invalid pattern type (%d)\n", (int)pat->type); + DEBUGASSERT(0); return CURLE_FAILED_INIT; } } - *globbed = strdup(glob->glob_buffer); + *globbed = strdup(curlx_dyn_ptr(&glob->buf)); if(!*globbed) return CURLE_OUT_OF_MEMORY; return CURLE_OK; } -#define MAX_OUTPUT_GLOB_LENGTH (10*1024) +#define MAX_OUTPUT_GLOB_LENGTH (1024*1024) -CURLcode glob_match_url(char **result, const char *filename, +CURLcode glob_match_url(char **output, const char *filename, struct URLGlob *glob) { - char numbuf[18]; - const char *appendthis = ""; - size_t appendlen = 0; struct dynbuf dyn; + *output = NULL; - *result = NULL; - - /* We cannot use the glob_buffer for storage since the filename may be - * longer than the URL we use. - */ curlx_dyn_init(&dyn, MAX_OUTPUT_GLOB_LENGTH); while(*filename) { + CURLcode result = CURLE_OK; if(*filename == '#' && ISDIGIT(filename[1])) { const char *ptr = filename; curl_off_t num; struct URLPattern *pat = NULL; filename++; if(!curlx_str_number(&filename, &num, glob->size) && num) { - unsigned long i; + size_t i; num--; /* make it zero based */ /* find the correct glob entry */ for(i = 0; i < glob->size; i++) { @@ -638,46 +616,33 @@ CURLcode glob_match_url(char **result, const char *filename, if(pat) { switch(pat->type) { - case UPTSet: - if(pat->content.Set.elements) { - appendthis = pat->content.Set.elements[pat->content.Set.ptr_s]; - appendlen = - strlen(pat->content.Set.elements[pat->content.Set.ptr_s]); - } + case GLOB_SET: + if(pat->c.set.elem) + result = curlx_dyn_add(&dyn, pat->c.set.elem[pat->c.set.idx]); break; - case UPTCharRange: - numbuf[0] = pat->content.CharRange.ptr_c; - numbuf[1] = 0; - appendthis = numbuf; - appendlen = 1; + case GLOB_ASCII: { + char letter = (char)pat->c.ascii.letter; + result = curlx_dyn_addn(&dyn, &letter, 1); break; - case UPTNumRange: - msnprintf(numbuf, sizeof(numbuf), "%0*" CURL_FORMAT_CURL_OFF_T, - pat->content.NumRange.padlength, - pat->content.NumRange.ptr_n); - appendthis = numbuf; - appendlen = strlen(numbuf); + } + case GLOB_NUM: + result = curlx_dyn_addf(&dyn, "%0*" CURL_FORMAT_CURL_OFF_T, + pat->c.num.npad, pat->c.num.idx); break; default: - fprintf(tool_stderr, "internal error: invalid pattern type (%d)\n", - (int)pat->type); + DEBUGASSERT(0); curlx_dyn_free(&dyn); return CURLE_FAILED_INIT; } } - else { + else /* #[num] out of range, use the #[num] in the output */ - filename = ptr; - appendthis = filename++; - appendlen = 1; - } - } - else { - appendthis = filename++; - appendlen = 1; + result = curlx_dyn_addn(&dyn, ptr, filename - ptr); } - if(curlx_dyn_addn(&dyn, appendthis, appendlen)) - return CURLE_OUT_OF_MEMORY; + else + result = curlx_dyn_addn(&dyn, filename++, 1); + if(result) + return result; } if(curlx_dyn_addn(&dyn, "", 0)) @@ -692,11 +657,11 @@ CURLcode glob_match_url(char **result, const char *filename, curlx_dyn_free(&dyn); if(sc) return CURLE_URL_MALFORMAT; - *result = sanitized; + *output = sanitized; return CURLE_OK; } #else - *result = curlx_dyn_ptr(&dyn); + *output = curlx_dyn_ptr(&dyn); return CURLE_OK; #endif /* _WIN32 || MSDOS */ } diff --git a/vendor/curl/src/tool_urlglob.h b/vendor/curl/src/tool_urlglob.h index 6fcd0db498b..4bcf229ecce 100644 --- a/vendor/curl/src/tool_urlglob.h +++ b/vendor/curl/src/tool_urlglob.h @@ -26,53 +26,54 @@ #include "tool_setup.h" typedef enum { - UPTSet = 1, - UPTCharRange, - UPTNumRange -} URLPatternType; + GLOB_SET = 1, + GLOB_ASCII, + GLOB_NUM +} globtype; struct URLPattern { - URLPatternType type; + globtype type; int globindex; /* the number of this particular glob or -1 if not used within {} or [] */ union { struct { - char **elements; + char **elem; curl_off_t size; - int ptr_s; - } Set; + curl_off_t idx; + } set; struct { - char min_c; - char max_c; - char ptr_c; - int step; - } CharRange; + int min; + int max; + int letter; + unsigned char step; + } ascii; struct { - curl_off_t min_n; - curl_off_t max_n; - int padlength; - curl_off_t ptr_n; + curl_off_t min; + curl_off_t max; + curl_off_t idx; curl_off_t step; - } NumRange; - } content; + int npad; + } num; + } c; }; /* the total number of globs supported */ -#define GLOB_PATTERN_NUM 100 +#define GLOB_PATTERN_NUM 30 struct URLGlob { - struct URLPattern pattern[GLOB_PATTERN_NUM]; + struct dynbuf buf; + struct URLPattern *pattern; + size_t palloc; /* number of pattern entries allocated */ size_t size; - size_t urllen; - char *glob_buffer; char beenhere; const char *error; /* error message */ size_t pos; /* column position of error or 0 */ }; -CURLcode glob_url(struct URLGlob**, char *, curl_off_t *, FILE *); +CURLcode glob_url(struct URLGlob *, char *, curl_off_t *, FILE *); CURLcode glob_next_url(char **, struct URLGlob *); CURLcode glob_match_url(char **, const char *, struct URLGlob *); -void glob_cleanup(struct URLGlob **glob); +void glob_cleanup(struct URLGlob *glob); +bool glob_inuse(struct URLGlob *glob); #endif /* HEADER_CURL_TOOL_URLGLOB_H */ diff --git a/vendor/curl/src/tool_util.c b/vendor/curl/src/tool_util.c index 27c2df1b6ce..e7ab704f120 100644 --- a/vendor/curl/src/tool_util.c +++ b/vendor/curl/src/tool_util.c @@ -24,8 +24,7 @@ #include "tool_setup.h" #include "tool_util.h" -#include -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ #ifdef _WIN32 diff --git a/vendor/curl/src/tool_version.h b/vendor/curl/src/tool_version.h index d4e73a148bb..00be7799ea7 100644 --- a/vendor/curl/src/tool_version.h +++ b/vendor/curl/src/tool_version.h @@ -27,7 +27,7 @@ #define CURL_NAME "curl" #define CURL_COPYRIGHT LIBCURL_COPYRIGHT -#define CURL_VERSION "8.14.1" +#define CURL_VERSION LIBCURL_VERSION #define CURL_VERSION_MAJOR LIBCURL_VERSION_MAJOR #define CURL_VERSION_MINOR LIBCURL_VERSION_MINOR #define CURL_VERSION_PATCH LIBCURL_VERSION_PATCH diff --git a/vendor/curl/src/tool_vms.c b/vendor/curl/src/tool_vms.c index 67889283393..5beb89d2ece 100644 --- a/vendor/curl/src/tool_vms.c +++ b/vendor/curl/src/tool_vms.c @@ -26,14 +26,13 @@ #ifdef __VMS #if defined(__DECC) && !defined(__VAX) && \ - defined(__CRTL_VER) && (__CRTL_VER >= 70301000) + defined(__CRTL_VER) && (__CRTL_VER >= 70301000) #include #endif -#include #include "curlmsg_vms.h" #include "tool_vms.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ void decc$__posix_exit(int __status); void decc$exit(int __status); @@ -108,7 +107,7 @@ void vms_special_exit(int code, int vms_show) } #if defined(__DECC) && !defined(__VAX) && \ - defined(__CRTL_VER) && (__CRTL_VER >= 70301000) + defined(__CRTL_VER) && (__CRTL_VER >= 70301000) /* * 2004-09-19 SMS. diff --git a/vendor/curl/src/tool_vms.h b/vendor/curl/src/tool_vms.h index cc2d31d0534..3da816cf673 100644 --- a/vendor/curl/src/tool_vms.h +++ b/vendor/curl/src/tool_vms.h @@ -40,8 +40,8 @@ void vms_special_exit(int code, int vms_show); #undef exit #define exit(__code) vms_special_exit((__code), (0)) -#define VMS_STS(c,f,e,s) (((c&0xF)<<28)|((f&0xFFF)<<16)|((e&0x1FFF)<3)|(s&7)) -#define VMSSTS_HIDE VMS_STS(1,0,0,0) +#define VMS_STS(c,f,e,s) (((c&0xF)<<28)|((f&0xFFF)<<16)|((e&0x1FFF)<3)|(s&7)) +#define VMSSTS_HIDE VMS_STS(1,0,0,0) #endif /* __VMS */ diff --git a/vendor/curl/src/tool_writeout.c b/vendor/curl/src/tool_writeout.c index 3081b7082d0..0a610de79ab 100644 --- a/vendor/curl/src/tool_writeout.c +++ b/vendor/curl/src/tool_writeout.c @@ -23,11 +23,10 @@ ***************************************************************************/ #include "tool_setup.h" -#include #include "tool_cfgable.h" #include "tool_writeout.h" #include "tool_writeout_json.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ static int writeTime(FILE *stream, const struct writeoutvar *wovar, struct per_transfer *per, CURLcode per_result, @@ -149,7 +148,7 @@ static const struct writeoutvar variables[] = { {"urle.scheme", VAR_INPUT_URLESCHEME, CURLINFO_NONE, writeString}, {"urle.user", VAR_INPUT_URLEUSER, CURLINFO_NONE, writeString}, {"urle.zoneid", VAR_INPUT_URLEZONEID, CURLINFO_NONE, writeString}, - {"urlnum", VAR_URLNUM, CURLINFO_NONE, writeLong}, + {"urlnum", VAR_URLNUM, CURLINFO_NONE, writeOffset}, {"xfer_id", VAR_EASY_ID, CURLINFO_XFER_ID, writeOffset} }; @@ -463,12 +462,6 @@ static int writeLong(FILE *stream, const struct writeoutvar *wovar, longinfo = (long)per_result; valid = true; break; - case VAR_URLNUM: - if(per->urlnum <= INT_MAX) { - longinfo = (long)per->urlnum; - valid = true; - } - break; default: DEBUGASSERT(0); break; @@ -509,7 +502,16 @@ static int writeOffset(FILE *stream, const struct writeoutvar *wovar, valid = true; } else { - DEBUGASSERT(0); + switch(wovar->id) { + case VAR_URLNUM: + if(per->urlnum <= INT_MAX) { + offinfo = per->urlnum; + valid = true; + } + break; + default: + DEBUGASSERT(0); + } } if(valid) { @@ -537,6 +539,82 @@ matchvar(const void *m1, const void *m2) #define MAX_WRITEOUT_NAME_LENGTH 24 +/* return the position after %time{} */ +static const char *outtime(const char *ptr, /* %time{ ... */ + FILE *stream) +{ + const char *end; + ptr += 6; + end = strchr(ptr, '}'); + if(end) { + struct tm *utc; + struct dynbuf format; + char output[256]; /* max output time length */ +#ifdef HAVE_GETTIMEOFDAY + struct timeval cnow; +#else + struct curltime cnow; +#endif + time_t secs; + unsigned int usecs; + size_t i; + size_t vlen; + CURLcode result = CURLE_OK; + +#ifdef HAVE_GETTIMEOFDAY + gettimeofday(&cnow, NULL); +#else + cnow.tv_sec = time(NULL); + cnow.tv_usec = 0; +#endif + secs = cnow.tv_sec; + usecs = (unsigned int)cnow.tv_usec; +#ifdef DEBUGBUILD + { + const char *timestr = getenv("CURL_TIME"); + if(timestr) { + curl_off_t val; + curlx_str_number(×tr, &val, TIME_T_MAX); + secs = (time_t)val; + usecs = (unsigned int)(val % 1000000); + } + } +#endif + vlen = end - ptr; + curlx_dyn_init(&format, 1024); + + /* insert sub-seconds for %f */ + /* insert +0000 for %z because it is otherwise not portable */ + /* insert UTC for %Z because it is otherwise not portable */ + for(i = 0; !result && i < vlen; i++) { + if((i < vlen - 1) && ptr[i] == '%' && + ((ptr[i + 1] == 'f') || ((ptr[i + 1] | 0x20) == 'z'))) { + if(ptr[i + 1] == 'f') + result = curlx_dyn_addf(&format, "%06u", usecs); + else if(ptr[i + 1] == 'Z') + result = curlx_dyn_addn(&format, "UTC", 3); + else + result = curlx_dyn_addn(&format, "+0000", 5); + i++; + } + else + result = curlx_dyn_addn(&format, &ptr[i], 1); + } + if(!result) { + /* !checksrc! disable BANNEDFUNC 1 */ + utc = gmtime(&secs); + if(curlx_dyn_len(&format) && utc && + strftime(output, sizeof(output), curlx_dyn_ptr(&format), utc)) + fputs(output, stream); + curlx_dyn_free(&format); + } + ptr = end + 1; + } + else + fputs("%time{", stream); + return ptr; +} + void ourWriteOut(struct OperationConfig *config, struct per_transfer *per, CURLcode per_result) { @@ -638,6 +716,9 @@ void ourWriteOut(struct OperationConfig *config, struct per_transfer *per, else fputs("%header{", stream); } + else if(!strncmp("time{", &ptr[1], 5)) { + ptr = outtime(ptr, stream); + } else if(!strncmp("output{", &ptr[1], 7)) { bool append = FALSE; ptr += 8; diff --git a/vendor/curl/src/tool_writeout_json.c b/vendor/curl/src/tool_writeout_json.c index 1f10942378b..cfa2d1c9013 100644 --- a/vendor/curl/src/tool_writeout_json.c +++ b/vendor/curl/src/tool_writeout_json.c @@ -23,7 +23,6 @@ ***************************************************************************/ #include "tool_setup.h" -#include #include "tool_cfgable.h" #include "tool_writeout_json.h" #include "tool_writeout.h" diff --git a/vendor/curl/src/tool_xattr.c b/vendor/curl/src/tool_xattr.c index c0c1b2a99d9..346c805a405 100644 --- a/vendor/curl/src/tool_xattr.c +++ b/vendor/curl/src/tool_xattr.c @@ -24,7 +24,7 @@ #include "tool_setup.h" #include "tool_xattr.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ #ifdef USE_XATTR @@ -43,12 +43,7 @@ static const struct xattr_mapping { /* returns a new URL that needs to be freed */ /* @unittest: 1621 */ -#ifdef UNITTESTS -char *stripcredentials(const char *url); -#else -static -#endif -char *stripcredentials(const char *url) +UNITTEST char *stripcredentials(const char *url) { CURLU *u; CURLUcode uc; diff --git a/vendor/curl/src/tool_xattr.h b/vendor/curl/src/tool_xattr.h index 2ffffd275f6..31301b3b061 100644 --- a/vendor/curl/src/tool_xattr.h +++ b/vendor/curl/src/tool_xattr.h @@ -38,6 +38,10 @@ #ifdef USE_XATTR int fwrite_xattr(CURL *curl, const char *url, int fd); +#ifdef UNITTESTS +UNITTEST char *stripcredentials(const char *url); +#endif + #else #define fwrite_xattr(a,b,c) 0 #endif diff --git a/vendor/curl/src/var.c b/vendor/curl/src/var.c index 9dba7e4c1a1..612735016c9 100644 --- a/vendor/curl/src/var.c +++ b/vendor/curl/src/var.c @@ -23,7 +23,6 @@ ***************************************************************************/ #include "tool_setup.h" -#include #include "tool_cfgable.h" #include "tool_getparam.h" #include "tool_helpers.h" @@ -32,25 +31,15 @@ #include "tool_parsecfg.h" #include "tool_paramhlp.h" #include "tool_writeout_json.h" +#include "tool_strdup.h" #include "var.h" -#include /* keep this as LAST include */ +#include "memdebug.h" /* keep this as LAST include */ #define MAX_EXPAND_CONTENT 10000000 #define MAX_VAR_LEN 128 /* max length of a name */ -static char *Memdup(const char *data, size_t len) -{ - char *p = malloc(len + 1); - if(!p) - return NULL; - if(len) - memcpy(p, data, len); - p[len] = 0; - return p; -} - /* free everything */ -void varcleanup(struct GlobalConfig *global) +void varcleanup(void) { struct tool_var *list = global->variables; while(list) { @@ -61,8 +50,7 @@ void varcleanup(struct GlobalConfig *global) } } -static const struct tool_var *varcontent(struct GlobalConfig *global, - const char *name, size_t nlen) +static const struct tool_var *varcontent(const char *name, size_t nlen) { struct tool_var *list = global->variables; while(list) { @@ -90,8 +78,7 @@ static const struct tool_var *varcontent(struct GlobalConfig *global, #define FUNC_64DEC "64dec" /* base64 decode */ #define FUNC_64DEC_LEN (sizeof(FUNC_64DEC) - 1) -static ParameterError varfunc(struct GlobalConfig *global, - char *c, /* content */ +static ParameterError varfunc(char *c, /* content */ size_t clen, /* content length */ char *f, /* functions */ size_t flen, /* function string length */ @@ -200,8 +187,7 @@ static ParameterError varfunc(struct GlobalConfig *global, } else { /* unsupported function */ - errorf(global, "unknown variable function in '%.*s'", - (int)flen, finput); + errorf("unknown variable function in '%.*s'", (int)flen, finput); err = PARAM_EXPAND_ERROR; break; } @@ -209,7 +195,7 @@ static ParameterError varfunc(struct GlobalConfig *global, free(c); clen = curlx_dyn_len(out); - c = Memdup(curlx_dyn_ptr(out), clen); + c = memdup0(curlx_dyn_ptr(out), clen); if(!c) { err = PARAM_NO_MEM; break; @@ -223,8 +209,7 @@ static ParameterError varfunc(struct GlobalConfig *global, return err; } -ParameterError varexpand(struct GlobalConfig *global, - const char *line, struct dynbuf *out, +ParameterError varexpand(const char *line, struct dynbuf *out, bool *replaced) { CURLcode result; @@ -259,7 +244,7 @@ ParameterError varexpand(struct GlobalConfig *global, if(!clp) { /* uneven braces */ - warnf(global, "missing close '}}' in '%s'", input); + warnf("missing close '}}' in '%s'", input); break; } @@ -273,7 +258,7 @@ ParameterError varexpand(struct GlobalConfig *global, else nlen = clp - envp; if(!nlen || (nlen >= sizeof(name))) { - warnf(global, "bad variable name length '%s'", input); + warnf("bad variable name length '%s'", input); /* insert the text as-is since this is not an env variable */ result = curlx_dyn_addn(out, line, clp - line + prefix); if(result) @@ -293,7 +278,7 @@ ParameterError varexpand(struct GlobalConfig *global, for(i = 0; (i < nlen) && (ISALNUM(name[i]) || (name[i] == '_')); i++); if(i != nlen) { - warnf(global, "bad variable name: %s", name); + warnf("bad variable name: %s", name); /* insert the text as-is since this is not an env variable */ result = curlx_dyn_addn(out, envp - prefix, clp - envp + prefix + 2); @@ -304,7 +289,7 @@ ParameterError varexpand(struct GlobalConfig *global, char *value; size_t vlen = 0; struct dynbuf buf; - const struct tool_var *v = varcontent(global, name, nlen); + const struct tool_var *v = varcontent(name, nlen); if(v) { value = (char *)CURL_UNCONST(v->content); vlen = v->clen; @@ -316,8 +301,7 @@ ParameterError varexpand(struct GlobalConfig *global, if(funcp) { /* apply the list of functions on the value */ size_t flen = clp - funcp; - ParameterError err = varfunc(global, value, vlen, funcp, flen, - &buf); + ParameterError err = varfunc(value, vlen, funcp, flen, &buf); if(err) return err; value = curlx_dyn_ptr(&buf); @@ -329,7 +313,7 @@ ParameterError varexpand(struct GlobalConfig *global, using normal means, this is an error. */ char *nb = memchr(value, '\0', vlen); if(nb) { - errorf(global, "variable contains null byte"); + errorf("variable contains null byte"); return PARAM_EXPAND_ERROR; } } @@ -363,24 +347,23 @@ ParameterError varexpand(struct GlobalConfig *global, * that we can improve this if we want better performance when managing many * at a later point. */ -static ParameterError addvariable(struct GlobalConfig *global, - const char *name, +static ParameterError addvariable(const char *name, size_t nlen, const char *content, size_t clen, bool contalloc) { struct tool_var *p; - const struct tool_var *check = varcontent(global, name, nlen); + const struct tool_var *check = varcontent(name, nlen); DEBUGASSERT(nlen); if(check) - notef(global, "Overwriting variable '%s'", check->name); + notef("Overwriting variable '%s'", check->name); p = calloc(1, sizeof(struct tool_var) + nlen); if(p) { memcpy(p->name, name, nlen); - p->content = contalloc ? content : Memdup(content, clen); + p->content = contalloc ? content : memdup0(content, clen); if(p->content) { p->clen = clen; @@ -395,8 +378,7 @@ static ParameterError addvariable(struct GlobalConfig *global, #define MAX_FILENAME 10000 -ParameterError setvariable(struct GlobalConfig *global, - const char *input) +ParameterError setvariable(const char *input) { const char *name; size_t nlen; @@ -420,7 +402,7 @@ ParameterError setvariable(struct GlobalConfig *global, line++; nlen = line - name; if(!nlen || (nlen >= MAX_VAR_LEN)) { - warnf(global, "Bad variable name length (%zd), skipping", nlen); + warnf("Bad variable name length (%zd), skipping", nlen); return PARAM_OK; } if(import) { @@ -435,7 +417,7 @@ ParameterError setvariable(struct GlobalConfig *global, ge = getenv(name); if(!*line && !ge) { /* no assign, no variable, fail */ - errorf(global, "Variable '%s' import fail, not set", name); + errorf("Variable '%s' import fail, not set", name); return PARAM_EXPAND_ERROR; } else if(ge) { @@ -475,8 +457,7 @@ ParameterError setvariable(struct GlobalConfig *global, else { file = fopen(line, "rb"); if(!file) { - errorf(global, "Failed to open %s: %s", line, - strerror(errno)); + errorf("Failed to open %s: %s", line, strerror(errno)); err = PARAM_READ_ERROR; } } @@ -510,10 +491,10 @@ ParameterError setvariable(struct GlobalConfig *global, } } else { - warnf(global, "Bad --variable syntax, skipping: %s", input); + warnf("Bad --variable syntax, skipping: %s", input); return PARAM_OK; } - err = addvariable(global, name, nlen, content, clen, contalloc); + err = addvariable(name, nlen, content, clen, contalloc); if(err) { if(contalloc) free(content); diff --git a/vendor/curl/src/var.h b/vendor/curl/src/var.h index 8e5b6850857..4f1361cf1ea 100644 --- a/vendor/curl/src/var.h +++ b/vendor/curl/src/var.h @@ -25,7 +25,6 @@ ***************************************************************************/ #include "tool_getparam.h" -#include struct tool_var { struct tool_var *next; @@ -34,14 +33,11 @@ struct tool_var { char name[1]; /* allocated as part of the struct */ }; -struct GlobalConfig; - -ParameterError setvariable(struct GlobalConfig *global, const char *input); -ParameterError varexpand(struct GlobalConfig *global, - const char *line, struct dynbuf *out, +ParameterError setvariable(const char *input); +ParameterError varexpand(const char *line, struct dynbuf *out, bool *replaced); /* free everything */ -void varcleanup(struct GlobalConfig *global); +void varcleanup(void); #endif /* HEADER_CURL_VAR_H */ diff --git a/vendor/curl/tests/.gitignore b/vendor/curl/tests/.gitignore new file mode 100644 index 00000000000..83cda8fcebc --- /dev/null +++ b/vendor/curl/tests/.gitignore @@ -0,0 +1,25 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +*pid +configurehelp.pm +curl_client_key +curl_client_key.pub +curl_client_knownhosts +curl_host_rsa_key +curl_host_rsa_key.pub +curl_host_rsa_key.pub_md5 +curl_host_rsa_key.pub_sha256 +curl_sftp_cmds +curl_sftp_config +curl_ssh_config +curl_sshd_config +ftps_stunnel.conf +https_stunnel.conf +log* +*.port +config +second-hsts.txt +runtests.1 +testcurl.1 diff --git a/vendor/curl/tests/certs/.gitignore b/vendor/curl/tests/certs/.gitignore new file mode 100644 index 00000000000..98adccef08b --- /dev/null +++ b/vendor/curl/tests/certs/.gitignore @@ -0,0 +1,14 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl +test-*.crl +test-*.crt +test-*.csr +test-*.der +test-*.key* +test-*.pem +test-ca.cacert +test-ca.cnt* +test-ca.db* +test-ca.raw* +test-ca.srl diff --git a/vendor/curl/tests/data/.gitignore b/vendor/curl/tests/data/.gitignore new file mode 100644 index 00000000000..52ecd174e6c --- /dev/null +++ b/vendor/curl/tests/data/.gitignore @@ -0,0 +1,5 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +DISABLED.local diff --git a/vendor/curl/tests/http/.gitignore b/vendor/curl/tests/http/.gitignore new file mode 100644 index 00000000000..37a847fa934 --- /dev/null +++ b/vendor/curl/tests/http/.gitignore @@ -0,0 +1,6 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +config.ini +gen diff --git a/vendor/curl/tests/http/testenv/mod_curltest/.gitignore b/vendor/curl/tests/http/testenv/mod_curltest/.gitignore new file mode 100644 index 00000000000..8774a09325e --- /dev/null +++ b/vendor/curl/tests/http/testenv/mod_curltest/.gitignore @@ -0,0 +1,5 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +*.slo diff --git a/vendor/curl/tests/http/testenv/mod_curltest/mod_curltest.c b/vendor/curl/tests/http/testenv/mod_curltest/mod_curltest.c index 7e6aff87b32..d9ff9152c87 100644 --- a/vendor/curl/tests/http/testenv/mod_curltest/mod_curltest.c +++ b/vendor/curl/tests/http/testenv/mod_curltest/mod_curltest.c @@ -51,7 +51,7 @@ AP_DECLARE_MODULE(curltest) = NULL, /* func to merge per server config */ NULL, /* command handlers */ curltest_hooks, -#if defined(AP_MODULE_FLAG_NONE) +#ifdef AP_MODULE_FLAG_NONE AP_MODULE_FLAG_ALWAYS_MERGE #endif }; diff --git a/vendor/curl/tests/libtest/.gitignore b/vendor/curl/tests/libtest/.gitignore new file mode 100644 index 00000000000..c78bdfd7661 --- /dev/null +++ b/vendor/curl/tests/libtest/.gitignore @@ -0,0 +1,7 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +libtests +libtests.c +lib1521.c diff --git a/vendor/curl/tests/libtest/cli_h2_pausing.c b/vendor/curl/tests/libtest/cli_h2_pausing.c new file mode 100644 index 00000000000..8cc440daacf --- /dev/null +++ b/vendor/curl/tests/libtest/cli_h2_pausing.c @@ -0,0 +1,295 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 based on the PoC client of issue #11982 + */ +#include "first.h" + +#include "testtrace.h" +#include "memdebug.h" + +static void usage_h2_pausing(const char *msg) +{ + if(msg) + curl_mfprintf(stderr, "%s\n", msg); + curl_mfprintf(stderr, + "usage: [options] url\n" + " pause downloads with following options:\n" + " -V http_version (http/1.1, h2, h3) http version to use\n" + ); +} + +struct handle +{ + size_t idx; + int paused; + int resumed; + int errored; + int fail_write; + CURL *h; +}; + +static size_t cb(char *data, size_t size, size_t nmemb, void *clientp) +{ + size_t realsize = size * nmemb; + struct handle *handle = (struct handle *) clientp; + curl_off_t totalsize; + + (void)data; + if(curl_easy_getinfo(handle->h, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, + &totalsize) == CURLE_OK) + curl_mfprintf(stderr, "INFO: [%zu] write, " + "Content-Length %" CURL_FORMAT_CURL_OFF_T "\n", + handle->idx, totalsize); + + if(!handle->resumed) { + ++handle->paused; + curl_mfprintf(stderr, "INFO: [%zu] write, PAUSING %d time on %zu bytes\n", + handle->idx, handle->paused, realsize); + assert(handle->paused == 1); + return CURL_WRITEFUNC_PAUSE; + } + if(handle->fail_write) { + ++handle->errored; + curl_mfprintf(stderr, "INFO: [%zu] FAIL write of %zu bytes, %d time\n", + handle->idx, realsize, handle->errored); + return CURL_WRITEFUNC_ERROR; + } + curl_mfprintf(stderr, "INFO: [%zu] write, accepting %zu bytes\n", + handle->idx, realsize); + return realsize; +} + +#define CLI_ERR() \ + do { \ + curl_mfprintf(stderr, "something unexpected went wrong - bailing out!\n");\ + return (CURLcode)2; \ + } while(0) + +static CURLcode test_cli_h2_pausing(const char *URL) +{ + struct handle handles[2]; + CURLM *multi_handle; + int still_running = 1, msgs_left, numfds; + size_t i; + CURLMsg *msg; + int rounds = 0; + CURLcode rc = CURLE_OK; + CURLU *cu; + struct curl_slist *resolve = NULL; + char resolve_buf[1024]; + const char *url; + char *host = NULL, *port = NULL; + int all_paused = 0; + int resume_round = -1; + long http_version = CURL_HTTP_VERSION_2_0; + int ch; + + (void)URL; + + while((ch = cgetopt(test_argc, test_argv, "hV:")) != -1) { + switch(ch) { + case 'h': + usage_h2_pausing(NULL); + return (CURLcode)2; + case 'V': { + if(!strcmp("http/1.1", coptarg)) + http_version = CURL_HTTP_VERSION_1_1; + else if(!strcmp("h2", coptarg)) + http_version = CURL_HTTP_VERSION_2_0; + else if(!strcmp("h3", coptarg)) + http_version = CURL_HTTP_VERSION_3ONLY; + else { + usage_h2_pausing("invalid http version"); + return (CURLcode)1; + } + break; + } + default: + usage_h2_pausing("invalid option"); + return (CURLcode)1; + } + } + test_argc -= coptind; + test_argv += coptind; + + if(test_argc != 1) { + curl_mfprintf(stderr, "ERROR: need URL as argument\n"); + return (CURLcode)2; + } + url = test_argv[0]; + + curl_global_init(CURL_GLOBAL_DEFAULT); + curl_global_trace("ids,time,http/2,http/3"); + + cu = curl_url(); + if(!cu) { + curl_mfprintf(stderr, "out of memory\n"); + return (CURLcode)1; + } + if(curl_url_set(cu, CURLUPART_URL, url, 0)) { + curl_mfprintf(stderr, "not a URL: '%s'\n", url); + return (CURLcode)1; + } + if(curl_url_get(cu, CURLUPART_HOST, &host, 0)) { + curl_mfprintf(stderr, "could not get host of '%s'\n", url); + return (CURLcode)1; + } + if(curl_url_get(cu, CURLUPART_PORT, &port, 0)) { + curl_mfprintf(stderr, "could not get port of '%s'\n", url); + return (CURLcode)1; + } + memset(&resolve, 0, sizeof(resolve)); + curl_msnprintf(resolve_buf, sizeof(resolve_buf)-1, "%s:%s:127.0.0.1", + host, port); + resolve = curl_slist_append(resolve, resolve_buf); + + for(i = 0; i < CURL_ARRAYSIZE(handles); i++) { + handles[i].idx = i; + handles[i].paused = 0; + handles[i].resumed = 0; + handles[i].errored = 0; + handles[i].fail_write = 1; + handles[i].h = curl_easy_init(); + if(!handles[i].h || + curl_easy_setopt(handles[i].h, CURLOPT_WRITEFUNCTION, cb) != CURLE_OK || + curl_easy_setopt(handles[i].h, CURLOPT_WRITEDATA, &handles[i]) + != CURLE_OK || + curl_easy_setopt(handles[i].h, CURLOPT_FOLLOWLOCATION, 1L) != CURLE_OK || + curl_easy_setopt(handles[i].h, CURLOPT_VERBOSE, 1L) != CURLE_OK || + curl_easy_setopt(handles[i].h, CURLOPT_DEBUGFUNCTION, cli_debug_cb) + != CURLE_OK || + curl_easy_setopt(handles[i].h, CURLOPT_SSL_VERIFYPEER, 0L) != CURLE_OK || + curl_easy_setopt(handles[i].h, CURLOPT_RESOLVE, resolve) != CURLE_OK || + curl_easy_setopt(handles[i].h, CURLOPT_PIPEWAIT, 1L) || + curl_easy_setopt(handles[i].h, CURLOPT_URL, url) != CURLE_OK) { + CLI_ERR(); + } + curl_easy_setopt(handles[i].h, CURLOPT_HTTP_VERSION, http_version); + } + + multi_handle = curl_multi_init(); + if(!multi_handle) + CLI_ERR(); + + for(i = 0; i < CURL_ARRAYSIZE(handles); i++) { + if(curl_multi_add_handle(multi_handle, handles[i].h) != CURLM_OK) + CLI_ERR(); + } + + for(rounds = 0;; rounds++) { + curl_mfprintf(stderr, "INFO: multi_perform round %d\n", rounds); + if(curl_multi_perform(multi_handle, &still_running) != CURLM_OK) + CLI_ERR(); + + if(!still_running) { + int as_expected = 1; + curl_mfprintf(stderr, "INFO: no more handles running\n"); + for(i = 0; i < CURL_ARRAYSIZE(handles); i++) { + if(!handles[i].paused) { + curl_mfprintf(stderr, "ERROR: [%zu] NOT PAUSED\n", i); + as_expected = 0; + } + else if(handles[i].paused != 1) { + curl_mfprintf(stderr, "ERROR: [%zu] PAUSED %d times!\n", + i, handles[i].paused); + as_expected = 0; + } + else if(!handles[i].resumed) { + curl_mfprintf(stderr, "ERROR: [%zu] NOT resumed!\n", i); + as_expected = 0; + } + else if(handles[i].errored != 1) { + curl_mfprintf(stderr, "ERROR: [%zu] NOT errored once, %d instead!\n", + i, handles[i].errored); + as_expected = 0; + } + } + if(!as_expected) { + curl_mfprintf(stderr, "ERROR: handles not in expected state " + "after %d rounds\n", rounds); + rc = (CURLcode)1; + } + break; + } + + if(curl_multi_poll(multi_handle, NULL, 0, 100, &numfds) != CURLM_OK) + CLI_ERR(); + + /* !checksrc! disable EQUALSNULL 1 */ + while((msg = curl_multi_info_read(multi_handle, &msgs_left)) != NULL) { + if(msg->msg == CURLMSG_DONE) { + for(i = 0; i < CURL_ARRAYSIZE(handles); i++) { + if(msg->easy_handle == handles[i].h) { + if(handles[i].paused != 1 || !handles[i].resumed) { + curl_mfprintf(stderr, "ERROR: [%zu] done, paused=%d, " + "resumed=%d, result %d - wtf?\n", i, + handles[i].paused, + handles[i].resumed, msg->data.result); + rc = (CURLcode)1; + goto out; + } + } + } + } + } + + /* Successfully paused? */ + if(!all_paused) { + for(i = 0; i < CURL_ARRAYSIZE(handles); i++) { + if(!handles[i].paused) { + break; + } + } + all_paused = (i == CURL_ARRAYSIZE(handles)); + if(all_paused) { + curl_mfprintf(stderr, "INFO: all transfers paused\n"); + /* give transfer some rounds to mess things up */ + resume_round = rounds + 2; + } + } + if(resume_round > 0 && rounds == resume_round) { + /* time to resume */ + for(i = 0; i < CURL_ARRAYSIZE(handles); i++) { + curl_mfprintf(stderr, "INFO: [%zu] resumed\n", i); + handles[i].resumed = 1; + curl_easy_pause(handles[i].h, CURLPAUSE_CONT); + } + } + } + +out: + for(i = 0; i < CURL_ARRAYSIZE(handles); i++) { + curl_multi_remove_handle(multi_handle, handles[i].h); + curl_easy_cleanup(handles[i].h); + } + + curl_slist_free_all(resolve); + curl_free(host); + curl_free(port); + curl_url_cleanup(cu); + curl_multi_cleanup(multi_handle); + curl_global_cleanup(); + + return rc; +} diff --git a/vendor/curl/tests/libtest/cli_h2_serverpush.c b/vendor/curl/tests/libtest/cli_h2_serverpush.c new file mode 100644 index 00000000000..a58f38dd0a6 --- /dev/null +++ b/vendor/curl/tests/libtest/cli_h2_serverpush.c @@ -0,0 +1,174 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "first.h" + +#include "testtrace.h" +#include "memdebug.h" + +static FILE *out_download; + +static int setup_h2_serverpush(CURL *hnd, const char *url) +{ + out_download = fopen("download_0.data", "wb"); + if(!out_download) + return 1; /* failed */ + + curl_easy_setopt(hnd, CURLOPT_URL, url); + curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); + curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYHOST, 0L); + + curl_easy_setopt(hnd, CURLOPT_WRITEDATA, out_download); + + /* please be verbose */ + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(hnd, CURLOPT_DEBUGFUNCTION, libtest_debug_cb); + curl_easy_setopt(hnd, CURLOPT_DEBUGDATA, &debug_config); + + /* wait for pipe connection to confirm */ + curl_easy_setopt(hnd, CURLOPT_PIPEWAIT, 1L); + + return 0; /* all is good */ +} + +static FILE *out_push; + +/* called when there's an incoming push */ +static int server_push_callback(CURL *parent, + CURL *easy, + size_t num_headers, + struct curl_pushheaders *headers, + void *userp) +{ + char *headp; + size_t i; + int *transfers = (int *)userp; + char filename[128]; + static unsigned int count = 0; + int rv; + + (void)parent; /* we have no use for this */ + curl_msnprintf(filename, sizeof(filename) - 1, "push%u", count++); + + /* here's a new stream, save it in a new file for each new push */ + out_push = fopen(filename, "wb"); + if(!out_push) { + /* if we cannot save it, deny it */ + curl_mfprintf(stderr, "Failed to create output file for push\n"); + rv = CURL_PUSH_DENY; + goto out; + } + + /* write to this file */ + curl_easy_setopt(easy, CURLOPT_WRITEDATA, out_push); + + curl_mfprintf(stderr, "**** push callback approves stream %u, " + "got %zu headers!\n", count, num_headers); + + for(i = 0; i < num_headers; i++) { + headp = curl_pushheader_bynum(headers, i); + curl_mfprintf(stderr, "**** header %zu: %s\n", i, headp); + } + + headp = curl_pushheader_byname(headers, ":path"); + if(headp) { + curl_mfprintf(stderr, "**** The PATH is %s\n", + headp /* skip :path + colon */); + } + + (*transfers)++; /* one more */ + rv = CURL_PUSH_OK; + +out: + return rv; +} + +/* + * Download a file over HTTP/2, take care of server push. + */ +static CURLcode test_cli_h2_serverpush(const char *URL) +{ + CURL *easy; + CURLM *multi_handle; + int transfers = 1; /* we start with one */ + struct CURLMsg *m; + + debug_config.nohex = TRUE; + debug_config.tracetime = FALSE; + + if(!URL) { + curl_mfprintf(stderr, "need URL as argument\n"); + return (CURLcode)2; + } + + multi_handle = curl_multi_init(); + curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX); + curl_multi_setopt(multi_handle, CURLMOPT_PUSHFUNCTION, server_push_callback); + curl_multi_setopt(multi_handle, CURLMOPT_PUSHDATA, &transfers); + + easy = curl_easy_init(); + if(setup_h2_serverpush(easy, URL)) { + fclose(out_download); + curl_mfprintf(stderr, "failed\n"); + return (CURLcode)1; + } + + curl_multi_add_handle(multi_handle, easy); + do { + int still_running; /* keep number of running handles */ + CURLMcode mc = curl_multi_perform(multi_handle, &still_running); + + if(still_running) + /* wait for activity, timeout or "nothing" */ + mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL); + + if(mc) + break; + + /* + * A little caution when doing server push is that libcurl itself has + * created and added one or more easy handles but we need to clean them up + * when we are done. + */ + do { + int msgq = 0; + m = curl_multi_info_read(multi_handle, &msgq); + if(m && (m->msg == CURLMSG_DONE)) { + CURL *e = m->easy_handle; + transfers--; + curl_multi_remove_handle(multi_handle, e); + curl_easy_cleanup(e); + } + } while(m); + + } while(transfers); /* as long as we have transfers going */ + + curl_multi_cleanup(multi_handle); + + fclose(out_download); + if(out_push) + fclose(out_push); + + return CURLE_OK; +} diff --git a/vendor/curl/tests/libtest/cli_h2_upgrade_extreme.c b/vendor/curl/tests/libtest/cli_h2_upgrade_extreme.c new file mode 100644 index 00000000000..f6b277424fd --- /dev/null +++ b/vendor/curl/tests/libtest/cli_h2_upgrade_extreme.c @@ -0,0 +1,165 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "first.h" + +#include "testtrace.h" +#include "memdebug.h" + +static size_t write_h2_upg_extreme_cb(char *ptr, size_t size, size_t nmemb, + void *opaque) +{ + (void)ptr; + (void)opaque; + return size * nmemb; +} + +static CURLcode test_cli_h2_upgrade_extreme(const char *URL) +{ + CURLM *multi = NULL; + CURL *easy; + CURLMcode mc; + int running_handles = 0, start_count, numfds; + CURLMsg *msg; + int msgs_in_queue; + char range[128]; + CURLcode exitcode = (CURLcode)1; + + if(!URL) { + curl_mfprintf(stderr, "need URL as argument\n"); + return (CURLcode)2; + } + + multi = curl_multi_init(); + if(!multi) { + curl_mfprintf(stderr, "curl_multi_init failed\n"); + goto cleanup; + } + + start_count = 200; + do { + if(start_count) { + easy = curl_easy_init(); + if(!easy) { + curl_mfprintf(stderr, "curl_easy_init failed\n"); + goto cleanup; + } + curl_easy_setopt(easy, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(easy, CURLOPT_DEBUGFUNCTION, cli_debug_cb); + curl_easy_setopt(easy, CURLOPT_URL, URL); + curl_easy_setopt(easy, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt(easy, CURLOPT_AUTOREFERER, 1L); + curl_easy_setopt(easy, CURLOPT_FAILONERROR, 1L); + curl_easy_setopt(easy, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); + curl_easy_setopt(easy, CURLOPT_WRITEFUNCTION, write_h2_upg_extreme_cb); + curl_easy_setopt(easy, CURLOPT_WRITEDATA, NULL); + curl_easy_setopt(easy, CURLOPT_HTTPGET, 1L); + curl_msnprintf(range, sizeof(range), + "%" CURL_FORMAT_CURL_OFF_TU "-" + "%" CURL_FORMAT_CURL_OFF_TU, + (curl_off_t)0, + (curl_off_t)16384); + curl_easy_setopt(easy, CURLOPT_RANGE, range); + + mc = curl_multi_add_handle(multi, easy); + if(mc != CURLM_OK) { + curl_mfprintf(stderr, "curl_multi_add_handle: %s\n", + curl_multi_strerror(mc)); + curl_easy_cleanup(easy); + goto cleanup; + } + --start_count; + } + + mc = curl_multi_perform(multi, &running_handles); + if(mc != CURLM_OK) { + curl_mfprintf(stderr, "curl_multi_perform: %s\n", + curl_multi_strerror(mc)); + goto cleanup; + } + + if(running_handles) { + mc = curl_multi_poll(multi, NULL, 0, 1000000, &numfds); + if(mc != CURLM_OK) { + curl_mfprintf(stderr, "curl_multi_poll: %s\n", + curl_multi_strerror(mc)); + goto cleanup; + } + } + + /* Check for finished handles and remove. */ + /* !checksrc! disable EQUALSNULL 1 */ + while((msg = curl_multi_info_read(multi, &msgs_in_queue)) != NULL) { + if(msg->msg == CURLMSG_DONE) { + long status = 0; + curl_off_t xfer_id; + curl_easy_getinfo(msg->easy_handle, CURLINFO_XFER_ID, &xfer_id); + curl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE, &status); + if(msg->data.result == CURLE_SEND_ERROR || + msg->data.result == CURLE_RECV_ERROR) { + /* We get these if the server had a GOAWAY in transit on + * reusing a connection */ + } + else if(msg->data.result) { + curl_mfprintf(stderr, "transfer #%" CURL_FORMAT_CURL_OFF_T + ": failed with %d\n", xfer_id, msg->data.result); + goto cleanup; + } + else if(status != 206) { + curl_mfprintf(stderr, "transfer #%" CURL_FORMAT_CURL_OFF_T + ": wrong http status %ld (expected 206)\n", xfer_id, + status); + goto cleanup; + } + curl_multi_remove_handle(multi, msg->easy_handle); + curl_easy_cleanup(msg->easy_handle); + curl_mfprintf(stderr, "transfer #%" CURL_FORMAT_CURL_OFF_T" retiring " + "(%d now running)\n", xfer_id, running_handles); + } + } + + curl_mfprintf(stderr, "running_handles=%d, yet_to_start=%d\n", + running_handles, start_count); + + } while(running_handles > 0 || start_count); + + curl_mfprintf(stderr, "exiting\n"); + exitcode = CURLE_OK; + +cleanup: + + if(multi) { + CURL **list = curl_multi_get_handles(multi); + if(list) { + int i; + for(i = 0; list[i]; i++) { + curl_multi_remove_handle(multi, list[i]); + curl_easy_cleanup(list[i]); + } + curl_free(list); + } + curl_multi_cleanup(multi); + } + + return exitcode; +} diff --git a/vendor/curl/tests/libtest/cli_hx_download.c b/vendor/curl/tests/libtest/cli_hx_download.c new file mode 100644 index 00000000000..6394c5e25b2 --- /dev/null +++ b/vendor/curl/tests/libtest/cli_hx_download.c @@ -0,0 +1,553 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "first.h" + +#include "testtrace.h" + +#include "curl_mem_undef.h" + +#if defined(USE_QUICHE) || defined(USE_OPENSSL) +#include +#endif +#ifdef USE_WOLFSSL +#include +#include +#include +#endif +#ifdef USE_GNUTLS +#include +#endif +#ifdef USE_MBEDTLS +#include +#endif +#ifdef USE_RUSTLS +#include +#endif + +#include "memdebug.h" + +static int verbose_d = 1; + +struct transfer_d { + size_t idx; + CURL *easy; + char filename[128]; + FILE *out; + curl_off_t recv_size; + curl_off_t fail_at; + curl_off_t pause_at; + curl_off_t abort_at; + int started; + int paused; + int resumed; + int done; + int checked_ssl; + CURLcode result; +}; + +static size_t transfer_count_d = 1; +static struct transfer_d *transfer_d; +static int forbid_reuse_d = 0; + +static struct transfer_d *get_transfer_for_easy_d(CURL *easy) +{ + size_t i; + for(i = 0; i < transfer_count_d; ++i) { + if(easy == transfer_d[i].easy) + return &transfer_d[i]; + } + return NULL; +} + +static size_t my_write_d_cb(char *buf, size_t nitems, size_t buflen, + void *userdata) +{ + struct transfer_d *t = userdata; + size_t blen = (nitems * buflen); + size_t nwritten; + + curl_mfprintf(stderr, "[t-%zu] RECV %zu bytes, " + "total=%" CURL_FORMAT_CURL_OFF_T ", " + "pause_at=%" CURL_FORMAT_CURL_OFF_T "\n", + t->idx, blen, t->recv_size, t->pause_at); + if(!t->out) { + curl_msnprintf(t->filename, sizeof(t->filename)-1, "download_%zu.data", + t->idx); + t->out = fopen(t->filename, "wb"); + if(!t->out) + return 0; + } + + if(!t->resumed && + t->recv_size < t->pause_at && + ((t->recv_size + (curl_off_t)blen) >= t->pause_at)) { + curl_mfprintf(stderr, "[t-%zu] PAUSE\n", t->idx); + t->paused = 1; + return CURL_WRITEFUNC_PAUSE; + } + + nwritten = fwrite(buf, nitems, buflen, t->out); + if(nwritten < blen) { + curl_mfprintf(stderr, "[t-%zu] write failure\n", t->idx); + return 0; + } + t->recv_size += (curl_off_t)nwritten; + if(t->fail_at > 0 && t->recv_size >= t->fail_at) { + curl_mfprintf(stderr, "[t-%zu] FAIL by write callback at " + "%" CURL_FORMAT_CURL_OFF_T " bytes\n", t->idx, t->recv_size); + return CURL_WRITEFUNC_ERROR; + } + + return (size_t)nwritten; +} + +static int my_progress_d_cb(void *userdata, + curl_off_t dltotal, curl_off_t dlnow, + curl_off_t ultotal, curl_off_t ulnow) +{ + struct transfer_d *t = userdata; + (void)ultotal; + (void)ulnow; + (void)dltotal; + if(t->abort_at > 0 && dlnow >= t->abort_at) { + curl_mfprintf(stderr, "[t-%zu] ABORT by progress_cb at " + "%" CURL_FORMAT_CURL_OFF_T " bytes\n", t->idx, dlnow); + return 1; + } + +#if defined(USE_QUICHE) || defined(USE_OPENSSL) || defined(USE_WOLFSSL) || \ + defined(USE_GNUTLS) || defined(USE_MBEDTLS) || defined(USE_RUSTLS) + if(!t->checked_ssl && dlnow > 0) { + struct curl_tlssessioninfo *tls; + CURLcode res; + + t->checked_ssl = TRUE; + res = curl_easy_getinfo(t->easy, CURLINFO_TLS_SSL_PTR, &tls); + if(res) { + curl_mfprintf(stderr, "[t-%zu] info CURLINFO_TLS_SSL_PTR failed: %d\n", + t->idx, res); + assert(0); + } + else { + switch(tls->backend) { +#if defined(USE_QUICHE) || defined(USE_OPENSSL) + case CURLSSLBACKEND_OPENSSL: { + const char *version = SSL_get_version((SSL*)tls->internals); + assert(version); + assert(strcmp(version, "unknown")); + curl_mfprintf(stderr, "[t-%zu] info OpenSSL using %s\n", + t->idx, version); + break; + } +#endif +#ifdef USE_WOLFSSL + case CURLSSLBACKEND_WOLFSSL: { + const char *version = wolfSSL_get_version((WOLFSSL*)tls->internals); + assert(version); + assert(strcmp(version, "unknown")); + curl_mfprintf(stderr, "[t-%zu] info wolfSSL using %s\n", + t->idx, version); + break; + } +#endif +#ifdef USE_GNUTLS + case CURLSSLBACKEND_GNUTLS: { + int v = gnutls_protocol_get_version((gnutls_session_t)tls->internals); + assert(v); + curl_mfprintf(stderr, "[t-%zu] info GnuTLS using %s\n", + t->idx, gnutls_protocol_get_name(v)); + break; + } +#endif +#ifdef USE_MBEDTLS + case CURLSSLBACKEND_MBEDTLS: { + const char *version = mbedtls_ssl_get_version( + (mbedtls_ssl_context*)tls->internals); + assert(version); + assert(strcmp(version, "unknown")); + curl_mfprintf(stderr, "[t-%zu] info mbedTLS using %s\n", + t->idx, version); + break; + } +#endif +#ifdef USE_RUSTLS + case CURLSSLBACKEND_RUSTLS: { + int v = rustls_connection_get_protocol_version( + (struct rustls_connection*)tls->internals); + assert(v); + curl_mfprintf(stderr, "[t-%zu] info rustls TLS version 0x%x\n", + t->idx, v); + break; + } +#endif + default: + curl_mfprintf(stderr, "[t-%zu] info SSL_PTR backend=%d, ptr=%p\n", + t->idx, tls->backend, (void *)tls->internals); + break; + } + } + } +#endif + return 0; +} + +static int setup_hx_download(CURL *hnd, const char *url, struct transfer_d *t, + long http_version, struct curl_slist *host, + CURLSH *share, int use_earlydata, + int fresh_connect) +{ + curl_easy_setopt(hnd, CURLOPT_SHARE, share); + curl_easy_setopt(hnd, CURLOPT_URL, url); + curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, http_version); + curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(hnd, CURLOPT_ACCEPT_ENCODING, ""); + curl_easy_setopt(hnd, CURLOPT_BUFFERSIZE, (long)(128 * 1024)); + curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, my_write_d_cb); + curl_easy_setopt(hnd, CURLOPT_WRITEDATA, t); + curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 0L); + curl_easy_setopt(hnd, CURLOPT_XFERINFOFUNCTION, my_progress_d_cb); + curl_easy_setopt(hnd, CURLOPT_XFERINFODATA, t); + if(use_earlydata) + curl_easy_setopt(hnd, CURLOPT_SSL_OPTIONS, CURLSSLOPT_EARLYDATA); + if(forbid_reuse_d) + curl_easy_setopt(hnd, CURLOPT_FORBID_REUSE, 1L); + if(host) + curl_easy_setopt(hnd, CURLOPT_RESOLVE, host); + if(fresh_connect) + curl_easy_setopt(hnd, CURLOPT_FRESH_CONNECT, 1L); + + /* please be verbose */ + if(verbose_d) { + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(hnd, CURLOPT_DEBUGFUNCTION, cli_debug_cb); + } + + /* wait for pipe connection to confirm */ + curl_easy_setopt(hnd, CURLOPT_PIPEWAIT, 1L); + + return 0; /* all is good */ +} + +static void usage_hx_download(const char *msg) +{ + if(msg) + curl_mfprintf(stderr, "%s\n", msg); + curl_mfprintf(stderr, + "usage: [options] url\n" + " download a url with following options:\n" + " -a abort paused transfer\n" + " -m number max parallel downloads\n" + " -e use TLS early data when possible\n" + " -f forbid connection reuse\n" + " -n number total downloads\n"); + curl_mfprintf(stderr, + " -A number abort transfer after `number` response bytes\n" + " -F number fail writing response after `number` response bytes\n" + " -M number max concurrent connections to a host\n" + " -P number pause transfer after `number` response bytes\n" + " -r :: resolve information\n" + " -T number max concurrent connections total\n" + " -V http_version (http/1.1, h2, h3) http version to use\n" + ); +} + +/* + * Download a file over HTTP/2, take care of server push. + */ +static CURLcode test_cli_hx_download(const char *URL) +{ + CURLM *multi_handle; + struct CURLMsg *m; + CURLSH *share; + const char *url; + size_t i, n, max_parallel = 1; + size_t active_transfers; + size_t pause_offset = 0; + size_t abort_offset = 0; + size_t fail_offset = 0; + int abort_paused = 0, use_earlydata = 0; + struct transfer_d *t; + long http_version = CURL_HTTP_VERSION_2_0; + int ch; + struct curl_slist *host = NULL; + char *resolve = NULL; + size_t max_host_conns = 0; + size_t max_total_conns = 0; + int fresh_connect = 0; + CURLcode result = CURLE_OK; + + (void)URL; + + while((ch = cgetopt(test_argc, test_argv, "aefhm:n:xA:F:M:P:r:T:V:")) + != -1) { + switch(ch) { + case 'h': + usage_hx_download(NULL); + result = (CURLcode)2; + goto cleanup; + case 'a': + abort_paused = 1; + break; + case 'e': + use_earlydata = 1; + break; + case 'f': + forbid_reuse_d = 1; + break; + case 'm': + max_parallel = (size_t)strtol(coptarg, NULL, 10); + break; + case 'n': + transfer_count_d = (size_t)strtol(coptarg, NULL, 10); + break; + case 'x': + fresh_connect = 1; + break; + case 'A': + abort_offset = (size_t)strtol(coptarg, NULL, 10); + break; + case 'F': + fail_offset = (size_t)strtol(coptarg, NULL, 10); + break; + case 'M': + max_host_conns = (size_t)strtol(coptarg, NULL, 10); + break; + case 'P': + pause_offset = (size_t)strtol(coptarg, NULL, 10); + break; + case 'r': + free(resolve); + resolve = strdup(coptarg); + break; + case 'T': + max_total_conns = (size_t)strtol(coptarg, NULL, 10); + break; + case 'V': { + if(!strcmp("http/1.1", coptarg)) + http_version = CURL_HTTP_VERSION_1_1; + else if(!strcmp("h2", coptarg)) + http_version = CURL_HTTP_VERSION_2_0; + else if(!strcmp("h3", coptarg)) + http_version = CURL_HTTP_VERSION_3ONLY; + else { + usage_hx_download("invalid http version"); + result = (CURLcode)1; + goto cleanup; + } + break; + } + default: + usage_hx_download("invalid option"); + result = (CURLcode)1; + goto cleanup; + } + } + test_argc -= coptind; + test_argv += coptind; + + curl_global_init(CURL_GLOBAL_DEFAULT); + curl_global_trace("ids,time,http/2,http/3"); + + if(test_argc != 1) { + usage_hx_download("not enough arguments"); + result = (CURLcode)2; + goto cleanup; + } + url = test_argv[0]; + + if(resolve) + host = curl_slist_append(NULL, resolve); + + share = curl_share_init(); + if(!share) { + curl_mfprintf(stderr, "error allocating share\n"); + result = (CURLcode)1; + goto cleanup; + } + curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE); + curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS); + curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION); + /* curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); */ + curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_PSL); + curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_HSTS); + + transfer_d = calloc(transfer_count_d, sizeof(*transfer_d)); + if(!transfer_d) { + curl_mfprintf(stderr, "error allocating transfer structs\n"); + result = (CURLcode)1; + goto cleanup; + } + + multi_handle = curl_multi_init(); + curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX); + curl_multi_setopt(multi_handle, CURLMOPT_MAX_TOTAL_CONNECTIONS, + (long)max_total_conns); + curl_multi_setopt(multi_handle, CURLMOPT_MAX_HOST_CONNECTIONS, + (long)max_host_conns); + + active_transfers = 0; + for(i = 0; i < transfer_count_d; ++i) { + t = &transfer_d[i]; + t->idx = i; + t->abort_at = (curl_off_t)abort_offset; + t->fail_at = (curl_off_t)fail_offset; + t->pause_at = (curl_off_t)pause_offset; + } + + n = (max_parallel < transfer_count_d) ? max_parallel : transfer_count_d; + for(i = 0; i < n; ++i) { + t = &transfer_d[i]; + t->easy = curl_easy_init(); + if(!t->easy || + setup_hx_download(t->easy, url, t, http_version, host, share, + use_earlydata, fresh_connect)) { + curl_mfprintf(stderr, "[t-%zu] FAILED setup\n", i); + result = (CURLcode)1; + goto cleanup; + } + curl_multi_add_handle(multi_handle, t->easy); + t->started = 1; + ++active_transfers; + curl_mfprintf(stderr, "[t-%zu] STARTED\n", t->idx); + } + + do { + int still_running; /* keep number of running handles */ + CURLMcode mc = curl_multi_perform(multi_handle, &still_running); + + if(still_running) { + /* wait for activity, timeout or "nothing" */ + mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL); + } + + if(mc) + break; + + do { + int msgq = 0; + m = curl_multi_info_read(multi_handle, &msgq); + if(m && (m->msg == CURLMSG_DONE)) { + CURL *e = m->easy_handle; + --active_transfers; + curl_multi_remove_handle(multi_handle, e); + t = get_transfer_for_easy_d(e); + if(t) { + t->done = 1; + t->result = m->data.result; + curl_mfprintf(stderr, "[t-%zu] FINISHED with result %d\n", + t->idx, t->result); + if(use_earlydata) { + curl_off_t sent; + curl_easy_getinfo(e, CURLINFO_EARLYDATA_SENT_T, &sent); + curl_mfprintf(stderr, "[t-%zu] EarlyData: " + "%" CURL_FORMAT_CURL_OFF_T "\n", t->idx, sent); + } + } + else { + curl_easy_cleanup(e); + curl_mfprintf(stderr, "unknown FINISHED???\n"); + } + } + + /* nothing happening, maintenance */ + if(abort_paused) { + /* abort paused transfers */ + for(i = 0; i < transfer_count_d; ++i) { + t = &transfer_d[i]; + if(!t->done && t->paused && t->easy) { + curl_multi_remove_handle(multi_handle, t->easy); + t->done = 1; + active_transfers--; + curl_mfprintf(stderr, "[t-%zu] ABORTED\n", t->idx); + } + } + } + else { + /* resume one paused transfer */ + for(i = 0; i < transfer_count_d; ++i) { + t = &transfer_d[i]; + if(!t->done && t->paused) { + t->resumed = 1; + t->paused = 0; + curl_easy_pause(t->easy, CURLPAUSE_CONT); + curl_mfprintf(stderr, "[t-%zu] RESUMED\n", t->idx); + break; + } + } + } + + while(active_transfers < max_parallel) { + for(i = 0; i < transfer_count_d; ++i) { + t = &transfer_d[i]; + if(!t->started) { + t->easy = curl_easy_init(); + if(!t->easy || + setup_hx_download(t->easy, url, t, http_version, host, share, + use_earlydata, fresh_connect)) { + curl_mfprintf(stderr, "[t-%zu] FAILED setup\n", i); + result = (CURLcode)1; + goto cleanup; + } + curl_multi_add_handle(multi_handle, t->easy); + t->started = 1; + ++active_transfers; + curl_mfprintf(stderr, "[t-%zu] STARTED\n", t->idx); + break; + } + } + /* all started */ + if(i == transfer_count_d) + break; + } + } while(m); + + } while(active_transfers); /* as long as we have transfers going */ + + curl_multi_cleanup(multi_handle); + + for(i = 0; i < transfer_count_d; ++i) { + t = &transfer_d[i]; + if(t->out) { + fclose(t->out); + t->out = NULL; + } + if(t->easy) { + curl_easy_cleanup(t->easy); + t->easy = NULL; + } + if(t->result) + result = t->result; + else /* on success we expect ssl to have been checked */ + assert(t->checked_ssl); + } + free(transfer_d); + + curl_share_cleanup(share); + curl_slist_free_all(host); +cleanup: + free(resolve); + + return result; +} diff --git a/vendor/curl/tests/libtest/cli_hx_upload.c b/vendor/curl/tests/libtest/cli_hx_upload.c new file mode 100644 index 00000000000..9c69e36787f --- /dev/null +++ b/vendor/curl/tests/libtest/cli_hx_upload.c @@ -0,0 +1,509 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "first.h" + +#include "testtrace.h" +#include "memdebug.h" + +static int verbose_u = 1; + +struct transfer_u { + size_t idx; + CURL *easy; + const char *method; + char filename[128]; + FILE *out; + curl_off_t send_total; + curl_off_t recv_size; + curl_off_t send_size; + curl_off_t fail_at; + curl_off_t pause_at; + curl_off_t abort_at; + int started; + int paused; + int resumed; + int done; +}; + +static size_t transfer_count_u = 1; +static struct transfer_u *transfer_u; +static int forbid_reuse_u = 0; + +static struct transfer_u *get_transfer_for_easy_u(CURL *easy) +{ + size_t i; + for(i = 0; i < transfer_count_u; ++i) { + if(easy == transfer_u[i].easy) + return &transfer_u[i]; + } + return NULL; +} + +static size_t my_write_u_cb(char *buf, size_t nitems, size_t buflen, + void *userdata) +{ + struct transfer_u *t = userdata; + size_t blen = (nitems * buflen); + size_t nwritten; + + curl_mfprintf(stderr, "[t-%zu] RECV %zu bytes, " + "total=%" CURL_FORMAT_CURL_OFF_T ", " + "pause_at=%" CURL_FORMAT_CURL_OFF_T "\n", + t->idx, blen, t->recv_size, t->pause_at); + if(!t->out) { + curl_msnprintf(t->filename, sizeof(t->filename)-1, "download_%zu.data", + t->idx); + t->out = fopen(t->filename, "wb"); + if(!t->out) + return 0; + } + + nwritten = fwrite(buf, nitems, buflen, t->out); + if(nwritten < blen) { + curl_mfprintf(stderr, "[t-%zu] write failure\n", t->idx); + return 0; + } + t->recv_size += (curl_off_t)nwritten; + return (size_t)nwritten; +} + +static size_t my_read_cb(char *buf, size_t nitems, size_t buflen, + void *userdata) +{ + struct transfer_u *t = userdata; + size_t blen = (nitems * buflen); + size_t nread; + + if(t->send_total <= t->send_size) + nread = 0; + else if((t->send_total - t->send_size) < (curl_off_t)blen) + nread = (size_t)(t->send_total - t->send_size); + else + nread = blen; + + curl_mfprintf(stderr, "[t-%zu] SEND %zu bytes, " + "total=%" CURL_FORMAT_CURL_OFF_T ", " + "pause_at=%" CURL_FORMAT_CURL_OFF_T "\n", + t->idx, nread, t->send_total, t->pause_at); + + if(!t->resumed && + t->send_size < t->pause_at && + ((t->send_size + (curl_off_t)blen) >= t->pause_at)) { + curl_mfprintf(stderr, "[t-%zu] PAUSE\n", t->idx); + t->paused = 1; + return CURL_READFUNC_PAUSE; + } + + memset(buf, 'x', nread); + t->send_size += (curl_off_t)nread; + if(t->fail_at > 0 && t->send_size >= t->fail_at) { + curl_mfprintf(stderr, "[t-%zu] ABORT by read callback at " + "%" CURL_FORMAT_CURL_OFF_T " bytes\n", t->idx, t->send_size); + return CURL_READFUNC_ABORT; + } + return (size_t)nread; +} + +static int my_progress_u_cb(void *userdata, + curl_off_t dltotal, curl_off_t dlnow, + curl_off_t ultotal, curl_off_t ulnow) +{ + struct transfer_u *t = userdata; + (void)ultotal; + (void)dlnow; + (void)dltotal; + if(t->abort_at > 0 && ulnow >= t->abort_at) { + curl_mfprintf(stderr, "[t-%zu] ABORT by progress_cb at " + "%" CURL_FORMAT_CURL_OFF_T " bytes sent\n", t->idx, ulnow); + return 1; + } + return 0; +} + +static int setup_hx_upload(CURL *hnd, const char *url, struct transfer_u *t, + long http_version, struct curl_slist *host, + CURLSH *share, int use_earlydata, + int announce_length) +{ + curl_easy_setopt(hnd, CURLOPT_SHARE, share); + curl_easy_setopt(hnd, CURLOPT_URL, url); + curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, http_version); + curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(hnd, CURLOPT_BUFFERSIZE, (long)(128 * 1024)); + curl_easy_setopt(hnd, CURLOPT_FOLLOWLOCATION, CURLFOLLOW_OBEYCODE); + curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, my_write_u_cb); + curl_easy_setopt(hnd, CURLOPT_WRITEDATA, t); + if(use_earlydata) + curl_easy_setopt(hnd, CURLOPT_SSL_OPTIONS, CURLSSLOPT_EARLYDATA); + + if(!t->method || !strcmp("PUT", t->method)) + curl_easy_setopt(hnd, CURLOPT_UPLOAD, 1L); + else if(!strcmp("POST", t->method)) + curl_easy_setopt(hnd, CURLOPT_POST, 1L); + else { + curl_mfprintf(stderr, "unsupported method '%s'\n", t->method); + return 1; + } + curl_easy_setopt(hnd, CURLOPT_READFUNCTION, my_read_cb); + curl_easy_setopt(hnd, CURLOPT_READDATA, t); + if(announce_length) + curl_easy_setopt(hnd, CURLOPT_INFILESIZE_LARGE, t->send_total); + + curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 0L); + curl_easy_setopt(hnd, CURLOPT_XFERINFOFUNCTION, my_progress_u_cb); + curl_easy_setopt(hnd, CURLOPT_XFERINFODATA, t); + if(forbid_reuse_u) + curl_easy_setopt(hnd, CURLOPT_FORBID_REUSE, 1L); + if(host) + curl_easy_setopt(hnd, CURLOPT_RESOLVE, host); + + /* please be verbose */ + if(verbose_u) { + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(hnd, CURLOPT_DEBUGFUNCTION, cli_debug_cb); + } + + /* wait for pipe connection to confirm */ + curl_easy_setopt(hnd, CURLOPT_PIPEWAIT, 1L); + + return 0; /* all is good */ +} + +static void usage_hx_upload(const char *msg) +{ + if(msg) + curl_mfprintf(stderr, "%s\n", msg); + curl_mfprintf(stderr, + "usage: [options] url\n" + " upload to a url with following options:\n" + " -a abort paused transfer\n" + " -e use TLS earlydata\n" + " -m number max parallel uploads\n" + " -n number total uploads\n" + " -A number abort transfer after `number` request body bytes\n" + " -F number fail reading request body after `number` of bytes\n" + " -P number pause transfer after `number` request body bytes\n" + " -r :: resolve information\n" + " -S number size to upload\n" + " -V http_version (http/1.1, h2, h3) http version to use\n" + ); +} + +/* + * Download a file over HTTP/2, take care of server push. + */ +static CURLcode test_cli_hx_upload(const char *URL) +{ + CURLM *multi_handle; + CURLSH *share; + const char *url; + const char *method = "PUT"; + size_t i, n, max_parallel = 1; + size_t active_transfers; + size_t pause_offset = 0; + size_t abort_offset = 0; + size_t fail_offset = 0; + size_t send_total = (128 * 1024); + int abort_paused = 0; + int reuse_easy = 0; + int use_earlydata = 0; + int announce_length = 0; + struct transfer_u *t; + long http_version = CURL_HTTP_VERSION_2_0; + struct curl_slist *host = NULL; + const char *resolve = NULL; + int ch; + + (void)URL; + + while((ch = cgetopt(test_argc, test_argv, "aefhlm:n:A:F:M:P:r:RS:V:")) + != -1) { + switch(ch) { + case 'h': + usage_hx_upload(NULL); + return (CURLcode)2; + case 'a': + abort_paused = 1; + break; + case 'e': + use_earlydata = 1; + break; + case 'f': + forbid_reuse_u = 1; + break; + case 'l': + announce_length = 1; + break; + case 'm': + max_parallel = (size_t)strtol(coptarg, NULL, 10); + break; + case 'n': + transfer_count_u = (size_t)strtol(coptarg, NULL, 10); + break; + case 'A': + abort_offset = (size_t)strtol(coptarg, NULL, 10); + break; + case 'F': + fail_offset = (size_t)strtol(coptarg, NULL, 10); + break; + case 'M': + method = coptarg; + break; + case 'P': + pause_offset = (size_t)strtol(coptarg, NULL, 10); + break; + case 'r': + resolve = coptarg; + break; + case 'R': + reuse_easy = 1; + break; + case 'S': + send_total = (size_t)strtol(coptarg, NULL, 10); + break; + case 'V': { + if(!strcmp("http/1.1", coptarg)) + http_version = CURL_HTTP_VERSION_1_1; + else if(!strcmp("h2", coptarg)) + http_version = CURL_HTTP_VERSION_2_0; + else if(!strcmp("h3", coptarg)) + http_version = CURL_HTTP_VERSION_3ONLY; + else { + usage_hx_upload("invalid http version"); + return (CURLcode)1; + } + break; + } + default: + usage_hx_upload("invalid option"); + return (CURLcode)1; + } + } + test_argc -= coptind; + test_argv += coptind; + + if(max_parallel > 1 && reuse_easy) { + usage_hx_upload("cannot mix -R and -P"); + return (CURLcode)2; + } + + curl_global_init(CURL_GLOBAL_DEFAULT); + curl_global_trace("ids,time,http/2,http/3"); + + if(test_argc != 1) { + usage_hx_upload("not enough arguments"); + return (CURLcode)2; + } + url = test_argv[0]; + + if(resolve) + host = curl_slist_append(NULL, resolve); + + share = curl_share_init(); + if(!share) { + curl_mfprintf(stderr, "error allocating share\n"); + return (CURLcode)1; + } + curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE); + curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS); + curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION); + curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); + curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_PSL); + curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_HSTS); + + transfer_u = calloc(transfer_count_u, sizeof(*transfer_u)); + if(!transfer_u) { + curl_mfprintf(stderr, "error allocating transfer structs\n"); + return (CURLcode)1; + } + + active_transfers = 0; + for(i = 0; i < transfer_count_u; ++i) { + t = &transfer_u[i]; + t->idx = i; + t->method = method; + t->send_total = (curl_off_t)send_total; + t->abort_at = (curl_off_t)abort_offset; + t->fail_at = (curl_off_t)fail_offset; + t->pause_at = (curl_off_t)pause_offset; + } + + if(reuse_easy) { + CURL *easy = curl_easy_init(); + CURLcode rc = CURLE_OK; + if(!easy) { + curl_mfprintf(stderr, "failed to init easy handle\n"); + return (CURLcode)1; + } + for(i = 0; i < transfer_count_u; ++i) { + t = &transfer_u[i]; + t->easy = easy; + if(setup_hx_upload(t->easy, url, t, http_version, host, share, + use_earlydata, announce_length)) { + curl_mfprintf(stderr, "[t-%zu] FAILED setup\n", i); + return (CURLcode)1; + } + + curl_mfprintf(stderr, "[t-%zu] STARTING\n", t->idx); + rc = curl_easy_perform(easy); + curl_mfprintf(stderr, "[t-%zu] DONE -> %d\n", t->idx, rc); + t->easy = NULL; + curl_easy_reset(easy); + } + curl_easy_cleanup(easy); + } + else { + multi_handle = curl_multi_init(); + curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX); + + n = (max_parallel < transfer_count_u) ? max_parallel : transfer_count_u; + for(i = 0; i < n; ++i) { + t = &transfer_u[i]; + t->easy = curl_easy_init(); + if(!t->easy || setup_hx_upload(t->easy, url, t, http_version, host, + share, use_earlydata, announce_length)) { + curl_mfprintf(stderr, "[t-%zu] FAILED setup\n", i); + return (CURLcode)1; + } + curl_multi_add_handle(multi_handle, t->easy); + t->started = 1; + ++active_transfers; + curl_mfprintf(stderr, "[t-%zu] STARTED\n", t->idx); + } + + do { + int still_running; /* keep number of running handles */ + CURLMcode mc = curl_multi_perform(multi_handle, &still_running); + struct CURLMsg *m; + + if(still_running) { + /* wait for activity, timeout or "nothing" */ + mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL); + } + + if(mc) + break; + + do { + int msgq = 0; + m = curl_multi_info_read(multi_handle, &msgq); + if(m && (m->msg == CURLMSG_DONE)) { + CURL *e = m->easy_handle; + --active_transfers; + curl_multi_remove_handle(multi_handle, e); + t = get_transfer_for_easy_u(e); + if(t) { + long res_status; + curl_easy_getinfo(e, CURLINFO_RESPONSE_CODE, &res_status); + t->done = 1; + curl_mfprintf(stderr, "[t-%zu] FINISHED, " + "result=%d, response=%ld\n", + t->idx, m->data.result, res_status); + if(use_earlydata) { + curl_off_t sent; + curl_easy_getinfo(e, CURLINFO_EARLYDATA_SENT_T, &sent); + curl_mfprintf(stderr, "[t-%zu] EarlyData: " + "%" CURL_FORMAT_CURL_OFF_T "\n", t->idx, sent); + } + } + else { + curl_easy_cleanup(e); + curl_mfprintf(stderr, "unknown FINISHED???\n"); + } + } + + + /* nothing happening, maintenance */ + if(abort_paused) { + /* abort paused transfers */ + for(i = 0; i < transfer_count_u; ++i) { + t = &transfer_u[i]; + if(!t->done && t->paused && t->easy) { + curl_multi_remove_handle(multi_handle, t->easy); + t->done = 1; + active_transfers--; + curl_mfprintf(stderr, "[t-%zu] ABORTED\n", t->idx); + } + } + } + else { + /* resume one paused transfer */ + for(i = 0; i < transfer_count_u; ++i) { + t = &transfer_u[i]; + if(!t->done && t->paused) { + t->resumed = 1; + t->paused = 0; + curl_easy_pause(t->easy, CURLPAUSE_CONT); + curl_mfprintf(stderr, "[t-%zu] RESUMED\n", t->idx); + break; + } + } + } + + while(active_transfers < max_parallel) { + for(i = 0; i < transfer_count_u; ++i) { + t = &transfer_u[i]; + if(!t->started) { + t->easy = curl_easy_init(); + if(!t->easy || setup_hx_upload(t->easy, url, t, http_version, + host, share, use_earlydata, + announce_length)) { + curl_mfprintf(stderr, "[t-%zu] FAILED setup\n", i); + return (CURLcode)1; + } + curl_multi_add_handle(multi_handle, t->easy); + t->started = 1; + ++active_transfers; + curl_mfprintf(stderr, "[t-%zu] STARTED\n", t->idx); + break; + } + } + /* all started */ + if(i == transfer_count_u) + break; + } + } while(m); + + } while(active_transfers); /* as long as we have transfers going */ + + curl_multi_cleanup(multi_handle); + } + + for(i = 0; i < transfer_count_u; ++i) { + t = &transfer_u[i]; + if(t->out) { + fclose(t->out); + t->out = NULL; + } + if(t->easy) { + curl_easy_cleanup(t->easy); + t->easy = NULL; + } + } + free(transfer_u); + curl_share_cleanup(share); + + return CURLE_OK; +} diff --git a/vendor/curl/tests/libtest/cli_tls_session_reuse.c b/vendor/curl/tests/libtest/cli_tls_session_reuse.c new file mode 100644 index 00000000000..b0b2456ce9d --- /dev/null +++ b/vendor/curl/tests/libtest/cli_tls_session_reuse.c @@ -0,0 +1,261 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "first.h" + +#include "testtrace.h" +#include "memdebug.h" + +static int tse_found_tls_session = FALSE; + +static size_t write_tse_cb(char *ptr, size_t size, size_t nmemb, void *opaque) +{ + CURL *easy = opaque; + (void)ptr; + if(!tse_found_tls_session) { + struct curl_tlssessioninfo *tlssession; + CURLcode rc; + + rc = curl_easy_getinfo(easy, CURLINFO_TLS_SSL_PTR, &tlssession); + if(rc) { + curl_mfprintf(stderr, "curl_easy_getinfo(CURLINFO_TLS_SSL_PTR) " + "failed: %s\n", curl_easy_strerror(rc)); + return rc; + } + if(tlssession->backend == CURLSSLBACKEND_NONE) { + curl_mfprintf(stderr, "curl_easy_getinfo(CURLINFO_TLS_SSL_PTR) " + "gave no backend\n"); + return CURLE_FAILED_INIT; + } + if(!tlssession->internals) { + curl_mfprintf(stderr, "curl_easy_getinfo(CURLINFO_TLS_SSL_PTR) " + "missing\n"); + return CURLE_FAILED_INIT; + } + tse_found_tls_session = TRUE; + } + return size * nmemb; +} + +static CURL *tse_add_transfer(CURLM *multi, CURLSH *share, + struct curl_slist *resolve, + const char *url, long http_version) +{ + CURL *easy; + CURLMcode mc; + + easy = curl_easy_init(); + if(!easy) { + curl_mfprintf(stderr, "curl_easy_init failed\n"); + return NULL; + } + curl_easy_setopt(easy, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(easy, CURLOPT_DEBUGFUNCTION, cli_debug_cb); + curl_easy_setopt(easy, CURLOPT_URL, url); + curl_easy_setopt(easy, CURLOPT_SHARE, share); + curl_easy_setopt(easy, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt(easy, CURLOPT_AUTOREFERER, 1L); + curl_easy_setopt(easy, CURLOPT_FAILONERROR, 1L); + curl_easy_setopt(easy, CURLOPT_HTTP_VERSION, http_version); + curl_easy_setopt(easy, CURLOPT_WRITEFUNCTION, write_tse_cb); + curl_easy_setopt(easy, CURLOPT_WRITEDATA, easy); + curl_easy_setopt(easy, CURLOPT_HTTPGET, 1L); + curl_easy_setopt(easy, CURLOPT_SSL_VERIFYPEER, 0L); + if(resolve) + curl_easy_setopt(easy, CURLOPT_RESOLVE, resolve); + + + mc = curl_multi_add_handle(multi, easy); + if(mc != CURLM_OK) { + curl_mfprintf(stderr, "curl_multi_add_handle: %s\n", + curl_multi_strerror(mc)); + curl_easy_cleanup(easy); + return NULL; + } + return easy; +} + +static CURLcode test_cli_tls_session_reuse(const char *URL) +{ + CURLM *multi = NULL; + CURLMcode mc; + int running_handles = 0, numfds; + CURLMsg *msg; + CURLSH *share = NULL; + CURLU *cu; + struct curl_slist *resolve = NULL; + char resolve_buf[1024]; + int msgs_in_queue; + int add_more, waits, ongoing = 0; + char *host = NULL, *port = NULL; + long http_version = CURL_HTTP_VERSION_1_1; + CURLcode exitcode = (CURLcode)1; + + if(!URL || !libtest_arg2) { + curl_mfprintf(stderr, "need args: URL proto\n"); + return (CURLcode)2; + } + + if(!strcmp("h2", libtest_arg2)) + http_version = CURL_HTTP_VERSION_2; + else if(!strcmp("h3", libtest_arg2)) + http_version = CURL_HTTP_VERSION_3ONLY; + + cu = curl_url(); + if(!cu) { + curl_mfprintf(stderr, "out of memory\n"); + return (CURLcode)1; + } + if(curl_url_set(cu, CURLUPART_URL, URL, 0)) { + curl_mfprintf(stderr, "not a URL: '%s'\n", URL); + goto cleanup; + } + if(curl_url_get(cu, CURLUPART_HOST, &host, 0)) { + curl_mfprintf(stderr, "could not get host of '%s'\n", URL); + goto cleanup; + } + if(curl_url_get(cu, CURLUPART_PORT, &port, 0)) { + curl_mfprintf(stderr, "could not get port of '%s'\n", URL); + goto cleanup; + } + + curl_msnprintf(resolve_buf, sizeof(resolve_buf)-1, "%s:%s:127.0.0.1", + host, port); + resolve = curl_slist_append(resolve, resolve_buf); + + multi = curl_multi_init(); + if(!multi) { + curl_mfprintf(stderr, "curl_multi_init failed\n"); + goto cleanup; + } + + share = curl_share_init(); + if(!share) { + curl_mfprintf(stderr, "curl_share_init failed\n"); + goto cleanup; + } + curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION); + + + if(!tse_add_transfer(multi, share, resolve, URL, http_version)) + goto cleanup; + ++ongoing; + add_more = 6; + waits = 3; + do { + mc = curl_multi_perform(multi, &running_handles); + if(mc != CURLM_OK) { + curl_mfprintf(stderr, "curl_multi_perform: %s\n", + curl_multi_strerror(mc)); + goto cleanup; + } + + if(running_handles) { + mc = curl_multi_poll(multi, NULL, 0, 1000000, &numfds); + if(mc != CURLM_OK) { + curl_mfprintf(stderr, "curl_multi_poll: %s\n", + curl_multi_strerror(mc)); + goto cleanup; + } + } + + if(waits) { + --waits; + } + else { + while(add_more) { + if(!tse_add_transfer(multi, share, resolve, URL, http_version)) + goto cleanup; + ++ongoing; + --add_more; + } + } + + /* Check for finished handles and remove. */ + /* !checksrc! disable EQUALSNULL 1 */ + while((msg = curl_multi_info_read(multi, &msgs_in_queue)) != NULL) { + if(msg->msg == CURLMSG_DONE) { + long status = 0; + curl_off_t xfer_id; + curl_easy_getinfo(msg->easy_handle, CURLINFO_XFER_ID, &xfer_id); + curl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE, &status); + if(msg->data.result == CURLE_SEND_ERROR || + msg->data.result == CURLE_RECV_ERROR) { + /* We get these if the server had a GOAWAY in transit on + * reusing a connection */ + } + else if(msg->data.result) { + curl_mfprintf(stderr, "transfer #%" CURL_FORMAT_CURL_OFF_T + ": failed with %d\n", xfer_id, msg->data.result); + goto cleanup; + } + else if(status != 200) { + curl_mfprintf(stderr, "transfer #%" CURL_FORMAT_CURL_OFF_T + ": wrong http status %ld (expected 200)\n", xfer_id, + status); + goto cleanup; + } + curl_multi_remove_handle(multi, msg->easy_handle); + curl_easy_cleanup(msg->easy_handle); + --ongoing; + curl_mfprintf(stderr, "transfer #%" CURL_FORMAT_CURL_OFF_T" retiring " + "(%d now running)\n", xfer_id, running_handles); + } + } + + curl_mfprintf(stderr, "running_handles=%d, yet_to_start=%d\n", + running_handles, add_more); + + } while(ongoing || add_more); + + if(!tse_found_tls_session) { + curl_mfprintf(stderr, "CURLINFO_TLS_SSL_PTR not found during run\n"); + exitcode = CURLE_FAILED_INIT; + goto cleanup; + } + + curl_mfprintf(stderr, "exiting\n"); + exitcode = CURLE_OK; + +cleanup: + + if(multi) { + CURL **list = curl_multi_get_handles(multi); + if(list) { + int i; + for(i = 0; list[i]; i++) { + curl_multi_remove_handle(multi, list[i]); + curl_easy_cleanup(list[i]); + } + curl_free(list); + } + curl_multi_cleanup(multi); + } + curl_share_cleanup(share); + curl_slist_free_all(resolve); + curl_free(host); + curl_free(port); + curl_url_cleanup(cu); + + return exitcode; +} diff --git a/vendor/curl/tests/libtest/cli_upload_pausing.c b/vendor/curl/tests/libtest/cli_upload_pausing.c new file mode 100644 index 00000000000..a6a74eeaded --- /dev/null +++ b/vendor/curl/tests/libtest/cli_upload_pausing.c @@ -0,0 +1,203 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 based on the PoC client of issue #11769 + */ +#include "first.h" + +#include "testtrace.h" +#include "memdebug.h" + +static size_t total_read = 0; + +static size_t read_callback(char *ptr, size_t size, size_t nmemb, + void *userdata) +{ + static const size_t PAUSE_READ_AFTER = 1; + + (void)size; + (void)nmemb; + (void)userdata; + if(total_read >= PAUSE_READ_AFTER) { + curl_mfprintf(stderr, "read_callback, return PAUSE\n"); + return CURL_READFUNC_PAUSE; + } + else { + ptr[0] = '\n'; + ++total_read; + curl_mfprintf(stderr, "read_callback, return 1 byte\n"); + return 1; + } +} + +static int progress_callback(void *clientp, + curl_off_t dltotal, + curl_off_t dlnow, + curl_off_t ultotal, + curl_off_t ulnow) +{ + (void)dltotal; + (void)dlnow; + (void)ultotal; + (void)ulnow; + (void)clientp; +#if 0 + /* Used to unpause on progress, but keeping for now. */ + { + CURL *curl = (CURL *)clientp; + curl_easy_pause(curl, CURLPAUSE_CONT); + /* curl_easy_pause(curl, CURLPAUSE_RECV_CONT); */ + } +#endif + return 0; +} + +static void usage_upload_pausing(const char *msg) +{ + if(msg) + curl_mfprintf(stderr, "%s\n", msg); + curl_mfprintf(stderr, + "usage: [options] url\n" + " upload and pause, options:\n" + " -V http_version (http/1.1, h2, h3) http version to use\n" + ); +} + +static CURLcode test_cli_upload_pausing(const char *URL) +{ + CURL *curl; + CURLcode rc = CURLE_OK; + CURLU *cu; + struct curl_slist *resolve = NULL; + char resolve_buf[1024]; + const char *url; + char *host = NULL, *port = NULL; + long http_version = CURL_HTTP_VERSION_1_1; + int ch; + + (void)URL; + + while((ch = cgetopt(test_argc, test_argv, "V:")) != -1) { + switch(ch) { + case 'V': { + if(!strcmp("http/1.1", coptarg)) + http_version = CURL_HTTP_VERSION_1_1; + else if(!strcmp("h2", coptarg)) + http_version = CURL_HTTP_VERSION_2_0; + else if(!strcmp("h3", coptarg)) + http_version = CURL_HTTP_VERSION_3ONLY; + else { + usage_upload_pausing("invalid http version"); + return (CURLcode)1; + } + break; + } + default: + usage_upload_pausing("invalid option"); + return (CURLcode)1; + } + } + test_argc -= coptind; + test_argv += coptind; + + if(test_argc != 1) { + usage_upload_pausing("not enough arguments"); + return (CURLcode)2; + } + url = test_argv[0]; + + curl_global_init(CURL_GLOBAL_DEFAULT); + curl_global_trace("ids,time"); + + cu = curl_url(); + if(!cu) { + curl_mfprintf(stderr, "out of memory\n"); + return (CURLcode)1; + } + if(curl_url_set(cu, CURLUPART_URL, url, 0)) { + curl_mfprintf(stderr, "not a URL: '%s'\n", url); + return (CURLcode)1; + } + if(curl_url_get(cu, CURLUPART_HOST, &host, 0)) { + curl_mfprintf(stderr, "could not get host of '%s'\n", url); + return (CURLcode)1; + } + if(curl_url_get(cu, CURLUPART_PORT, &port, 0)) { + curl_mfprintf(stderr, "could not get port of '%s'\n", url); + return (CURLcode)1; + } + memset(&resolve, 0, sizeof(resolve)); + curl_msnprintf(resolve_buf, sizeof(resolve_buf)-1, "%s:%s:127.0.0.1", + host, port); + resolve = curl_slist_append(resolve, resolve_buf); + + curl = curl_easy_init(); + if(!curl) { + curl_mfprintf(stderr, "out of memory\n"); + return (CURLcode)1; + } + /* We want to use our own read function. */ + curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); + + /* It will help us to continue the read function. */ + curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback); + curl_easy_setopt(curl, CURLOPT_XFERINFODATA, curl); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); + + /* It will help us to ensure that keepalive does not help. */ + curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L); + curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 1L); + curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 1L); + curl_easy_setopt(curl, CURLOPT_TCP_KEEPCNT, 1L); + + /* Enable uploading. */ + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); + + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + if(curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L) != CURLE_OK || + curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, cli_debug_cb) != CURLE_OK || + curl_easy_setopt(curl, CURLOPT_RESOLVE, resolve) != CURLE_OK) { + curl_mfprintf(stderr, "something unexpected went wrong - bailing out!\n"); + return (CURLcode)2; + } + + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, http_version); + + rc = curl_easy_perform(curl); + + if(curl) { + curl_easy_cleanup(curl); + } + + curl_slist_free_all(resolve); + curl_free(host); + curl_free(port); + curl_url_cleanup(cu); + curl_global_cleanup(); + + return rc; +} diff --git a/vendor/curl/tests/libtest/cli_ws_data.c b/vendor/curl/tests/libtest/cli_ws_data.c new file mode 100644 index 00000000000..501c01eae2e --- /dev/null +++ b/vendor/curl/tests/libtest/cli_ws_data.c @@ -0,0 +1,419 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "first.h" + +#include "testtrace.h" +#include "memdebug.h" + +#ifndef CURL_DISABLE_WEBSOCKETS + +static CURLcode +test_ws_data_m2_check_recv(const struct curl_ws_frame *frame, + size_t r_offset, size_t nread, + size_t exp_len) +{ + if(!frame) + return CURLE_OK; + + if(frame->flags & CURLWS_CLOSE) { + curl_mfprintf(stderr, "recv_data: unexpected CLOSE frame from server, " + "got %zu bytes, offset=%zu, rflags %x\n", + nread, r_offset, frame->flags); + return CURLE_RECV_ERROR; + } + if(!r_offset && !(frame->flags & CURLWS_BINARY)) { + curl_mfprintf(stderr, "recv_data: wrong frame, got %zu bytes, offset=%zu, " + "rflags %x\n", + nread, r_offset, frame->flags); + return CURLE_RECV_ERROR; + } + if(frame->offset != (curl_off_t)r_offset) { + curl_mfprintf(stderr, "recv_data: frame offset, expected %zu, " + "got %" CURL_FORMAT_CURL_OFF_T "\n", + r_offset, frame->offset); + return CURLE_RECV_ERROR; + } + if(frame->bytesleft != (curl_off_t)(exp_len - r_offset - nread)) { + curl_mfprintf(stderr, "recv_data: frame bytesleft, " + "expected %" CURL_FORMAT_CURL_OFF_T ", " + "got %" CURL_FORMAT_CURL_OFF_T "\n", + (curl_off_t)(exp_len - r_offset - nread), frame->bytesleft); + return CURLE_RECV_ERROR; + } + if(r_offset + nread > exp_len) { + curl_mfprintf(stderr, "recv_data: data length, expected %zu, now at %zu\n", + exp_len, r_offset + nread); + return CURLE_RECV_ERROR; + } + return CURLE_OK; +} + +/* WebSocket Mode 2: CONNECT_ONLY 2, curl_ws_send()/curl_ws_recv() */ +static CURLcode test_ws_data_m2_echo(const char *url, + size_t count, + size_t plen_min, + size_t plen_max) +{ + CURL *curl = NULL; + CURLcode r = CURLE_OK; + const struct curl_ws_frame *frame; + size_t len; + char *send_buf = NULL, *recv_buf = NULL; + size_t i, scount = count, rcount = count; + int rblock, sblock; + + send_buf = calloc(1, plen_max + 1); + recv_buf = calloc(1, plen_max + 1); + if(!send_buf || !recv_buf) { + r = CURLE_OUT_OF_MEMORY; + goto out; + } + for(i = 0; i < plen_max; ++i) { + send_buf[i] = (char)('0' + ((int)i % 10)); + } + + curl = curl_easy_init(); + if(!curl) { + r = CURLE_OUT_OF_MEMORY; + goto out; + } + + curl_easy_setopt(curl, CURLOPT_URL, url); + + /* use the callback style */ + curl_easy_setopt(curl, CURLOPT_USERAGENT, "ws-data"); + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 2L); /* websocket style */ + r = curl_easy_perform(curl); + curl_mfprintf(stderr, "curl_easy_perform() returned %u\n", (int)r); + if(r != CURLE_OK) + goto out; + + for(len = plen_min; len <= plen_max; ++len) { + size_t nwritten, nread, slen = len, rlen = len; + char *sbuf = send_buf, *rbuf = recv_buf; + + memset(recv_buf, 0, plen_max); + while(slen || rlen || scount || rcount) { + sblock = rblock = 1; + if(slen) { + r = curl_ws_send(curl, sbuf, slen, &nwritten, 0, CURLWS_BINARY); + sblock = (r == CURLE_AGAIN); + if(!r || (r == CURLE_AGAIN)) { + curl_mfprintf(stderr, "curl_ws_send(len=%zu) -> %d, " + "%zu (%" CURL_FORMAT_CURL_OFF_T "/%zu)\n", + slen, r, nwritten, (curl_off_t)(len - slen), len); + sbuf += nwritten; + slen -= nwritten; + } + else + goto out; + } + if(!slen && scount) { /* go again? */ + scount--; + sbuf = send_buf; + slen = len; + } + + if(rlen) { + size_t max_recv = (64 * 1024); + r = curl_ws_recv(curl, rbuf, (rlen > max_recv) ? max_recv : rlen, + &nread, &frame); + if(!r || (r == CURLE_AGAIN)) { + rblock = (r == CURLE_AGAIN); + curl_mfprintf(stderr, "curl_ws_recv(len=%zu) -> %d, %zu (%ld/%zu) " + "\n", rlen, r, nread, (long)(len - rlen), len); + if(!r) { + r = test_ws_data_m2_check_recv(frame, len - rlen, nread, len); + if(r) + goto out; + } + rbuf += nread; + rlen -= nread; + } + else + goto out; + } + if(!rlen && rcount) { /* go again? */ + rcount--; + rbuf = recv_buf; + rlen = len; + } + + if(rblock && sblock) { + curl_mfprintf(stderr, "EAGAIN, sleep, try again\n"); + curlx_wait_ms(1); + } + } + + if(memcmp(send_buf, recv_buf, len)) { + curl_mfprintf(stderr, "recv_data: data differs\n"); + debug_dump("", "expected:", stderr, + (const unsigned char *)send_buf, len, FALSE); + debug_dump("", "received:", stderr, + (const unsigned char *)recv_buf, len, FALSE); + r = CURLE_RECV_ERROR; + goto out; + } + } + +out: + if(curl) { + if(!r) + ws_close(curl); + curl_easy_cleanup(curl); + } + free(send_buf); + free(recv_buf); + return r; +} + +struct test_ws_m1_ctx { + CURL *easy; + char *send_buf; + char *recv_buf; + size_t send_len, nsent; + size_t recv_len, nrcvd; +}; + +static size_t test_ws_data_m1_read(char *buf, size_t nitems, size_t buflen, + void *userdata) +{ + struct test_ws_m1_ctx *ctx = userdata; + size_t len = nitems * buflen; + size_t left = ctx->send_len - ctx->nsent; + + curl_mfprintf(stderr, "m1_read(len=%zu, left=%zu)\n", len, left); + if(left) { + if(left > len) + left = len; + memcpy(buf, ctx->send_buf + ctx->nsent, left); + ctx->nsent += left; + return left; + } + return CURL_READFUNC_PAUSE; +} + +static size_t test_ws_data_m1_write(char *buf, size_t nitems, size_t buflen, + void *userdata) +{ + struct test_ws_m1_ctx *ctx = userdata; + size_t len = nitems * buflen; + + curl_mfprintf(stderr, "m1_write(len=%zu)\n", len); + if(len > (ctx->recv_len - ctx->nrcvd)) + return CURL_WRITEFUNC_ERROR; + memcpy(ctx->recv_buf + ctx->nrcvd, buf, len); + ctx->nrcvd += len; + return len; +} + +/* WebSocket Mode 1: multi handle, READ/WRITEFUNCTION use */ +static CURLcode test_ws_data_m1_echo(const char *url, + size_t count, + size_t plen_min, + size_t plen_max) +{ + CURLM *multi = NULL; + CURLcode r = CURLE_OK; + struct test_ws_m1_ctx m1_ctx; + size_t i, len; + + memset(&m1_ctx, 0, sizeof(m1_ctx)); + m1_ctx.send_buf = calloc(1, plen_max + 1); + m1_ctx.recv_buf = calloc(1, plen_max + 1); + if(!m1_ctx.send_buf || !m1_ctx.recv_buf) { + r = CURLE_OUT_OF_MEMORY; + goto out; + } + for(i = 0; i < plen_max; ++i) { + m1_ctx.send_buf[i] = (char)('0' + ((int)i % 10)); + } + + multi = curl_multi_init(); + if(!multi) { + r = CURLE_OUT_OF_MEMORY; + goto out; + } + + m1_ctx.easy = curl_easy_init(); + if(!m1_ctx.easy) { + r = CURLE_OUT_OF_MEMORY; + goto out; + } + + curl_easy_setopt(m1_ctx.easy, CURLOPT_URL, url); + /* use the callback style */ + curl_easy_setopt(m1_ctx.easy, CURLOPT_USERAGENT, "ws-data"); + curl_easy_setopt(m1_ctx.easy, CURLOPT_VERBOSE, 1L); + /* we want to send */ + curl_easy_setopt(m1_ctx.easy, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(m1_ctx.easy, CURLOPT_READFUNCTION, test_ws_data_m1_read); + curl_easy_setopt(m1_ctx.easy, CURLOPT_READDATA, &m1_ctx); + curl_easy_setopt(m1_ctx.easy, CURLOPT_WRITEFUNCTION, test_ws_data_m1_write); + curl_easy_setopt(m1_ctx.easy, CURLOPT_WRITEDATA, &m1_ctx); + + curl_multi_add_handle(multi, m1_ctx.easy); + + for(len = plen_min; len <= plen_max; ++len) { + /* init what we want to send and expect to receive */ + m1_ctx.send_len = len; + m1_ctx.nsent = 0; + m1_ctx.recv_len = len; + m1_ctx.nrcvd = 0; + memset(m1_ctx.recv_buf, 0, plen_max); + curl_easy_pause(m1_ctx.easy, CURLPAUSE_CONT); + + for(i = 0; i < count; ++i) { + while(1) { + int still_running; /* keep number of running handles */ + CURLMcode mc = curl_multi_perform(multi, &still_running); + + if(!still_running || (m1_ctx.nrcvd == m1_ctx.recv_len)) { + /* got the full echo back or failed */ + break; + } + + if(!mc && still_running) { + mc = curl_multi_poll(multi, NULL, 0, 1, NULL); + } + if(mc) { + r = CURLE_RECV_ERROR; + goto out; + } + + } + + if(memcmp(m1_ctx.send_buf, m1_ctx.recv_buf, m1_ctx.send_len)) { + curl_mfprintf(stderr, "recv_data: data differs\n"); + debug_dump("", "expected:", stderr, + (unsigned char *)m1_ctx.send_buf, m1_ctx.send_len, 0); + debug_dump("", "received:", stderr, + (unsigned char *)m1_ctx.recv_buf, m1_ctx.nrcvd, 0); + r = CURLE_RECV_ERROR; + goto out; + } + + } + } + +out: + if(multi) + curl_multi_cleanup(multi); + if(m1_ctx.easy) { + curl_easy_cleanup(m1_ctx.easy); + } + free(m1_ctx.send_buf); + free(m1_ctx.recv_buf); + return r; +} + + +static void test_ws_data_usage(const char *msg) +{ + if(msg) + curl_mfprintf(stderr, "%s\n", msg); + curl_mfprintf(stderr, + "usage: [options] url\n" + " -m number minimum frame size\n" + " -M number maximum frame size\n" + ); +} + +#endif + +static CURLcode test_cli_ws_data(const char *URL) +{ +#ifndef CURL_DISABLE_WEBSOCKETS + CURLcode res = CURLE_OK; + const char *url; + size_t plen_min = 0, plen_max = 0, count = 1; + int ch, model = 2; + + (void)URL; + + while((ch = cgetopt(test_argc, test_argv, "12c:hm:M:")) != -1) { + switch(ch) { + case '1': + model = 1; + break; + case '2': + model = 2; + break; + case 'h': + test_ws_data_usage(NULL); + res = CURLE_BAD_FUNCTION_ARGUMENT; + goto cleanup; + case 'c': + count = (size_t)strtol(coptarg, NULL, 10); + break; + case 'm': + plen_min = (size_t)strtol(coptarg, NULL, 10); + break; + case 'M': + plen_max = (size_t)strtol(coptarg, NULL, 10); + break; + default: + test_ws_data_usage("invalid option"); + res = CURLE_BAD_FUNCTION_ARGUMENT; + goto cleanup; + } + } + test_argc -= coptind; + test_argv += coptind; + + if(!plen_max) + plen_max = plen_min; + + if(plen_max < plen_min) { + curl_mfprintf(stderr, "maxlen must be >= minlen, got %zu-%zu\n", + plen_min, plen_max); + res = CURLE_BAD_FUNCTION_ARGUMENT; + goto cleanup; + } + + if(test_argc != 1) { + test_ws_data_usage(NULL); + res = CURLE_BAD_FUNCTION_ARGUMENT; + goto cleanup; + } + url = test_argv[0]; + + curl_global_init(CURL_GLOBAL_ALL); + + if(model == 1) + res = test_ws_data_m1_echo(url, count, plen_min, plen_max); + else + res = test_ws_data_m2_echo(url, count, plen_min, plen_max); + +cleanup: + curl_global_cleanup(); + return res; + +#else /* !CURL_DISABLE_WEBSOCKETS */ + (void)URL; + curl_mfprintf(stderr, "WebSockets not enabled in libcurl\n"); + return (CURLcode)1; +#endif /* CURL_DISABLE_WEBSOCKETS */ +} diff --git a/vendor/curl/tests/libtest/cli_ws_pingpong.c b/vendor/curl/tests/libtest/cli_ws_pingpong.c new file mode 100644 index 00000000000..80707c95852 --- /dev/null +++ b/vendor/curl/tests/libtest/cli_ws_pingpong.c @@ -0,0 +1,94 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "first.h" + +#include "testtrace.h" +#include "memdebug.h" + +#ifndef CURL_DISABLE_WEBSOCKETS + +static CURLcode pingpong(CURL *curl, const char *payload) +{ + CURLcode res; + int i; + + res = ws_send_ping(curl, payload); + if(res) + return res; + for(i = 0; i < 10; ++i) { + curl_mfprintf(stderr, "Receive pong\n"); + res = ws_recv_pong(curl, payload); + if(res == CURLE_AGAIN) { + curlx_wait_ms(100); + continue; + } + ws_close(curl); + return res; + } + ws_close(curl); + return CURLE_RECV_ERROR; +} + +#endif + +static CURLcode test_cli_ws_pingpong(const char *URL) +{ +#ifndef CURL_DISABLE_WEBSOCKETS + CURL *curl; + CURLcode res = CURLE_OK; + const char *payload; + + if(!URL || !libtest_arg2) { + curl_mfprintf(stderr, "need args: URL payload\n"); + return (CURLcode)2; + } + payload = libtest_arg2; + + curl_global_init(CURL_GLOBAL_ALL); + + curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, URL); + + /* use the callback style */ + curl_easy_setopt(curl, CURLOPT_USERAGENT, "ws-pingpong"); + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 2L); /* websocket style */ + res = curl_easy_perform(curl); + curl_mfprintf(stderr, "curl_easy_perform() returned %u\n", res); + if(res == CURLE_OK) + res = pingpong(curl, payload); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + curl_global_cleanup(); + return res; + +#else /* !CURL_DISABLE_WEBSOCKETS */ + (void)URL; + curl_mfprintf(stderr, "WebSockets not enabled in libcurl\n"); + return (CURLcode)1; +#endif /* CURL_DISABLE_WEBSOCKETS */ +} diff --git a/vendor/curl/tests/libtest/first.c b/vendor/curl/tests/libtest/first.c index a10f87106d4..49ec8a5f91b 100644 --- a/vendor/curl/tests/libtest/first.c +++ b/vendor/curl/tests/libtest/first.c @@ -21,16 +21,13 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" #include "first.h" #ifdef HAVE_LOCALE_H -# include /* for setlocale() */ +#include /* for setlocale() */ #endif #include "memdebug.h" -#include "curlx/timediff.h" -#include "tool_binmode.h" int select_wrapper(int nfds, fd_set *rd, fd_set *wr, fd_set *exc, struct timeval *tv) @@ -53,31 +50,80 @@ int select_wrapper(int nfds, fd_set *rd, fd_set *wr, fd_set *exc, return select(nfds, rd, wr, exc, tv); } -void wait_ms(int ms) -{ - if(ms < 0) - return; -#ifdef USE_WINSOCK - Sleep((DWORD)ms); -#else - { - struct timeval t; - curlx_mstotv(&t, ms); - select_wrapper(0, NULL, NULL, NULL, &t); - } -#endif -} - -char *libtest_arg2 = NULL; -char *libtest_arg3 = NULL; -char *libtest_arg4 = NULL; +const char *libtest_arg2 = NULL; +const char *libtest_arg3 = NULL; +const char *libtest_arg4 = NULL; int test_argc; -char **test_argv; +const char **test_argv; +int testnum; -struct timeval tv_test_start; /* for test timing */ +struct curltime tv_test_start; /* for test timing */ int unitfail; /* for unittests */ +int coptind; +const char *coptarg; + +int cgetopt(int argc, const char * const argv[], const char *optstring) +{ + static int optpos = 1; + int coptopt; + const char *arg; + + if(coptind == 0) { /* Reset? */ + coptind = !!argc; + optpos = 1; + } + + arg = argv[coptind]; + if(arg && strcmp(arg, "--") == 0) { + coptind++; + return -1; + } + else if(!arg || arg[0] != '-') { + return -1; + } + else { + const char *opt = strchr(optstring, arg[optpos]); + coptopt = arg[optpos]; + if(!opt) { + if(!arg[++optpos]) { + coptind++; + optpos = 1; + } + return '?'; + } + else if(opt[1] == ':') { + if(arg[optpos + 1]) { + coptarg = arg + optpos + 1; + coptind++; + optpos = 1; + return coptopt; + } + else if(argv[coptind + 1]) { + coptarg = argv[coptind + 1]; + coptind += 2; + optpos = 1; + return coptopt; + } + else { + if(!arg[++optpos]) { + coptind++; + optpos = 1; + } + return *optstring == ':' ? ':' : '?'; + } + } + else { + if(!arg[++optpos]) { + coptind++; + optpos = 1; + } + return coptopt; + } + } +} + #ifdef CURLDEBUG static void memory_tracking_init(void) { @@ -114,17 +160,71 @@ char *hexdump(const unsigned char *buf, size_t len) return dump; } +#ifndef CURL_DISABLE_WEBSOCKETS +CURLcode ws_send_ping(CURL *curl, const char *send_payload) +{ + size_t sent; + CURLcode result = curl_ws_send(curl, send_payload, strlen(send_payload), + &sent, 0, CURLWS_PING); + curl_mfprintf(stderr, "ws: curl_ws_send returned %u, sent %zu\n", + result, sent); + return result; +} -int main(int argc, char **argv) +CURLcode ws_recv_pong(CURL *curl, const char *expected_payload) { - char *URL; + size_t rlen; + const struct curl_ws_frame *meta; + char buffer[256]; + CURLcode result = curl_ws_recv(curl, buffer, sizeof(buffer), &rlen, &meta); + if(result) { + curl_mfprintf(stderr, "ws: curl_ws_recv returned %u, received %zu\n", + result, rlen); + return result; + } + + if(!(meta->flags & CURLWS_PONG)) { + curl_mfprintf(stderr, "recv_pong: wrong frame, got %zu bytes rflags %x\n", + rlen, meta->flags); + return CURLE_RECV_ERROR; + } + + curl_mfprintf(stderr, "ws: got PONG back\n"); + if(rlen == strlen(expected_payload) && + !memcmp(expected_payload, buffer, rlen)) { + curl_mfprintf(stderr, "ws: got the same payload back\n"); + return CURLE_OK; /* lib2304 returned 'result' here. Intentional? */ + } + curl_mfprintf(stderr, "ws: did NOT get the same payload back\n"); + return CURLE_RECV_ERROR; +} + +/* just close the connection */ +void ws_close(CURL *curl) +{ + size_t sent; + CURLcode result = curl_ws_send(curl, "", 0, &sent, 0, CURLWS_CLOSE); + curl_mfprintf(stderr, "ws: curl_ws_send returned %u, sent %zu\n", + result, sent); +} +#endif /* CURL_DISABLE_WEBSOCKETS */ + + +int main(int argc, const char **argv) +{ + const char *URL = ""; CURLcode result; - int basearg; - test_func_t test_func; + entry_func_t entry_func; + const char *entry_name; + char *env; + size_t tmp; - CURL_SET_BINMODE(stdout); + CURLX_SET_BINMODE(stdout); memory_tracking_init(); +#ifdef _WIN32 + curlx_now_init(); +#endif /* * Setup proper locale from environment. This is needed to enable locale- @@ -135,65 +235,50 @@ int main(int argc, char **argv) setlocale(LC_ALL, ""); #endif - test_argc = argc; - test_argv = argv; + test_argc = argc - 1; + test_argv = argv + 1; -#ifdef CURLTESTS_BUNDLED - { - char *test_name; - - --test_argc; - ++test_argv; - - basearg = 2; - - if(argc < (basearg + 1)) { - curl_mfprintf(stderr, "Pass testname and URL as arguments please\n"); - return 1; - } - - test_name = argv[basearg - 1]; - test_func = NULL; - { - size_t tmp; - for(tmp = 0; tmp < CURL_ARRAYSIZE(s_tests); ++tmp) { - if(strcmp(test_name, s_tests[tmp].name) == 0) { - test_func = s_tests[tmp].ptr; - break; - } - } - } + if(argc < 2) { + curl_mfprintf(stderr, "Pass testname " + "(and URL as argument for numbered tests) please\n"); + return 1; + } - if(!test_func) { - curl_mfprintf(stderr, "Test '%s' not found.\n", test_name); - return 1; + entry_name = argv[1]; + entry_func = NULL; + for(tmp = 0; s_entries[tmp].ptr; ++tmp) { + if(strcmp(entry_name, s_entries[tmp].name) == 0) { + entry_func = s_entries[tmp].ptr; + break; } } -#else - basearg = 1; - if(argc < (basearg + 1)) { - curl_mfprintf(stderr, "Pass URL as argument please\n"); + if(!entry_func) { + curl_mfprintf(stderr, "Test '%s' not found.\n", entry_name); return 1; } - test_func = test; -#endif - - if(argc > (basearg + 1)) - libtest_arg2 = argv[basearg + 1]; + if(argc > 2) { + URL = argv[2]; + curl_mfprintf(stderr, "URL: %s\n", URL); + } - if(argc > (basearg + 2)) - libtest_arg3 = argv[basearg + 2]; + if(argc > 3) + libtest_arg2 = argv[3]; - if(argc > (basearg + 2)) - libtest_arg4 = argv[basearg + 3]; + if(argc > 4) + libtest_arg3 = argv[4]; - URL = argv[basearg]; /* provide this to the rest */ + if(argc > 5) + libtest_arg4 = argv[5]; - curl_mfprintf(stderr, "URL: %s\n", URL); + env = getenv("CURL_TESTNUM"); + if(env) + testnum = atoi(env); + else + testnum = 0; - result = test_func(URL); + result = entry_func(URL); curl_mfprintf(stderr, "Test ended with result %d\n", result); #ifdef _WIN32 diff --git a/vendor/curl/tests/libtest/first.h b/vendor/curl/tests/libtest/first.h index acf00a3a896..1592922e39a 100644 --- a/vendor/curl/tests/libtest/first.h +++ b/vendor/curl/tests/libtest/first.h @@ -23,17 +23,505 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#define CURL_DISABLE_DEPRECATION 1 +#define CURL_NO_OLDIES +#define CURL_DISABLE_DEPRECATION + +/* Now include the curl_setup.h file from libcurl's private libdir (the source + version, but that might include "curl_config.h" from the build dir so we + need both of them in the include path), so that we get good in-depth + knowledge about the system we're building this on */ #include "curl_setup.h" + #include -typedef CURLcode (*test_func_t)(char *); +typedef CURLcode (*entry_func_t)(const char *); -#ifdef CURLTESTS_BUNDLED -struct onetest { +struct entry_s { const char *name; - test_func_t ptr; + entry_func_t ptr; }; + +extern const struct entry_s s_entries[]; + +extern int unitfail; /* for unittests */ + +#include + +#ifdef HAVE_SYS_SELECT_H +/* since so many tests use select(), we can just as well include it here */ +#include #endif +#include "curl_printf.h" + +/* GCC <4.6 does not support '#pragma GCC diagnostic push' and + does not support 'pragma GCC diagnostic' inside functions. */ +#if (defined(__GNUC__) && \ + ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)))) +#define CURL_GNUC_DIAG +#endif + +#define test_setopt(A,B,C) \ + if((res = curl_easy_setopt((A), (B), (C))) != CURLE_OK) \ + goto test_cleanup + +#define test_multi_setopt(A,B,C) \ + if((res = curl_multi_setopt((A), (B), (C))) != CURLE_OK) \ + goto test_cleanup + +extern const char *libtest_arg2; /* set by first.c to the argv[2] or NULL */ +extern const char *libtest_arg3; /* set by first.c to the argv[3] or NULL */ +extern const char *libtest_arg4; /* set by first.c to the argv[4] or NULL */ + +/* argc and argv as passed in to the main() function */ +extern int test_argc; +extern const char **test_argv; +extern int testnum; +extern struct curltime tv_test_start; /* for test timing */ + +extern int coptind; +extern const char *coptarg; +int cgetopt(int argc, const char * const argv[], const char *optstring); + +extern int select_wrapper(int nfds, fd_set *rd, fd_set *wr, fd_set *exc, + struct timeval *tv); + +extern char *hexdump(const unsigned char *buffer, size_t len); + +#ifndef CURL_DISABLE_WEBSOCKETS +CURLcode ws_send_ping(CURL *curl, const char *send_payload); +CURLcode ws_recv_pong(CURL *curl, const char *expected_payload); +/* just close the connection */ +void ws_close(CURL *curl); +#endif + +/* +** TEST_ERR_* values must within the CURLcode range to not cause compiler +** errors. + +** For portability reasons TEST_ERR_* values should be less than 127. +*/ + +#define TEST_ERR_MAJOR_BAD CURLE_OBSOLETE20 +#define TEST_ERR_RUNS_FOREVER CURLE_OBSOLETE24 +#define TEST_ERR_EASY_INIT CURLE_OBSOLETE29 +#define TEST_ERR_MULTI CURLE_OBSOLETE32 +#define TEST_ERR_NUM_HANDLES CURLE_OBSOLETE34 +#define TEST_ERR_SELECT CURLE_OBSOLETE40 +#define TEST_ERR_SUCCESS CURLE_OBSOLETE41 +#define TEST_ERR_FAILURE CURLE_OBSOLETE44 +#define TEST_ERR_USAGE CURLE_OBSOLETE46 +#define TEST_ERR_FOPEN CURLE_OBSOLETE50 +#define TEST_ERR_FSTAT CURLE_OBSOLETE51 +#define TEST_ERR_BAD_TIMEOUT CURLE_OBSOLETE57 + +/* +** Macros for test source code readability/maintainability. +** +** All of the following macros require that an int data type 'res' variable +** exists in scope where macro is used, and that it has been initialized to +** zero before the macro is used. +** +** exe_* and chk_* macros are helper macros not intended to be used from +** outside of this header file. Arguments 'Y' and 'Z' of these represent +** source code file and line number, while Arguments 'A', 'B', etc, are +** the arguments used to actually call a libcurl function. +** +** All easy_* and multi_* macros call a libcurl function and evaluate if +** the function has succeeded or failed. When the function succeeds 'res' +** variable is not set nor cleared and program continues normal flow. On +** the other hand if function fails 'res' variable is set and a jump to +** label 'test_cleanup' is performed. +** +** Every easy_* and multi_* macros have a res_easy_* and res_multi_* macro +** counterpart that operates in the same way with the exception that no +** jump takes place in case of failure. res_easy_* and res_multi_* macros +** should be immediately followed by checking if 'res' variable has been +** set. +** +** 'res' variable when set will hold a CURLcode, CURLMcode, or any of the +** TEST_ERR_* values defined above. It is advisable to return this value +** as test result. +*/ + +/* ---------------------------------------------------------------- */ + +#define exe_easy_init(A,Y,Z) do { \ + if(((A) = curl_easy_init()) == NULL) { \ + curl_mfprintf(stderr, "%s:%d curl_easy_init() failed\n", (Y), (Z)); \ + res = TEST_ERR_EASY_INIT; \ + } \ +} while(0) + +#define res_easy_init(A) \ + exe_easy_init((A), (__FILE__), (__LINE__)) + +#define chk_easy_init(A,Y,Z) do { \ + exe_easy_init((A), (Y), (Z)); \ + if(res) \ + goto test_cleanup; \ +} while(0) + +#define easy_init(A) \ + chk_easy_init((A), (__FILE__), (__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_multi_init(A,Y,Z) do { \ + if(((A) = curl_multi_init()) == NULL) { \ + curl_mfprintf(stderr, "%s:%d curl_multi_init() failed\n", (Y), (Z)); \ + res = TEST_ERR_MULTI; \ + } \ +} while(0) + +#define res_multi_init(A) \ + exe_multi_init((A), (__FILE__), (__LINE__)) + +#define chk_multi_init(A,Y,Z) do { \ + exe_multi_init((A), (Y), (Z)); \ + if(res) \ + goto test_cleanup; \ +} while(0) + +#define multi_init(A) \ + chk_multi_init((A), (__FILE__), (__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_easy_setopt(A,B,C,Y,Z) do { \ + CURLcode ec; \ + if((ec = curl_easy_setopt((A), (B), (C))) != CURLE_OK) { \ + curl_mfprintf(stderr, "%s:%d curl_easy_setopt() failed, " \ + "with code %d (%s)\n", \ + (Y), (Z), ec, curl_easy_strerror(ec)); \ + res = ec; \ + } \ +} while(0) + +#define res_easy_setopt(A, B, C) \ + exe_easy_setopt((A), (B), (C), (__FILE__), (__LINE__)) + +#define chk_easy_setopt(A, B, C, Y, Z) do { \ + exe_easy_setopt((A), (B), (C), (Y), (Z)); \ + if(res) \ + goto test_cleanup; \ +} while(0) + +#define easy_setopt(A, B, C) \ + chk_easy_setopt((A), (B), (C), (__FILE__), (__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_multi_setopt(A, B, C, Y, Z) do { \ + CURLMcode ec; \ + if((ec = curl_multi_setopt((A), (B), (C))) != CURLM_OK) { \ + curl_mfprintf(stderr, "%s:%d curl_multi_setopt() failed, " \ + "with code %d (%s)\n", \ + (Y), (Z), ec, curl_multi_strerror(ec)); \ + res = TEST_ERR_MULTI; \ + } \ +} while(0) + +#define res_multi_setopt(A,B,C) \ + exe_multi_setopt((A), (B), (C), (__FILE__), (__LINE__)) + +#define chk_multi_setopt(A,B,C,Y,Z) do { \ + exe_multi_setopt((A), (B), (C), (Y), (Z)); \ + if(res) \ + goto test_cleanup; \ +} while(0) + +#define multi_setopt(A,B,C) \ + chk_multi_setopt((A), (B), (C), (__FILE__), (__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_multi_add_handle(A,B,Y,Z) do { \ + CURLMcode ec; \ + if((ec = curl_multi_add_handle((A), (B))) != CURLM_OK) { \ + curl_mfprintf(stderr, "%s:%d curl_multi_add_handle() failed, " \ + "with code %d (%s)\n", \ + (Y), (Z), ec, curl_multi_strerror(ec)); \ + res = TEST_ERR_MULTI; \ + } \ +} while(0) + +#define res_multi_add_handle(A, B) \ + exe_multi_add_handle((A), (B), (__FILE__), (__LINE__)) + +#define chk_multi_add_handle(A, B, Y, Z) do { \ + exe_multi_add_handle((A), (B), (Y), (Z)); \ + if(res) \ + goto test_cleanup; \ +} while(0) + +#define multi_add_handle(A, B) \ + chk_multi_add_handle((A), (B), (__FILE__), (__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_multi_remove_handle(A,B,Y,Z) do { \ + CURLMcode ec; \ + if((ec = curl_multi_remove_handle((A), (B))) != CURLM_OK) { \ + curl_mfprintf(stderr, "%s:%d curl_multi_remove_handle() failed, " \ + "with code %d (%s)\n", \ + (Y), (Z), ec, curl_multi_strerror(ec)); \ + res = TEST_ERR_MULTI; \ + } \ +} while(0) + +#define res_multi_remove_handle(A, B) \ + exe_multi_remove_handle((A), (B), (__FILE__), (__LINE__)) + +#define chk_multi_remove_handle(A, B, Y, Z) do { \ + exe_multi_remove_handle((A), (B), (Y), (Z)); \ + if(res) \ + goto test_cleanup; \ +} while(0) + + +#define multi_remove_handle(A, B) \ + chk_multi_remove_handle((A), (B), (__FILE__), (__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_multi_perform(A,B,Y,Z) do { \ + CURLMcode ec; \ + if((ec = curl_multi_perform((A), (B))) != CURLM_OK) { \ + curl_mfprintf(stderr, "%s:%d curl_multi_perform() failed, " \ + "with code %d (%s)\n", \ + (Y), (Z), ec, curl_multi_strerror(ec)); \ + res = TEST_ERR_MULTI; \ + } \ + else if(*((B)) < 0) { \ + curl_mfprintf(stderr, "%s:%d curl_multi_perform() succeeded, " \ + "but returned invalid running_handles value (%d)\n", \ + (Y), (Z), (int)*((B))); \ + res = TEST_ERR_NUM_HANDLES; \ + } \ +} while(0) + +#define res_multi_perform(A, B) \ + exe_multi_perform((A), (B), (__FILE__), (__LINE__)) + +#define chk_multi_perform(A, B, Y, Z) do { \ + exe_multi_perform((A), (B), (Y), (Z)); \ + if(res) \ + goto test_cleanup; \ +} while(0) + +#define multi_perform(A,B) \ + chk_multi_perform((A), (B), (__FILE__), (__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_multi_fdset(A, B, C, D, E, Y, Z) do { \ + CURLMcode ec; \ + if((ec = curl_multi_fdset((A), (B), (C), (D), (E))) != CURLM_OK) { \ + curl_mfprintf(stderr, "%s:%d curl_multi_fdset() failed, " \ + "with code %d (%s)\n", \ + (Y), (Z), ec, curl_multi_strerror(ec)); \ + res = TEST_ERR_MULTI; \ + } \ + else if(*((E)) < -1) { \ + curl_mfprintf(stderr, "%s:%d curl_multi_fdset() succeeded, " \ + "but returned invalid max_fd value (%d)\n", \ + (Y), (Z), (int)*((E))); \ + res = TEST_ERR_NUM_HANDLES; \ + } \ +} while(0) + +#define res_multi_fdset(A, B, C, D, E) \ + exe_multi_fdset((A), (B), (C), (D), (E), (__FILE__), (__LINE__)) + +#define chk_multi_fdset(A, B, C, D, E, Y, Z) do { \ + exe_multi_fdset((A), (B), (C), (D), (E), (Y), (Z)); \ + if(res) \ + goto test_cleanup; \ + } while(0) + +#define multi_fdset(A, B, C, D, E) \ + chk_multi_fdset((A), (B), (C), (D), (E), (__FILE__), (__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_multi_timeout(A,B,Y,Z) do { \ + CURLMcode ec; \ + if((ec = curl_multi_timeout((A), (B))) != CURLM_OK) { \ + curl_mfprintf(stderr, "%s:%d curl_multi_timeout() failed, " \ + "with code %d (%s)\n", \ + (Y), (Z), ec, curl_multi_strerror(ec)); \ + res = TEST_ERR_BAD_TIMEOUT; \ + } \ + else if(*((B)) < -1L) { \ + curl_mfprintf(stderr, "%s:%d curl_multi_timeout() succeeded, " \ + "but returned invalid timeout value (%ld)\n", \ + (Y), (Z), (long)*((B))); \ + res = TEST_ERR_BAD_TIMEOUT; \ + } \ +} while(0) + +#define res_multi_timeout(A, B) \ + exe_multi_timeout((A), (B), (__FILE__), (__LINE__)) + +#define chk_multi_timeout(A, B, Y, Z) do { \ + exe_multi_timeout((A), (B), (Y), (Z)); \ + if(res) \ + goto test_cleanup; \ + } while(0) + +#define multi_timeout(A, B) \ + chk_multi_timeout((A), (B), (__FILE__), (__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_multi_poll(A,B,C,D,E,Y,Z) do { \ + CURLMcode ec; \ + if((ec = curl_multi_poll((A), (B), (C), (D), (E))) != CURLM_OK) { \ + curl_mfprintf(stderr, "%s:%d curl_multi_poll() failed, " \ + "with code %d (%s)\n", \ + (Y), (Z), ec, curl_multi_strerror(ec)); \ + res = TEST_ERR_MULTI; \ + } \ + else if(*((E)) < 0) { \ + curl_mfprintf(stderr, "%s:%d curl_multi_poll() succeeded, " \ + "but returned invalid numfds value (%d)\n", \ + (Y), (Z), (int)*((E))); \ + res = TEST_ERR_NUM_HANDLES; \ + } \ +} while(0) + +#define res_multi_poll(A, B, C, D, E) \ + exe_multi_poll((A), (B), (C), (D), (E), (__FILE__), (__LINE__)) + +#define chk_multi_poll(A, B, C, D, E, Y, Z) do { \ + exe_multi_poll((A), (B), (C), (D), (E), (Y), (Z)); \ + if(res) \ + goto test_cleanup; \ +} while(0) + +#define multi_poll(A, B, C, D, E) \ + chk_multi_poll((A), (B), (C), (D), (E), (__FILE__), (__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_multi_wakeup(A,Y,Z) do { \ + CURLMcode ec; \ + if((ec = curl_multi_wakeup((A))) != CURLM_OK) { \ + curl_mfprintf(stderr, "%s:%d curl_multi_wakeup() failed, " \ + "with code %d (%s)\n", \ + (Y), (Z), ec, curl_multi_strerror(ec)); \ + res = TEST_ERR_MULTI; \ + } \ +} while(0) + +#define res_multi_wakeup(A) \ + exe_multi_wakeup((A), (__FILE__), (__LINE__)) + +#define chk_multi_wakeup(A, Y, Z) do { \ + exe_multi_wakeup((A), (Y), (Z)); \ + if(res) \ + goto test_cleanup; \ +} while(0) + +#define multi_wakeup(A) \ + chk_multi_wakeup((A), (__FILE__), (__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_select_test(A, B, C, D, E, Y, Z) do { \ + int ec; \ + if(select_wrapper((A), (B), (C), (D), (E)) == -1) { \ + ec = SOCKERRNO; \ + curl_mfprintf(stderr, "%s:%d select() failed, with " \ + "errno %d (%s)\n", \ + (Y), (Z), ec, strerror(ec)); \ + res = TEST_ERR_SELECT; \ + } \ + } while(0) + +#define res_select_test(A, B, C, D, E) \ + exe_select_test((A), (B), (C), (D), (E), (__FILE__), (__LINE__)) + +#define chk_select_test(A, B, C, D, E, Y, Z) do { \ + exe_select_test((A), (B), (C), (D), (E), (Y), (Z)); \ + if(res) \ + goto test_cleanup; \ + } while(0) + +#define select_test(A, B, C, D, E) \ + chk_select_test((A), (B), (C), (D), (E), (__FILE__), (__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define start_test_timing() do { \ + tv_test_start = curlx_now(); \ +} while(0) + +#define TEST_HANG_TIMEOUT 60 * 1000 /* global default */ + +#define exe_test_timedout(T,Y,Z) do { \ + timediff_t timediff = curlx_timediff(curlx_now(), tv_test_start); \ + if(timediff > (T)) { \ + curl_mfprintf(stderr, "%s:%d ABORTING TEST, since it seems " \ + "that it would have run forever (%ld ms > %ld ms)\n", \ + (Y), (Z), (long)timediff, (long)(TEST_HANG_TIMEOUT)); \ + res = TEST_ERR_RUNS_FOREVER; \ + } \ +} while(0) + +#define res_test_timedout() \ + exe_test_timedout(TEST_HANG_TIMEOUT, (__FILE__), (__LINE__)) + +#define res_test_timedout_custom(T) \ + exe_test_timedout((T), (__FILE__), (__LINE__)) + +#define chk_test_timedout(T, Y, Z) do { \ + exe_test_timedout(T, Y, Z); \ + if(res) \ + goto test_cleanup; \ + } while(0) + +#define abort_on_test_timeout() \ + chk_test_timedout(TEST_HANG_TIMEOUT, (__FILE__), (__LINE__)) + +#define abort_on_test_timeout_custom(T) \ + chk_test_timedout((T), (__FILE__), (__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_global_init(A,Y,Z) do { \ + CURLcode ec; \ + if((ec = curl_global_init((A))) != CURLE_OK) { \ + curl_mfprintf(stderr, "%s:%d curl_global_init() failed, " \ + "with code %d (%s)\n", \ + (Y), (Z), ec, curl_easy_strerror(ec)); \ + res = ec; \ + } \ +} while(0) + +#define res_global_init(A) \ + exe_global_init((A), (__FILE__), (__LINE__)) + +#define chk_global_init(A, Y, Z) do { \ + exe_global_init((A), (Y), (Z)); \ + if(res) \ + return res; \ + } while(0) + +/* global_init() is different than other macros. In case of + failure it 'return's instead of going to 'test_cleanup'. */ + +#define global_init(A) \ + chk_global_init((A), (__FILE__), (__LINE__)) + +#define NO_SUPPORT_BUILT_IN \ + { \ + (void)URL; \ + curl_mfprintf(stderr, "Missing support\n"); \ + return CURLE_UNSUPPORTED_PROTOCOL; \ + } + +#define NUM_HANDLES 4 /* global default */ + #endif /* HEADER_LIBTEST_FIRST_H */ diff --git a/vendor/curl/tests/libtest/lib1156.c b/vendor/curl/tests/libtest/lib1156.c index 1db7c7d8679..07f8e46a047 100644 --- a/vendor/curl/tests/libtest/lib1156.c +++ b/vendor/curl/tests/libtest/lib1156.c @@ -21,7 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" /* Check range/resume returned error codes and data presence. @@ -71,12 +71,12 @@ static const struct testparams testparams[] = { CURLE_OK } }; -static int hasbody; +static int hasbody; static size_t writedata(char *data, size_t size, size_t nmemb, void *userdata) { - (void) data; - (void) userdata; + (void)data; + (void)userdata; if(size && nmemb) hasbody = 1; @@ -98,12 +98,12 @@ static int onetest(CURL *curl, const char *url, const struct testparams *p, test_setopt(curl, CURLOPT_VERBOSE, 1L); test_setopt(curl, CURLOPT_RESUME_FROM, (p->flags & F_RESUME) ? 3L : 0L); test_setopt(curl, CURLOPT_RANGE, !(p->flags & F_RESUME) ? - "3-1000000": (char *) NULL); + "3-1000000": (char *)NULL); test_setopt(curl, CURLOPT_FAILONERROR, (p->flags & F_FAIL) ? 1L : 0L); hasbody = 0; res = curl_easy_perform(curl); if(res != p->result) { - curl_mprintf("%zd: bad error code (%d): resume=%s, fail=%s, http416=%s, " + curl_mprintf("%zu: bad error code (%d): resume=%s, fail=%s, http416=%s, " "content-range=%s, expected=%d\n", num, res, (p->flags & F_RESUME) ? "yes": "no", (p->flags & F_FAIL) ? "yes": "no", @@ -131,7 +131,7 @@ static int onetest(CURL *curl, const char *url, const struct testparams *p, /* for debugging: */ /* #define SINGLETEST 9 */ -CURLcode test(char *URL) +static CURLcode test_lib1156(const char *URL) { CURLcode res; CURL *curl; diff --git a/vendor/curl/tests/libtest/lib1301.c b/vendor/curl/tests/libtest/lib1301.c index 0a6080e7110..d476aed1483 100644 --- a/vendor/curl/tests/libtest/lib1301.c +++ b/vendor/curl/tests/libtest/lib1301.c @@ -21,33 +21,42 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" - -CURLcode test(char *URL) +#include "first.h" + +#define t1301_fail_unless(expr, msg) \ + do { \ + if(!(expr)) { \ + curl_mfprintf(stderr, "%s:%d Assertion '%s' FAILED: %s\n", \ + __FILE__, __LINE__, #expr, msg); \ + return TEST_ERR_FAILURE; \ + } \ + } while(0) + +static CURLcode test_lib1301(const char *URL) { int rc; (void)URL; rc = curl_strequal("iii", "III"); - fail_unless(rc != 0, "return code should be non-zero"); + t1301_fail_unless(rc != 0, "return code should be non-zero"); rc = curl_strequal("iiia", "III"); - fail_unless(rc == 0, "return code should be zero"); + t1301_fail_unless(rc == 0, "return code should be zero"); rc = curl_strequal("iii", "IIIa"); - fail_unless(rc == 0, "return code should be zero"); + t1301_fail_unless(rc == 0, "return code should be zero"); rc = curl_strequal("iiiA", "IIIa"); - fail_unless(rc != 0, "return code should be non-zero"); + t1301_fail_unless(rc != 0, "return code should be non-zero"); rc = curl_strnequal("iii", "III", 3); - fail_unless(rc != 0, "return code should be non-zero"); + t1301_fail_unless(rc != 0, "return code should be non-zero"); rc = curl_strnequal("iiiABC", "IIIcba", 3); - fail_unless(rc != 0, "return code should be non-zero"); + t1301_fail_unless(rc != 0, "return code should be non-zero"); rc = curl_strnequal("ii", "II", 3); - fail_unless(rc != 0, "return code should be non-zero"); + t1301_fail_unless(rc != 0, "return code should be non-zero"); return CURLE_OK; } diff --git a/vendor/curl/tests/libtest/lib1308.c b/vendor/curl/tests/libtest/lib1308.c index 0c70f3d6bcb..8e83462a7ad 100644 --- a/vendor/curl/tests/libtest/lib1308.c +++ b/vendor/curl/tests/libtest/lib1308.c @@ -21,9 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" - -#include +#include "first.h" static size_t print_httppost_callback(void *arg, const char *buf, size_t len) { @@ -32,8 +30,18 @@ static size_t print_httppost_callback(void *arg, const char *buf, size_t len) return len; } -CURLcode test(char *URL) +#define t1308_fail_unless(expr, msg) \ + do { \ + if(!(expr)) { \ + curl_mfprintf(stderr, "%s:%d Assertion '%s' FAILED: %s\n", \ + __FILE__, __LINE__, #expr, msg); \ + errorcount++; \ + } \ + } while(0) + +static CURLcode test_lib1308(const char *URL) { + int errorcount = 0; CURLFORMcode rc; int res; struct curl_httppost *post = NULL; @@ -42,26 +50,26 @@ CURLcode test(char *URL) char buffer[] = "test buffer"; rc = curl_formadd(&post, &last, CURLFORM_COPYNAME, "name", - CURLFORM_COPYCONTENTS, "content", CURLFORM_END); - fail_unless(rc == 0, "curl_formadd returned error"); + CURLFORM_COPYCONTENTS, "content", CURLFORM_END); + t1308_fail_unless(rc == 0, "curl_formadd returned error"); /* after the first curl_formadd when there's a single entry, both pointers should point to the same struct */ - fail_unless(post == last, "post and last weren't the same"); + t1308_fail_unless(post == last, "post and last weren't the same"); rc = curl_formadd(&post, &last, CURLFORM_COPYNAME, "htmlcode", CURLFORM_COPYCONTENTS, "", CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END); - fail_unless(rc == 0, "curl_formadd returned error"); + t1308_fail_unless(rc == 0, "curl_formadd returned error"); rc = curl_formadd(&post, &last, CURLFORM_COPYNAME, "name_for_ptrcontent", CURLFORM_PTRCONTENTS, buffer, CURLFORM_END); - fail_unless(rc == 0, "curl_formadd returned error"); + t1308_fail_unless(rc == 0, "curl_formadd returned error"); res = curl_formget(post, &total_size, print_httppost_callback); - fail_unless(res == 0, "curl_formget returned error"); + t1308_fail_unless(res == 0, "curl_formget returned error"); - fail_unless(total_size == 518, "curl_formget got wrong size back"); + t1308_fail_unless(total_size == 518, "curl_formget got wrong size back"); curl_formfree(post); @@ -73,14 +81,14 @@ CURLcode test(char *URL) CURLFORM_FILE, URL, CURLFORM_FILENAME, "custom named file", CURLFORM_END); - fail_unless(rc == 0, "curl_formadd returned error"); + t1308_fail_unless(rc == 0, "curl_formadd returned error"); res = curl_formget(post, &total_size, print_httppost_callback); - fail_unless(res == 0, "curl_formget returned error"); - fail_unless(total_size == 899, "curl_formget got wrong size back"); + t1308_fail_unless(res == 0, "curl_formget returned error"); + t1308_fail_unless(total_size == 899, "curl_formget got wrong size back"); curl_formfree(post); - return CURLE_OK; + return errorcount ? TEST_ERR_FAILURE : CURLE_OK; } diff --git a/vendor/curl/tests/libtest/lib1485.c b/vendor/curl/tests/libtest/lib1485.c index 71678563f2f..dd2b9728b73 100644 --- a/vendor/curl/tests/libtest/lib1485.c +++ b/vendor/curl/tests/libtest/lib1485.c @@ -21,13 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -struct transfer_status { +struct t1485_transfer_status { CURL *easy; curl_off_t out_len; size_t hd_line; @@ -35,10 +33,10 @@ struct transfer_status { int http_status; }; -static size_t header_callback(char *ptr, size_t size, size_t nmemb, - void *userp) +static size_t t1485_header_callback(char *ptr, size_t size, size_t nmemb, + void *userp) { - struct transfer_status *st = (struct transfer_status *)userp; + struct t1485_transfer_status *st = (struct t1485_transfer_status *)userp; const char *hd = ptr; size_t len = size * nmemb; CURLcode result; @@ -61,8 +59,8 @@ static size_t header_callback(char *ptr, size_t size, size_t nmemb, if(st->http_status >= 200 && st->http_status < 300) { result = curl_easy_getinfo(st->easy, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &clen); - curl_mfprintf(stderr, "header_callback, info Content-Length: %ld, %d\n", - (long)clen, result); + curl_mfprintf(stderr, "header_callback, info Content-Length: " + "%" CURL_FORMAT_CURL_OFF_T ", %d\n", clen, result); if(result) { st->result = result; return CURLE_WRITE_ERROR; @@ -70,7 +68,7 @@ static size_t header_callback(char *ptr, size_t size, size_t nmemb, if(clen < 0) { curl_mfprintf(stderr, "header_callback, expected known Content-Length, " - "got: %ld\n", (long)clen); + "got: %" CURL_FORMAT_CURL_OFF_T "\n", clen); return CURLE_WRITE_ERROR; } } @@ -78,20 +76,20 @@ static size_t header_callback(char *ptr, size_t size, size_t nmemb, return len; } -static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userp) +static size_t t1485_write_cb(char *ptr, size_t size, size_t nmemb, void *userp) { - struct transfer_status *st = (struct transfer_status *)userp; + struct t1485_transfer_status *st = (struct t1485_transfer_status *)userp; size_t len = size * nmemb; fwrite(ptr, size, nmemb, stdout); st->out_len += (curl_off_t)len; return len; } -CURLcode test(char *URL) +static CURLcode test_lib1485(const char *URL) { CURL *curls = NULL; CURLcode res = CURLE_OK; - struct transfer_status st; + struct t1485_transfer_status st; start_test_timing(); @@ -103,9 +101,9 @@ CURLcode test(char *URL) st.easy = curls; /* to allow callbacks access */ easy_setopt(curls, CURLOPT_URL, URL); - easy_setopt(curls, CURLOPT_WRITEFUNCTION, write_callback); + easy_setopt(curls, CURLOPT_WRITEFUNCTION, t1485_write_cb); easy_setopt(curls, CURLOPT_WRITEDATA, &st); - easy_setopt(curls, CURLOPT_HEADERFUNCTION, header_callback); + easy_setopt(curls, CURLOPT_HEADERFUNCTION, t1485_header_callback); easy_setopt(curls, CURLOPT_HEADERDATA, &st); easy_setopt(curls, CURLOPT_NOPROGRESS, 1L); diff --git a/vendor/curl/tests/libtest/lib1500.c b/vendor/curl/tests/libtest/lib1500.c index b5944ef3137..8529f66a44e 100644 --- a/vendor/curl/tests/libtest/lib1500.c +++ b/vendor/curl/tests/libtest/lib1500.c @@ -21,15 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -CURLcode test(char *URL) +static CURLcode test_lib1500(const char *URL) { CURL *curls = NULL; CURLM *multi = NULL; diff --git a/vendor/curl/tests/libtest/lib1501.c b/vendor/curl/tests/libtest/lib1501.c index 2194127ed59..61e586cd3dd 100644 --- a/vendor/curl/tests/libtest/lib1501.c +++ b/vendor/curl/tests/libtest/lib1501.c @@ -21,22 +21,17 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include - -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 30 * 1000 - -/* 500 milliseconds allowed. An extreme number but lets be really conservative - to allow old and slow machines to run this test too */ -#define MAX_BLOCKED_TIME_MS 500 - -CURLcode test(char *URL) +static CURLcode test_lib1501(const char *URL) { + static const long HANG_TIMEOUT = 30 * 1000; + /* 500 milliseconds allowed. An extreme number but lets be really + conservative to allow old and slow machines to run this test too */ + static const int MAX_BLOCKED_TIME_MS = 500; + CURL *handle = NULL; CURLM *mhandle = NULL; CURLcode res = CURLE_OK; @@ -57,7 +52,7 @@ CURLcode test(char *URL) multi_perform(mhandle, &still_running); - abort_on_test_timeout(); + abort_on_test_timeout_custom(HANG_TIMEOUT); while(still_running) { struct timeval timeout; @@ -65,9 +60,9 @@ CURLcode test(char *URL) fd_set fdwrite; fd_set fdexcep; int maxfd = -99; - struct timeval before; - struct timeval after; - long e; + struct curltime before; + struct curltime after; + timediff_t e; timeout.tv_sec = 0; timeout.tv_usec = 100000L; /* 100 ms */ @@ -82,18 +77,18 @@ CURLcode test(char *URL) select_test(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout); - abort_on_test_timeout(); + abort_on_test_timeout_custom(HANG_TIMEOUT); curl_mfprintf(stderr, "ping\n"); - before = tutil_tvnow(); + before = curlx_now(); multi_perform(mhandle, &still_running); - abort_on_test_timeout(); + abort_on_test_timeout_custom(HANG_TIMEOUT); - after = tutil_tvnow(); - e = tutil_tvdiff(after, before); - curl_mfprintf(stderr, "pong = %ld\n", e); + after = curlx_now(); + e = curlx_timediff(after, before); + curl_mfprintf(stderr, "pong = %ld\n", (long)e); if(e > MAX_BLOCKED_TIME_MS) { res = CURLE_TOO_LARGE; diff --git a/vendor/curl/tests/libtest/lib1502.c b/vendor/curl/tests/libtest/lib1502.c index cb7a8c2ae64..22ac6e7c80a 100644 --- a/vendor/curl/tests/libtest/lib1502.c +++ b/vendor/curl/tests/libtest/lib1502.c @@ -23,30 +23,23 @@ ***************************************************************************/ /* * This source code is used for lib1502, lib1503, lib1504 and lib1505 with - * only #ifdefs controlling the cleanup sequence. + * only the testnum controlling the cleanup sequence. * * Test case 1502 converted from bug report #3575448, identifying a memory * leak in the CURLOPT_RESOLVE handling with the multi interface. */ -#include "test.h" +#include "first.h" -#include - -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -CURLcode test(char *URL) +static CURLcode test_lib1502(const char *URL) { CURL *easy = NULL; CURL *dup; CURLM *multi = NULL; int still_running; CURLcode res = CURLE_OK; - char redirect[160]; /* DNS cache injection */ @@ -123,35 +116,35 @@ CURLcode test(char *URL) test_cleanup: -#ifdef LIB1502 - /* undocumented cleanup sequence - type UA */ - curl_multi_cleanup(multi); - curl_easy_cleanup(easy); - curl_global_cleanup(); -#endif - -#ifdef LIB1503 - /* proper cleanup sequence - type PA */ - curl_multi_remove_handle(multi, easy); - curl_multi_cleanup(multi); - curl_easy_cleanup(easy); - curl_global_cleanup(); -#endif - -#ifdef LIB1504 - /* undocumented cleanup sequence - type UB */ - curl_easy_cleanup(easy); - curl_multi_cleanup(multi); - curl_global_cleanup(); -#endif - -#ifdef LIB1505 - /* proper cleanup sequence - type PB */ - curl_multi_remove_handle(multi, easy); - curl_easy_cleanup(easy); - curl_multi_cleanup(multi); - curl_global_cleanup(); -#endif + switch(testnum) { + case 1502: + default: + /* undocumented cleanup sequence - type UA */ + curl_multi_cleanup(multi); + curl_easy_cleanup(easy); + curl_global_cleanup(); + break; + case 1503: + /* proper cleanup sequence - type PA */ + curl_multi_remove_handle(multi, easy); + curl_multi_cleanup(multi); + curl_easy_cleanup(easy); + curl_global_cleanup(); + break; + case 1504: + /* undocumented cleanup sequence - type UB */ + curl_easy_cleanup(easy); + curl_multi_cleanup(multi); + curl_global_cleanup(); + break; + case 1505: + /* proper cleanup sequence - type PB */ + curl_multi_remove_handle(multi, easy); + curl_easy_cleanup(easy); + curl_multi_cleanup(multi); + curl_global_cleanup(); + break; + } curl_slist_free_all(dns_cache_list); diff --git a/vendor/curl/tests/libtest/lib1506.c b/vendor/curl/tests/libtest/lib1506.c index d7e4cb0d628..66768f75637 100644 --- a/vendor/curl/tests/libtest/lib1506.c +++ b/vendor/curl/tests/libtest/lib1506.c @@ -21,34 +21,28 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -#define NUM_HANDLES 4 - -CURLcode test(char *URL) +static CURLcode test_lib1506(const char *URL) { CURLcode res = CURLE_OK; CURL *curl[NUM_HANDLES] = {0}; int running; CURLM *m = NULL; - int i; + size_t i; char target_url[256]; char dnsentry[256]; struct curl_slist *slist = NULL, *slist2; - char *port = libtest_arg3; - char *address = libtest_arg2; + const char *port = libtest_arg3; + const char *address = libtest_arg2; (void)URL; /* Create fake DNS entries for serverX.example.com for all handles */ - for(i = 0; i < NUM_HANDLES; i++) { - curl_msnprintf(dnsentry, sizeof(dnsentry), "server%d.example.com:%s:%s", + for(i = 0; i < CURL_ARRAYSIZE(curl); i++) { + curl_msnprintf(dnsentry, sizeof(dnsentry), "server%zu.example.com:%s:%s", i + 1, port, address); curl_mprintf("%s\n", dnsentry); slist2 = curl_slist_append(slist, dnsentry); @@ -67,13 +61,13 @@ CURLcode test(char *URL) multi_setopt(m, CURLMOPT_MAXCONNECTS, 3L); - /* get NUM_HANDLES easy handles */ - for(i = 0; i < NUM_HANDLES; i++) { + /* get each easy handle */ + for(i = 0; i < CURL_ARRAYSIZE(curl); i++) { /* get an easy handle */ easy_init(curl[i]); /* specify target */ curl_msnprintf(target_url, sizeof(target_url), - "http://server%d.example.com:%s/path/1506%04i", + "http://server%zu.example.com:%s/path/1506%04zu", i + 1, port, i + 1); target_url[sizeof(target_url) - 1] = '\0'; easy_setopt(curl[i], CURLOPT_URL, target_url); @@ -87,7 +81,7 @@ CURLcode test(char *URL) curl_mfprintf(stderr, "Start at URL 0\n"); - for(i = 0; i < NUM_HANDLES; i++) { + for(i = 0; i < CURL_ARRAYSIZE(curl); i++) { /* add handle to multi */ multi_add_handle(m, curl[i]); @@ -118,14 +112,14 @@ CURLcode test(char *URL) abort_on_test_timeout(); } - wait_ms(1); /* to ensure different end times */ + curlx_wait_ms(1); /* to ensure different end times */ } test_cleanup: /* proper cleanup sequence - type PB */ - for(i = 0; i < NUM_HANDLES; i++) { + for(i = 0; i < CURL_ARRAYSIZE(curl); i++) { curl_multi_remove_handle(m, curl[i]); curl_easy_cleanup(curl[i]); } diff --git a/vendor/curl/tests/libtest/lib1507.c b/vendor/curl/tests/libtest/lib1507.c index 7525ec53429..8d96c6b3009 100644 --- a/vendor/curl/tests/libtest/lib1507.c +++ b/vendor/curl/tests/libtest/lib1507.c @@ -21,24 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "timediff.h" -#include "warnless.h" #include "memdebug.h" -/* - * This is the list of basic details you need to tweak to get things right. - */ -#define USERNAME "user@example.com" -#define PASSWORD "123qwerty" -#define RECIPIENT "<1507-recipient@example.com>" -#define MAILFROM "<1507-realuser@example.com>" - -#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000 - -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) +static size_t t1507_read_cb(char *ptr, size_t size, size_t nmemb, void *userp) { (void)ptr; (void)size; @@ -47,39 +34,41 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) return CURL_READFUNC_ABORT; } -CURLcode test(char *URL) +static CURLcode test_lib1507(const char *URL) { - CURLcode res = CURLE_OK; - CURL *curl = NULL; - CURLM *mcurl = NULL; - int still_running = 1; - struct timeval mp_start; - struct curl_slist *rcpt_list = NULL; + static const int MULTI_PERFORM_HANG_TIMEOUT = 60 * 1000; - curl_global_init(CURL_GLOBAL_DEFAULT); + CURLcode res = CURLE_OK; + CURL *curl = NULL; + CURLM *mcurl = NULL; + int still_running = 1; + struct curltime mp_start; + struct curl_slist *rcpt_list = NULL; - easy_init(curl); + curl_global_init(CURL_GLOBAL_DEFAULT); - multi_init(mcurl); + easy_init(curl); - rcpt_list = curl_slist_append(rcpt_list, RECIPIENT); - /* more addresses can be added here - rcpt_list = curl_slist_append(rcpt_list, ""); - */ + multi_init(mcurl); - curl_easy_setopt(curl, CURLOPT_URL, URL); + rcpt_list = curl_slist_append(rcpt_list, "<1507-recipient@example.com>"); +#if 0 + /* more addresses can be added here */ + rcpt_list = curl_slist_append(rcpt_list, ""); +#endif + curl_easy_setopt(curl, CURLOPT_URL, URL); #if 0 - curl_easy_setopt(curl, CURLOPT_USERNAME, USERNAME); - curl_easy_setopt(curl, CURLOPT_PASSWORD, PASSWORD); + curl_easy_setopt(curl, CURLOPT_USERNAME, "user@example.com"); + curl_easy_setopt(curl, CURLOPT_PASSWORD, "123qwerty"); #endif - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); - curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); - curl_easy_setopt(curl, CURLOPT_MAIL_FROM, MAILFROM); - curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt_list); - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); - multi_add_handle(mcurl, curl); + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(curl, CURLOPT_READFUNCTION, t1507_read_cb); + curl_easy_setopt(curl, CURLOPT_MAIL_FROM, "<1507-realuser@example.com>"); + curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt_list); + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + multi_add_handle(mcurl, curl); - mp_start = tutil_tvnow(); + mp_start = curlx_now(); /* we start some action by calling perform right away */ curl_multi_perform(mcurl, &still_running); @@ -123,7 +112,7 @@ CURLcode test(char *URL) rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout); - if(tutil_tvdiff(tutil_tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) { + if(curlx_timediff(curlx_now(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) { curl_mfprintf(stderr, "ABORTING TEST, since it seems " "that it would have run forever.\n"); break; diff --git a/vendor/curl/tests/libtest/lib1508.c b/vendor/curl/tests/libtest/lib1508.c index 5e8547bb8ac..a305e652ff2 100644 --- a/vendor/curl/tests/libtest/lib1508.c +++ b/vendor/curl/tests/libtest/lib1508.c @@ -21,13 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1508(const char *URL) { CURLcode res = CURLE_OK; CURLM *m = NULL; diff --git a/vendor/curl/tests/libtest/lib1509.c b/vendor/curl/tests/libtest/lib1509.c index a289da56dcf..1bbf61c74a2 100644 --- a/vendor/curl/tests/libtest/lib1509.c +++ b/vendor/curl/tests/libtest/lib1509.c @@ -21,18 +21,16 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" size_t WriteOutput(char *ptr, size_t size, size_t nmemb, void *stream); size_t WriteHeader(char *ptr, size_t size, size_t nmemb, void *stream); -static unsigned long realHeaderSize = 0; +static size_t realHeaderSize = 0; -CURLcode test(char *URL) +static CURLcode test_lib1509(const char *URL) { long headerSize; CURLcode code; @@ -72,7 +70,7 @@ CURLcode test(char *URL) } curl_mprintf("header length is ........: %ld\n", headerSize); - curl_mprintf("header length should be..: %lu\n", realHeaderSize); + curl_mprintf("header length should be..: %zu\n", realHeaderSize); test_cleanup: @@ -93,7 +91,7 @@ size_t WriteHeader(char *ptr, size_t size, size_t nmemb, void *stream) (void)ptr; (void)stream; - realHeaderSize += curlx_uztoul(size * nmemb); + realHeaderSize += size * nmemb; return nmemb * size; } diff --git a/vendor/curl/tests/libtest/lib1510.c b/vendor/curl/tests/libtest/lib1510.c index d039b7b0e35..e914d48eb78 100644 --- a/vendor/curl/tests/libtest/lib1510.c +++ b/vendor/curl/tests/libtest/lib1510.c @@ -21,26 +21,22 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -#define NUM_URLS 4 - -CURLcode test(char *URL) +static CURLcode test_lib1510(const char *URL) { + static const int NUM_URLS = 4; + CURLcode res = CURLE_OK; CURL *curl = NULL; int i; char target_url[256]; char dnsentry[256]; struct curl_slist *slist = NULL, *slist2; - char *port = libtest_arg3; - char *address = libtest_arg2; + const char *port = libtest_arg3; + const char *address = libtest_arg2; (void)URL; @@ -73,7 +69,7 @@ CURLcode test(char *URL) easy_setopt(curl, CURLOPT_MAXCONNECTS, 3L); - /* get NUM_HANDLES easy handles */ + /* get NUM_URLS easy handles */ for(i = 0; i < NUM_URLS; i++) { /* specify target */ curl_msnprintf(target_url, sizeof(target_url), diff --git a/vendor/curl/tests/libtest/lib1511.c b/vendor/curl/tests/libtest/lib1511.c index abc1356e5b5..de09d2a6fa9 100644 --- a/vendor/curl/tests/libtest/lib1511.c +++ b/vendor/curl/tests/libtest/lib1511.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1511(const char *URL) { long unmet; CURL *curl = NULL; @@ -37,7 +37,7 @@ CURLcode test(char *URL) easy_setopt(curl, CURLOPT_URL, URL); easy_setopt(curl, CURLOPT_HEADER, 1L); - easy_setopt(curl, CURLOPT_TIMECONDITION, (long)CURL_TIMECOND_IFMODSINCE); + easy_setopt(curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE); /* TIMEVALUE in the future */ easy_setopt(curl, CURLOPT_TIMEVALUE, 1566210680L); diff --git a/vendor/curl/tests/libtest/lib1512.c b/vendor/curl/tests/libtest/lib1512.c index 02b2e8cac5d..6e6287dbfc3 100644 --- a/vendor/curl/tests/libtest/lib1512.c +++ b/vendor/curl/tests/libtest/lib1512.c @@ -28,21 +28,19 @@ * easy transfer finds and uses the populated stuff. */ -#include "test.h" +#include "first.h" #include "memdebug.h" -#define NUM_HANDLES 2 - -CURLcode test(char *URL) +static CURLcode test_lib1512(const char *URL) { CURLcode res = CURLE_OK; - CURL *curl[NUM_HANDLES] = {NULL, NULL}; - char *port = libtest_arg3; - char *address = libtest_arg2; + CURL *curl[2] = {NULL, NULL}; + const char *port = libtest_arg3; + const char *address = libtest_arg2; char dnsentry[256]; struct curl_slist *slist = NULL; - int i; + size_t i; char target_url[256]; (void)URL; /* URL is setup in the code */ @@ -56,13 +54,13 @@ CURLcode test(char *URL) curl_mprintf("%s\n", dnsentry); slist = curl_slist_append(slist, dnsentry); - /* get NUM_HANDLES easy handles */ - for(i = 0; i < NUM_HANDLES; i++) { + /* get each easy handle */ + for(i = 0; i < CURL_ARRAYSIZE(curl); i++) { /* get an easy handle */ easy_init(curl[i]); /* specify target */ curl_msnprintf(target_url, sizeof(target_url), - "http://server.example.curl:%s/path/1512%04i", + "http://server.example.curl:%s/path/1512%04zu", port, i + 1); target_url[sizeof(target_url) - 1] = '\0'; easy_setopt(curl[i], CURLOPT_URL, target_url); @@ -77,8 +75,8 @@ CURLcode test(char *URL) /* make the first one populate the GLOBAL cache */ easy_setopt(curl[0], CURLOPT_RESOLVE, slist); - /* run NUM_HANDLES transfers */ - for(i = 0; (i < NUM_HANDLES) && !res; i++) { + /* run each transfer */ + for(i = 0; (i < CURL_ARRAYSIZE(curl)) && !res; i++) { res = curl_easy_perform(curl[i]); if(res) goto test_cleanup; diff --git a/vendor/curl/tests/libtest/lib1513.c b/vendor/curl/tests/libtest/lib1513.c index 9da57d967d5..c86c5185e23 100644 --- a/vendor/curl/tests/libtest/lib1513.c +++ b/vendor/curl/tests/libtest/lib1513.c @@ -28,7 +28,7 @@ * of 42 (CURLE_ABORTED_BY_CALLBACK). */ -#include "test.h" +#include "first.h" #include "memdebug.h" @@ -47,7 +47,7 @@ static int progressKiller(void *arg, return 1; } -CURLcode test(char *URL) +static CURLcode test_lib1513(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; @@ -57,11 +57,11 @@ CURLcode test(char *URL) easy_init(curl); easy_setopt(curl, CURLOPT_URL, URL); - easy_setopt(curl, CURLOPT_TIMEOUT, (long)7); - easy_setopt(curl, CURLOPT_NOSIGNAL, (long)1); + easy_setopt(curl, CURLOPT_TIMEOUT, 7L); + easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progressKiller); easy_setopt(curl, CURLOPT_PROGRESSDATA, NULL); - easy_setopt(curl, CURLOPT_NOPROGRESS, (long)0); + easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); res = curl_easy_perform(curl); diff --git a/vendor/curl/tests/libtest/lib1514.c b/vendor/curl/tests/libtest/lib1514.c index 6b4e18bac0f..265f47af08d 100644 --- a/vendor/curl/tests/libtest/lib1514.c +++ b/vendor/curl/tests/libtest/lib1514.c @@ -26,20 +26,18 @@ * size is unknown. */ -#include "test.h" +#include "first.h" #include "memdebug.h" -static char testdata[]="dummy"; - -struct WriteThis { +struct t1514_WriteThis { char *readptr; size_t sizeleft; }; -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) +static size_t t1514_read_cb(char *ptr, size_t size, size_t nmemb, void *userp) { - struct WriteThis *pooh = (struct WriteThis *)userp; + struct t1514_WriteThis *pooh = (struct t1514_WriteThis *)userp; if(size*nmemb < 1) return 0; @@ -54,12 +52,15 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) return 0; /* no more data left to deliver */ } -CURLcode test(char *URL) +static CURLcode test_lib1514(const char *URL) { CURL *curl; CURLcode result = CURLE_OK; CURLcode res = CURLE_OK; - struct WriteThis pooh = { testdata, sizeof(testdata)-1 }; + + static char testdata[] = "dummy"; + + struct t1514_WriteThis pooh = { testdata, sizeof(testdata)-1 }; global_init(CURL_GLOBAL_ALL); @@ -68,12 +69,13 @@ CURLcode test(char *URL) easy_setopt(curl, CURLOPT_URL, URL); easy_setopt(curl, CURLOPT_POST, 1L); /* Purposely omit to set CURLOPT_POSTFIELDSIZE */ - easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); + easy_setopt(curl, CURLOPT_READFUNCTION, t1514_read_cb); easy_setopt(curl, CURLOPT_READDATA, &pooh); -#ifdef LIB1539 - /* speak HTTP 1.0 - no chunked! */ - easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); -#endif + + if(testnum == 1539) { + /* speak HTTP 1.0 - no chunked! */ + easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); + } result = curl_easy_perform(curl); diff --git a/vendor/curl/tests/libtest/lib1515.c b/vendor/curl/tests/libtest/lib1515.c index 6c07c7901b2..02c3c99bf80 100644 --- a/vendor/curl/tests/libtest/lib1515.c +++ b/vendor/curl/tests/libtest/lib1515.c @@ -28,17 +28,14 @@ * (test1515) nor a dead connection is detected (test1616). */ -#include "test.h" +#include "first.h" + #include "testtrace.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - #define DNS_TIMEOUT 1L -static CURLcode do_one_request(CURLM *m, char *URL, char *resolve) +static CURLcode do_one_request(CURLM *m, const char *URL, const char *resolve) { CURL *curls; struct curl_slist *resolve_list = NULL; @@ -55,9 +52,9 @@ static CURLcode do_one_request(CURLM *m, char *URL, char *resolve) easy_setopt(curls, CURLOPT_RESOLVE, resolve_list); easy_setopt(curls, CURLOPT_DNS_CACHE_TIMEOUT, DNS_TIMEOUT); - libtest_debug_config.nohex = 1; - libtest_debug_config.tracetime = 1; - easy_setopt(curls, CURLOPT_DEBUGDATA, &libtest_debug_config); + debug_config.nohex = TRUE; + debug_config.tracetime = TRUE; + easy_setopt(curls, CURLOPT_DEBUGDATA, &debug_config); easy_setopt(curls, CURLOPT_DEBUGFUNCTION, libtest_debug_cb); easy_setopt(curls, CURLOPT_VERBOSE, 1L); @@ -103,13 +100,13 @@ static CURLcode do_one_request(CURLM *m, char *URL, char *resolve) return res; } -CURLcode test(char *URL) +static CURLcode test_lib1515(const char *URL) { CURLM *multi = NULL; CURLcode res = CURLE_OK; - char *address = libtest_arg2; - char *port = libtest_arg3; - char *path = URL; + const char *path = URL; + const char *address = libtest_arg2; + const char *port = libtest_arg3; char dns_entry[256]; int i; int count = 2; @@ -136,7 +133,7 @@ CURLcode test(char *URL) } if(i < count) - sleep(DNS_TIMEOUT + 1); + curlx_wait_ms((DNS_TIMEOUT + 1) * 1000); } test_cleanup: diff --git a/vendor/curl/tests/libtest/lib1517.c b/vendor/curl/tests/libtest/lib1517.c index 3ae6c03c4d7..c542aad032d 100644 --- a/vendor/curl/tests/libtest/lib1517.c +++ b/vendor/curl/tests/libtest/lib1517.c @@ -21,25 +21,23 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -static char testdata[]="this is what we post to the silly web server\n"; - -struct WriteThis { - char *readptr; +struct t1517_WriteThis { + const char *readptr; size_t sizeleft; }; -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) +static size_t t1517_read_cb(char *ptr, size_t size, size_t nmemb, void *userp) { - struct WriteThis *pooh = (struct WriteThis *)userp; + struct t1517_WriteThis *pooh = (struct t1517_WriteThis *)userp; size_t tocopy = size * nmemb; /* Wait one second before return POST data * * so libcurl will wait before sending request body */ - wait_ms(1000); + curlx_wait_ms(1000); if(tocopy < 1 || !pooh->sizeleft) return 0; @@ -53,12 +51,15 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) return tocopy; } -CURLcode test(char *URL) +static CURLcode test_lib1517(const char *URL) { + static const char testdata[] = + "this is what we post to the silly web server\n"; + CURL *curl; CURLcode res = CURLE_OK; - struct WriteThis pooh; + struct t1517_WriteThis pooh; if(!strcmp(URL, "check")) { #if (defined(_WIN32) || defined(__CYGWIN__)) @@ -96,7 +97,7 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)pooh.sizeleft); /* we want to use our own read function */ - test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + test_setopt(curl, CURLOPT_READFUNCTION, t1517_read_cb); /* pointer to pass to our read function */ test_setopt(curl, CURLOPT_READDATA, &pooh); diff --git a/vendor/curl/tests/libtest/lib1518.c b/vendor/curl/tests/libtest/lib1518.c index 928462e0a04..63e861910dd 100644 --- a/vendor/curl/tests/libtest/lib1518.c +++ b/vendor/curl/tests/libtest/lib1518.c @@ -21,14 +21,14 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" /* Test inspired by github issue 3340 */ -static size_t writecb(char *buffer, size_t size, size_t nitems, - void *outstream) +static size_t t1518_write_cb(char *buffer, size_t size, size_t nitems, + void *outstream) { (void)buffer; (void)size; @@ -37,7 +37,7 @@ static size_t writecb(char *buffer, size_t size, size_t nitems, return 0; } -CURLcode test(char *URL) +static CURLcode test_lib1518(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; @@ -45,18 +45,15 @@ CURLcode test(char *URL) long curlRedirectCount; char *effectiveUrl = NULL; char *redirectUrl = NULL; -#ifdef LIB1543 CURLU *urlu = NULL; -#endif curl = curl_easy_init(); if(!curl) { curl_mfprintf(stderr, "curl_easy_init() failed\n"); curl_global_cleanup(); return TEST_ERR_MAJOR_BAD; } -#ifdef LIB1543 - /* set CURLOPT_URLU */ - { + if(testnum == 1543) { + /* set CURLOPT_URLU */ CURLUcode rc = CURLUE_OK; urlu = curl_url(); if(urlu) @@ -65,14 +62,13 @@ CURLcode test(char *URL) goto test_cleanup; } test_setopt(curl, CURLOPT_CURLU, urlu); + test_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + } + else { + test_setopt(curl, CURLOPT_URL, URL); + /* just to make it explicit and visible in this test: */ + test_setopt(curl, CURLOPT_FOLLOWLOCATION, 0L); } - test_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); -#else - test_setopt(curl, CURLOPT_URL, URL); - /* just to make it explicit and visible in this test: */ - test_setopt(curl, CURLOPT_FOLLOWLOCATION, 0L); -#endif - /* Perform the request, res will get the return code */ res = curl_easy_perform(curl); @@ -83,7 +79,7 @@ CURLcode test(char *URL) curl_easy_getinfo(curl, CURLINFO_REDIRECT_COUNT, &curlRedirectCount); curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &effectiveUrl); curl_easy_getinfo(curl, CURLINFO_REDIRECT_URL, &redirectUrl); - test_setopt(curl, CURLOPT_WRITEFUNCTION, writecb); + test_setopt(curl, CURLOPT_WRITEFUNCTION, t1518_write_cb); curl_mprintf("res %d\n" "status %ld\n" @@ -101,8 +97,6 @@ CURLcode test(char *URL) /* always cleanup */ curl_easy_cleanup(curl); curl_global_cleanup(); -#ifdef LIB1543 curl_url_cleanup(urlu); -#endif return res; } diff --git a/vendor/curl/tests/libtest/lib1520.c b/vendor/curl/tests/libtest/lib1520.c index f9070945cae..e61727eadc2 100644 --- a/vendor/curl/tests/libtest/lib1520.c +++ b/vendor/curl/tests/libtest/lib1520.c @@ -21,36 +21,30 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -/* - * This is the list of basic details you need to tweak to get things right. - */ -#define TO "" -#define FROM "" - -static const char *payload_text[] = { - "From: different\r\n", - "To: another\r\n", - "\r\n", - "\r\n", - ".\r\n", - ".\r\n", - "\r\n", - ".\r\n", - "\r\n", - "body", - NULL -}; - struct upload_status { int lines_read; }; -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) +static size_t t1520_read_cb(char *ptr, size_t size, size_t nmemb, void *userp) { + static const char *payload_text[] = { + "From: different\r\n", + "To: another\r\n", + "\r\n", + "\r\n", + ".\r\n", + ".\r\n", + "\r\n", + ".\r\n", + "\r\n", + "body", + NULL + }; + struct upload_status *upload_ctx = (struct upload_status *)userp; const char *data; @@ -71,7 +65,7 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) return 0; } -CURLcode test(char *URL) +static CURLcode test_lib1520(const char *URL) { CURLcode res; CURL *curl; @@ -90,16 +84,16 @@ CURLcode test(char *URL) return TEST_ERR_MAJOR_BAD; } - rcpt_list = curl_slist_append(rcpt_list, TO); - /* more addresses can be added here - rcpt_list = curl_slist_append(rcpt_list, ""); - */ - + rcpt_list = curl_slist_append(rcpt_list, ""); +#if 0 + /* more addresses can be added here */ + rcpt_list = curl_slist_append(rcpt_list, ""); +#endif test_setopt(curl, CURLOPT_URL, URL); test_setopt(curl, CURLOPT_UPLOAD, 1L); - test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + test_setopt(curl, CURLOPT_READFUNCTION, t1520_read_cb); test_setopt(curl, CURLOPT_READDATA, &upload_ctx); - test_setopt(curl, CURLOPT_MAIL_FROM, FROM); + test_setopt(curl, CURLOPT_MAIL_FROM, ""); test_setopt(curl, CURLOPT_MAIL_RCPT, rcpt_list); test_setopt(curl, CURLOPT_VERBOSE, 1L); diff --git a/vendor/curl/tests/libtest/lib1522.c b/vendor/curl/tests/libtest/lib1522.c index 1c0d945293f..3423f4777c9 100644 --- a/vendor/curl/tests/libtest/lib1522.c +++ b/vendor/curl/tests/libtest/lib1522.c @@ -21,24 +21,20 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" /* test case and code based on https://github.com/curl/curl/issues/2847 */ #include "testtrace.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -static char g_Data[40 * 1024]; /* POST 40KB */ - static int sockopt_callback(void *clientp, curl_socket_t curlfd, curlsocktype purpose) { #if defined(SOL_SOCKET) && defined(SO_SNDBUF) int sndbufsize = 4 * 1024; /* 4KB send buffer */ - (void) clientp; - (void) purpose; + (void)clientp; + (void)purpose; setsockopt(curlfd, SOL_SOCKET, SO_SNDBUF, (char *)&sndbufsize, sizeof(sndbufsize)); #else @@ -49,8 +45,10 @@ static int sockopt_callback(void *clientp, curl_socket_t curlfd, return CURL_SOCKOPT_OK; } -CURLcode test(char *URL) +static CURLcode test_lib1522(const char *URL) { + static char g_Data[40 * 1024]; /* POST 40KB */ + CURLcode code = TEST_ERR_MAJOR_BAD; CURLcode res; struct curl_slist *pHeaderList = NULL; @@ -62,9 +60,9 @@ CURLcode test(char *URL) curl_easy_setopt(curl, CURLOPT_POSTFIELDS, g_Data); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)sizeof(g_Data)); - libtest_debug_config.nohex = 1; - libtest_debug_config.tracetime = 1; - test_setopt(curl, CURLOPT_DEBUGDATA, &libtest_debug_config); + debug_config.nohex = TRUE; + debug_config.tracetime = TRUE; + test_setopt(curl, CURLOPT_DEBUGDATA, &debug_config); test_setopt(curl, CURLOPT_DEBUGFUNCTION, libtest_debug_cb); test_setopt(curl, CURLOPT_VERBOSE, 1L); @@ -79,14 +77,14 @@ CURLcode test(char *URL) curl_off_t uploadSize; curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD_T, &uploadSize); - curl_mprintf("uploadSize = %ld\n", (long)uploadSize); + curl_mprintf("uploadSize = %" CURL_FORMAT_CURL_OFF_T "\n", uploadSize); if((size_t) uploadSize == sizeof(g_Data)) { curl_mprintf("!!!!!!!!!! PASS\n"); } else { - curl_mprintf("sent %d, libcurl says %d\n", - (int)sizeof(g_Data), (int)uploadSize); + curl_mprintf("sent %zu, libcurl says %" CURL_FORMAT_CURL_OFF_T "\n", + sizeof(g_Data), uploadSize); } } else { diff --git a/vendor/curl/tests/libtest/lib1523.c b/vendor/curl/tests/libtest/lib1523.c index 80e01aea6df..77767b20bec 100644 --- a/vendor/curl/tests/libtest/lib1523.c +++ b/vendor/curl/tests/libtest/lib1523.c @@ -21,12 +21,10 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" /* test case and code based on https://github.com/curl/curl/issues/3927 */ -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" static int dload_progress_cb(void *a, curl_off_t b, curl_off_t c, @@ -40,7 +38,7 @@ static int dload_progress_cb(void *a, curl_off_t b, curl_off_t c, return 0; } -static size_t write_cb(char *d, size_t n, size_t l, void *p) +static size_t t1523_write_cb(char *d, size_t n, size_t l, void *p) { /* take care of the data here, ignored in this example */ (void)d; @@ -55,7 +53,7 @@ static CURLcode run(CURL *hnd, long limit, long time) return curl_easy_perform(hnd); } -CURLcode test(char *URL) +static CURLcode test_lib1523(const char *URL) { CURLcode ret; CURL *hnd; @@ -63,7 +61,7 @@ CURLcode test(char *URL) curl_global_init(CURL_GLOBAL_ALL); hnd = curl_easy_init(); curl_easy_setopt(hnd, CURLOPT_URL, URL); - curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, write_cb); + curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, t1523_write_cb); curl_easy_setopt(hnd, CURLOPT_ERRORBUFFER, buffer); curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 0L); curl_easy_setopt(hnd, CURLOPT_XFERINFOFUNCTION, dload_progress_cb); diff --git a/vendor/curl/tests/libtest/lib1525.c b/vendor/curl/tests/libtest/lib1525.c index 481384320f7..7e7d98ef799 100644 --- a/vendor/curl/tests/libtest/lib1525.c +++ b/vendor/curl/tests/libtest/lib1525.c @@ -28,25 +28,24 @@ * from server http header */ -#include "test.h" +#include "first.h" #include "memdebug.h" -static char testdata[] = "Hello Cloud!\n"; +static const char t1525_testdata[] = "Hello Cloud!\n"; -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *stream) +static size_t t1525_read_cb(char *ptr, size_t size, size_t nmemb, void *stream) { size_t amount = nmemb * size; /* Total bytes curl wants */ - if(amount < strlen(testdata)) { - return strlen(testdata); + if(amount < strlen(t1525_testdata)) { + return strlen(t1525_testdata); } (void)stream; - memcpy(ptr, testdata, strlen(testdata)); - return strlen(testdata); + memcpy(ptr, t1525_testdata, strlen(t1525_testdata)); + return strlen(t1525_testdata); } - -CURLcode test(char *URL) +static CURLcode test_lib1525(const char *URL) { CURL *curl = NULL; CURLcode res = CURLE_FAILED_INIT; @@ -75,16 +74,16 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_PROXY, libtest_arg2); test_setopt(curl, CURLOPT_HTTPHEADER, hhl); test_setopt(curl, CURLOPT_PROXYHEADER, hhl); - test_setopt(curl, CURLOPT_HEADEROPT, (long)CURLHEADER_UNIFIED); + test_setopt(curl, CURLOPT_HEADEROPT, CURLHEADER_UNIFIED); test_setopt(curl, CURLOPT_POST, 0L); test_setopt(curl, CURLOPT_UPLOAD, 1L); test_setopt(curl, CURLOPT_VERBOSE, 1L); - test_setopt(curl, CURLOPT_PROXYTYPE, (long)CURLPROXY_HTTP); + test_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); test_setopt(curl, CURLOPT_HEADER, 1L); test_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite); - test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + test_setopt(curl, CURLOPT_READFUNCTION, t1525_read_cb); test_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1L); - test_setopt(curl, CURLOPT_INFILESIZE, (long)strlen(testdata)); + test_setopt(curl, CURLOPT_INFILESIZE, (long)strlen(t1525_testdata)); res = curl_easy_perform(curl); diff --git a/vendor/curl/tests/libtest/lib1526.c b/vendor/curl/tests/libtest/lib1526.c index cf6ca1e4297..bf2a07ee9df 100644 --- a/vendor/curl/tests/libtest/lib1526.c +++ b/vendor/curl/tests/libtest/lib1526.c @@ -27,24 +27,24 @@ * from server http header */ -#include "test.h" +#include "first.h" #include "memdebug.h" -static char testdata[] = "Hello Cloud!\n"; +static const char t1526_testdata[] = "Hello Cloud!\n"; -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *stream) +static size_t t1526_read_cb(char *ptr, size_t size, size_t nmemb, void *stream) { size_t amount = nmemb * size; /* Total bytes curl wants */ - if(amount < strlen(testdata)) { - return strlen(testdata); + if(amount < strlen(t1526_testdata)) { + return strlen(t1526_testdata); } (void)stream; - memcpy(ptr, testdata, strlen(testdata)); - return strlen(testdata); + memcpy(ptr, t1526_testdata, strlen(t1526_testdata)); + return strlen(t1526_testdata); } -CURLcode test(char *URL) +static CURLcode test_lib1526(const char *URL) { CURL *curl = NULL; CURLcode res = CURLE_FAILED_INIT; @@ -78,16 +78,16 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_PROXY, libtest_arg2); test_setopt(curl, CURLOPT_HTTPHEADER, hhl); test_setopt(curl, CURLOPT_PROXYHEADER, phl); - test_setopt(curl, CURLOPT_HEADEROPT, (long)CURLHEADER_SEPARATE); + test_setopt(curl, CURLOPT_HEADEROPT, CURLHEADER_SEPARATE); test_setopt(curl, CURLOPT_POST, 0L); test_setopt(curl, CURLOPT_UPLOAD, 1L); test_setopt(curl, CURLOPT_VERBOSE, 1L); - test_setopt(curl, CURLOPT_PROXYTYPE, (long)CURLPROXY_HTTP); + test_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); test_setopt(curl, CURLOPT_HEADER, 1L); test_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite); - test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + test_setopt(curl, CURLOPT_READFUNCTION, t1526_read_cb); test_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1L); - test_setopt(curl, CURLOPT_INFILESIZE, (long)strlen(testdata)); + test_setopt(curl, CURLOPT_INFILESIZE, (long)strlen(t1526_testdata)); res = curl_easy_perform(curl); diff --git a/vendor/curl/tests/libtest/lib1527.c b/vendor/curl/tests/libtest/lib1527.c index aa5aa286ab3..36247286879 100644 --- a/vendor/curl/tests/libtest/lib1527.c +++ b/vendor/curl/tests/libtest/lib1527.c @@ -27,25 +27,24 @@ * for server and proxy */ -#include "test.h" +#include "first.h" #include "memdebug.h" -static char testdata[] = "Hello Cloud!\n"; +static const char t1527_testdata[] = "Hello Cloud!\n"; -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *stream) +static size_t t1527_read_cb(char *ptr, size_t size, size_t nmemb, void *stream) { size_t amount = nmemb * size; /* Total bytes curl wants */ - if(amount < strlen(testdata)) { - return strlen(testdata); + if(amount < strlen(t1527_testdata)) { + return strlen(t1527_testdata); } (void)stream; - memcpy(ptr, testdata, strlen(testdata)); - return strlen(testdata); + memcpy(ptr, t1527_testdata, strlen(t1527_testdata)); + return strlen(t1527_testdata); } - -CURLcode test(char *URL) +static CURLcode test_lib1527(const char *URL) { CURL *curl = NULL; CURLcode res = CURLE_FAILED_INIT; @@ -80,13 +79,13 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_POST, 0L); test_setopt(curl, CURLOPT_UPLOAD, 1L); test_setopt(curl, CURLOPT_VERBOSE, 1L); - test_setopt(curl, CURLOPT_PROXYTYPE, (long)CURLPROXY_HTTP); + test_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); test_setopt(curl, CURLOPT_HEADER, 1L); test_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite); - test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + test_setopt(curl, CURLOPT_READFUNCTION, t1527_read_cb); test_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1L); - test_setopt(curl, CURLOPT_INFILESIZE, (long)strlen(testdata)); - test_setopt(curl, CURLOPT_HEADEROPT, (long)CURLHEADER_UNIFIED); + test_setopt(curl, CURLOPT_INFILESIZE, (long)strlen(t1527_testdata)); + test_setopt(curl, CURLOPT_HEADEROPT, CURLHEADER_UNIFIED); res = curl_easy_perform(curl); diff --git a/vendor/curl/tests/libtest/lib1528.c b/vendor/curl/tests/libtest/lib1528.c index 7cc21c7b092..98bd2bdaf18 100644 --- a/vendor/curl/tests/libtest/lib1528.c +++ b/vendor/curl/tests/libtest/lib1528.c @@ -21,12 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ - -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1528(const char *URL) { CURL *curl = NULL; CURLcode res = CURLE_FAILED_INIT; @@ -57,9 +56,9 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_PROXY, libtest_arg2); test_setopt(curl, CURLOPT_HTTPHEADER, hhl); test_setopt(curl, CURLOPT_PROXYHEADER, phl); - test_setopt(curl, CURLOPT_HEADEROPT, (long)CURLHEADER_SEPARATE); + test_setopt(curl, CURLOPT_HEADEROPT, CURLHEADER_SEPARATE); test_setopt(curl, CURLOPT_VERBOSE, 1L); - test_setopt(curl, CURLOPT_PROXYTYPE, (long)CURLPROXY_HTTP); + test_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); test_setopt(curl, CURLOPT_HEADER, 1L); res = curl_easy_perform(curl); diff --git a/vendor/curl/tests/libtest/lib1529.c b/vendor/curl/tests/libtest/lib1529.c index fb11ab16526..ae86b61a5e6 100644 --- a/vendor/curl/tests/libtest/lib1529.c +++ b/vendor/curl/tests/libtest/lib1529.c @@ -21,12 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ - -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1529(const char *URL) { CURL *curl = NULL; CURLcode res = CURLE_FAILED_INIT; @@ -49,7 +48,7 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_URL, bURL); test_setopt(curl, CURLOPT_PROXY, libtest_arg2); test_setopt(curl, CURLOPT_VERBOSE, 1L); - test_setopt(curl, CURLOPT_PROXYTYPE, (long)CURLPROXY_HTTP); + test_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); test_setopt(curl, CURLOPT_HEADER, 1L); res = curl_easy_perform(curl); diff --git a/vendor/curl/tests/libtest/lib1530.c b/vendor/curl/tests/libtest/lib1530.c index bb725eea66a..19b0d9cbde3 100644 --- a/vendor/curl/tests/libtest/lib1530.c +++ b/vendor/curl/tests/libtest/lib1530.c @@ -21,8 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ - -#include "test.h" +#include "first.h" #include "memdebug.h" @@ -37,7 +36,7 @@ static curl_socket_t opensocket(void *clientp, return CURL_SOCKET_BAD; } -CURLcode test(char *URL) +static CURLcode test_lib1530(const char *URL) { CURL *curl = NULL; CURLcode res = CURLE_FAILED_INIT; diff --git a/vendor/curl/tests/libtest/lib1531.c b/vendor/curl/tests/libtest/lib1531.c index 1155296fccb..9d4cd775399 100644 --- a/vendor/curl/tests/libtest/lib1531.c +++ b/vendor/curl/tests/libtest/lib1531.c @@ -21,20 +21,15 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "timediff.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -static char const testData[] = ".abc\0xyz"; -static curl_off_t const testDataSize = sizeof(testData) - 1; - -CURLcode test(char *URL) +static CURLcode test_lib1531(const char *URL) { + static char const testData[] = ".abc\0xyz"; + static curl_off_t const testDataSize = sizeof(testData) - 1; + CURL *easy; CURLM *multi_handle; int still_running; /* keep number of running handles */ @@ -109,15 +104,7 @@ CURLcode test(char *URL) curl_multi_fdset() doc. */ if(maxfd == -1) { -#ifdef _WIN32 - Sleep(100); - rc = 0; -#else - /* Portable sleep for platforms other than Windows. */ - struct timeval wait = {0}; - wait.tv_usec = 100 * 1000; /* 100ms */ - rc = select(0, NULL, NULL, NULL, &wait); -#endif + rc = curlx_wait_ms(100); } else { /* Note that on some platforms 'timeout' may be modified by select(). diff --git a/vendor/curl/tests/libtest/lib1532.c b/vendor/curl/tests/libtest/lib1532.c index c9fd4e66bc5..83a826de32d 100644 --- a/vendor/curl/tests/libtest/lib1532.c +++ b/vendor/curl/tests/libtest/lib1532.c @@ -21,13 +21,13 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" /* Test CURLINFO_RESPONSE_CODE */ -CURLcode test(char *URL) +static CURLcode test_lib1532(const char *URL) { CURL *curl; long httpcode; diff --git a/vendor/curl/tests/libtest/lib1533.c b/vendor/curl/tests/libtest/lib1533.c index 68fdb2b6d2b..15256deaf06 100644 --- a/vendor/curl/tests/libtest/lib1533.c +++ b/vendor/curl/tests/libtest/lib1533.c @@ -29,7 +29,7 @@ * because this implies that the data has been sent completely to the server. */ -#include "test.h" +#include "first.h" #include "memdebug.h" @@ -40,7 +40,6 @@ struct cb_data { size_t remaining_bytes; }; - static void reset_data(struct cb_data *data, CURL *curl) { data->easy_handle = curl; @@ -49,11 +48,9 @@ static void reset_data(struct cb_data *data, CURL *curl) data->remaining_bytes = 3; } - -static size_t read_callback(char *ptr, size_t size, size_t nitems, - void *userdata) +static size_t t1533_read_cb(char *ptr, size_t size, size_t nitems, void *userp) { - struct cb_data *data = (struct cb_data *)userdata; + struct cb_data *data = (struct cb_data *)userp; /* wait until the server has sent all response headers */ if(data->response_received) { @@ -75,11 +72,9 @@ static size_t read_callback(char *ptr, size_t size, size_t nitems, } } - -static size_t write_callback(char *ptr, size_t size, size_t nmemb, - void *userdata) +static size_t t1533_write_cb(char *ptr, size_t size, size_t nmemb, void *userp) { - struct cb_data *data = (struct cb_data *)userdata; + struct cb_data *data = (struct cb_data *)userp; size_t totalsize = nmemb * size; /* unused parameter */ @@ -97,7 +92,6 @@ static size_t write_callback(char *ptr, size_t size, size_t nmemb, return totalsize; } - static CURLcode perform_and_check_connections(CURL *curl, const char *description, long expected_connections) @@ -129,7 +123,7 @@ static CURLcode perform_and_check_connections(CURL *curl, } -CURLcode test(char *URL) +static CURLcode test_lib1533(const char *URL) { struct cb_data data; CURL *curl = NULL; @@ -155,9 +149,9 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)data.remaining_bytes); test_setopt(curl, CURLOPT_VERBOSE, 1L); - test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + test_setopt(curl, CURLOPT_READFUNCTION, t1533_read_cb); test_setopt(curl, CURLOPT_READDATA, &data); - test_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + test_setopt(curl, CURLOPT_WRITEFUNCTION, t1533_write_cb); test_setopt(curl, CURLOPT_WRITEDATA, &data); result = perform_and_check_connections(curl, diff --git a/vendor/curl/tests/libtest/lib1534.c b/vendor/curl/tests/libtest/lib1534.c index 467691c032e..af1c0bd5202 100644 --- a/vendor/curl/tests/libtest/lib1534.c +++ b/vendor/curl/tests/libtest/lib1534.c @@ -21,13 +21,13 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" /* Test CURLINFO_FILETIME */ -CURLcode test(char *URL) +static CURLcode test_lib1534(const char *URL) { CURL *curl, *dupe = NULL; long filetime; @@ -110,7 +110,6 @@ CURLcode test(char *URL) goto test_cleanup; } - /* Test that a filetime is properly initialized on curl_easy_reset. */ diff --git a/vendor/curl/tests/libtest/lib1535.c b/vendor/curl/tests/libtest/lib1535.c index f999427fd62..c0e0689d98b 100644 --- a/vendor/curl/tests/libtest/lib1535.c +++ b/vendor/curl/tests/libtest/lib1535.c @@ -21,13 +21,13 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" /* Test CURLINFO_PROTOCOL */ -CURLcode test(char *URL) +static CURLcode test_lib1535(const char *URL) { CURL *curl, *dupe = NULL; long protocol; @@ -80,7 +80,7 @@ CURLcode test(char *URL) if(protocol != CURLPROTO_HTTP) { curl_mfprintf(stderr, "%s:%d protocol of http resource is incorrect; " - "expected %d but is %ld\n", + "expected %ld but is %ld\n", __FILE__, __LINE__, CURLPROTO_HTTP, protocol); res = CURLE_HTTP_RETURNED_ERROR; goto test_cleanup; @@ -113,7 +113,6 @@ CURLcode test(char *URL) goto test_cleanup; } - /* Test that a protocol is properly initialized on curl_easy_reset. */ diff --git a/vendor/curl/tests/libtest/lib1536.c b/vendor/curl/tests/libtest/lib1536.c index fea7e1acf6a..3219724b9ae 100644 --- a/vendor/curl/tests/libtest/lib1536.c +++ b/vendor/curl/tests/libtest/lib1536.c @@ -21,13 +21,13 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" /* Test CURLINFO_SCHEME */ -CURLcode test(char *URL) +static CURLcode test_lib1536(const char *URL) { CURL *curl, *dupe = NULL; char *scheme; @@ -109,7 +109,6 @@ CURLcode test(char *URL) goto test_cleanup; } - /* Test that a scheme is properly initialized on curl_easy_reset. */ diff --git a/vendor/curl/tests/libtest/lib1537.c b/vendor/curl/tests/libtest/lib1537.c index 88f99bc60eb..52272cb2ec9 100644 --- a/vendor/curl/tests/libtest/lib1537.c +++ b/vendor/curl/tests/libtest/lib1537.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1537(const char *URL) { const unsigned char a[] = {0x2f, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x91, 0xa2, 0xb3, 0xc4, 0xd5, 0xe6, 0xf7}; diff --git a/vendor/curl/tests/libtest/lib1538.c b/vendor/curl/tests/libtest/lib1538.c index e5dcec1f49b..9aaec8171a1 100644 --- a/vendor/curl/tests/libtest/lib1538.c +++ b/vendor/curl/tests/libtest/lib1538.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1538(const char *URL) { CURLcode res = CURLE_OK; CURLcode easyret; @@ -45,17 +45,17 @@ CURLcode test(char *URL) curl_url_strerror((CURLUcode)-INT_MAX); /* NOLINTEND(clang-analyzer-optin.core.EnumCastOutOfRange) */ for(easyret = CURLE_OK; easyret <= CURL_LAST; easyret++) { - curl_mprintf("e%d: %s\n", (int)easyret, curl_easy_strerror(easyret)); + curl_mprintf("e%d: %s\n", easyret, curl_easy_strerror(easyret)); } for(multiret = CURLM_CALL_MULTI_PERFORM; multiret <= CURLM_LAST; multiret++) { - curl_mprintf("m%d: %s\n", (int)multiret, curl_multi_strerror(multiret)); + curl_mprintf("m%d: %s\n", multiret, curl_multi_strerror(multiret)); } for(shareret = CURLSHE_OK; shareret <= CURLSHE_LAST; shareret++) { - curl_mprintf("s%d: %s\n", (int)shareret, curl_share_strerror(shareret)); + curl_mprintf("s%d: %s\n", shareret, curl_share_strerror(shareret)); } for(urlret = CURLUE_OK; urlret <= CURLUE_LAST; urlret++) { - curl_mprintf("u%d: %s\n", (int)urlret, curl_url_strerror(urlret)); + curl_mprintf("u%d: %s\n", urlret, curl_url_strerror(urlret)); } return res; diff --git a/vendor/curl/tests/libtest/lib1540.c b/vendor/curl/tests/libtest/lib1540.c index aad97d2af2b..55195b6ba83 100644 --- a/vendor/curl/tests/libtest/lib1540.c +++ b/vendor/curl/tests/libtest/lib1540.c @@ -21,14 +21,12 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "testtrace.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -struct transfer_status { +struct t1540_transfer_status { CURL *easy; int halted; int counter; /* count write callback invokes */ @@ -41,7 +39,7 @@ static int please_continue(void *userp, curl_off_t ultotal, curl_off_t ulnow) { - struct transfer_status *st = (struct transfer_status *)userp; + struct t1540_transfer_status *st = (struct t1540_transfer_status *)userp; (void)dltotal; (void)dlnow; (void)ultotal; @@ -57,8 +55,8 @@ static int please_continue(void *userp, return 0; /* go on */ } -static size_t header_callback(char *ptr, size_t size, size_t nmemb, - void *userp) +static size_t t1540_header_callback(char *ptr, size_t size, size_t nmemb, + void *userp) { size_t len = size * nmemb; (void)userp; @@ -66,9 +64,9 @@ static size_t header_callback(char *ptr, size_t size, size_t nmemb, return len; } -static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userp) +static size_t t1540_write_cb(char *ptr, size_t size, size_t nmemb, void *userp) { - struct transfer_status *st = (struct transfer_status *)userp; + struct t1540_transfer_status *st = (struct t1540_transfer_status *)userp; size_t len = size * nmemb; st->counter++; if(st->counter > 1) { @@ -83,11 +81,11 @@ static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userp) return CURL_WRITEFUNC_PAUSE; } -CURLcode test(char *URL) +static CURLcode test_lib1540(const char *URL) { CURL *curls = NULL; CURLcode res = CURLE_OK; - struct transfer_status st; + struct t1540_transfer_status st; start_test_timing(); @@ -99,18 +97,18 @@ CURLcode test(char *URL) st.easy = curls; /* to allow callbacks access */ easy_setopt(curls, CURLOPT_URL, URL); - easy_setopt(curls, CURLOPT_WRITEFUNCTION, write_callback); + easy_setopt(curls, CURLOPT_WRITEFUNCTION, t1540_write_cb); easy_setopt(curls, CURLOPT_WRITEDATA, &st); - easy_setopt(curls, CURLOPT_HEADERFUNCTION, header_callback); + easy_setopt(curls, CURLOPT_HEADERFUNCTION, t1540_header_callback); easy_setopt(curls, CURLOPT_HEADERDATA, &st); easy_setopt(curls, CURLOPT_XFERINFOFUNCTION, please_continue); easy_setopt(curls, CURLOPT_XFERINFODATA, &st); easy_setopt(curls, CURLOPT_NOPROGRESS, 0L); - libtest_debug_config.nohex = 1; - libtest_debug_config.tracetime = 1; - test_setopt(curls, CURLOPT_DEBUGDATA, &libtest_debug_config); + debug_config.nohex = TRUE; + debug_config.tracetime = TRUE; + test_setopt(curls, CURLOPT_DEBUGDATA, &debug_config); easy_setopt(curls, CURLOPT_DEBUGFUNCTION, libtest_debug_cb); easy_setopt(curls, CURLOPT_VERBOSE, 1L); diff --git a/vendor/curl/tests/libtest/lib1541.c b/vendor/curl/tests/libtest/lib1541.c index d09e0e66e7e..9e7b2d43652 100644 --- a/vendor/curl/tests/libtest/lib1541.c +++ b/vendor/curl/tests/libtest/lib1541.c @@ -21,13 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -struct transfer_status { +struct t1541_transfer_status { CURL *easy; int hd_count; int bd_count; @@ -36,11 +34,10 @@ struct transfer_status { #define KN(a) a, #a -static int geterr(const char *name, CURLcode val, int lineno) +static void t1541_geterr(const char *name, CURLcode val, int lineno) { curl_mprintf("CURLINFO_%s returned %d, \"%s\" on line %d\n", name, val, curl_easy_strerror(val), lineno); - return (int)val; } static void report_time(const char *key, const char *where, curl_off_t time, @@ -59,7 +56,7 @@ static void check_time(CURL *easy, int key, const char *name, curl_off_t tval; CURLcode res = curl_easy_getinfo(easy, (CURLINFO)key, &tval); if(res) { - geterr(name, res, __LINE__); + t1541_geterr(name, res, __LINE__); } else report_time(name, where, tval, tval > 0); @@ -71,16 +68,16 @@ static void check_time0(CURL *easy, int key, const char *name, curl_off_t tval; CURLcode res = curl_easy_getinfo(easy, (CURLINFO)key, &tval); if(res) { - geterr(name, res, __LINE__); + t1541_geterr(name, res, __LINE__); } else report_time(name, where, tval, !tval); } -static size_t header_callback(char *ptr, size_t size, size_t nmemb, - void *userp) +static size_t t1541_header_callback(char *ptr, size_t size, size_t nmemb, + void *userp) { - struct transfer_status *st = (struct transfer_status *)userp; + struct t1541_transfer_status *st = (struct t1541_transfer_status *)userp; size_t len = size * nmemb; (void)ptr; @@ -100,9 +97,9 @@ static size_t header_callback(char *ptr, size_t size, size_t nmemb, return len; } -static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userp) +static size_t t1541_write_cb(char *ptr, size_t size, size_t nmemb, void *userp) { - struct transfer_status *st = (struct transfer_status *)userp; + struct t1541_transfer_status *st = (struct t1541_transfer_status *)userp; (void)ptr; (void)st; @@ -110,11 +107,11 @@ static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userp) return size * nmemb; } -CURLcode test(char *URL) +static CURLcode test_lib1541(const char *URL) { CURL *curls = NULL; CURLcode res = CURLE_OK; - struct transfer_status st; + struct t1541_transfer_status st; start_test_timing(); @@ -126,9 +123,9 @@ CURLcode test(char *URL) st.easy = curls; /* to allow callbacks access */ easy_setopt(curls, CURLOPT_URL, URL); - easy_setopt(curls, CURLOPT_WRITEFUNCTION, write_callback); + easy_setopt(curls, CURLOPT_WRITEFUNCTION, t1541_write_cb); easy_setopt(curls, CURLOPT_WRITEDATA, &st); - easy_setopt(curls, CURLOPT_HEADERFUNCTION, header_callback); + easy_setopt(curls, CURLOPT_HEADERFUNCTION, t1541_header_callback); easy_setopt(curls, CURLOPT_HEADERDATA, &st); easy_setopt(curls, CURLOPT_NOPROGRESS, 0L); diff --git a/vendor/curl/tests/libtest/lib1542.c b/vendor/curl/tests/libtest/lib1542.c index 5a8926585d8..b8edbcb7971 100644 --- a/vendor/curl/tests/libtest/lib1542.c +++ b/vendor/curl/tests/libtest/lib1542.c @@ -30,13 +30,12 @@ * first connection and open a second. */ -#include "test.h" -#include "testutil.h" +#include "first.h" + #include "testtrace.h" -#include "warnless.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1542(const char *URL) { CURL *easy = NULL; CURLcode res = CURLE_OK; @@ -47,9 +46,9 @@ CURLcode test(char *URL) easy_setopt(easy, CURLOPT_URL, URL); - libtest_debug_config.nohex = 1; - libtest_debug_config.tracetime = 0; - easy_setopt(easy, CURLOPT_DEBUGDATA, &libtest_debug_config); + debug_config.nohex = TRUE; + debug_config.tracetime = FALSE; + easy_setopt(easy, CURLOPT_DEBUGDATA, &debug_config); easy_setopt(easy, CURLOPT_DEBUGFUNCTION, libtest_debug_cb); easy_setopt(easy, CURLOPT_VERBOSE, 1L); @@ -63,7 +62,7 @@ CURLcode test(char *URL) /* CURLOPT_MAXLIFETIME_CONN is inclusive - the connection needs to be 2 * seconds old */ - sleep(2); + curlx_wait_ms(2000); res = curl_easy_perform(easy); if(res) diff --git a/vendor/curl/tests/libtest/lib1545.c b/vendor/curl/tests/libtest/lib1545.c index d2709987e74..ac59d028c01 100644 --- a/vendor/curl/tests/libtest/lib1545.c +++ b/vendor/curl/tests/libtest/lib1545.c @@ -21,9 +21,9 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -CURLcode test(char *URL) +static CURLcode test_lib1545(const char *URL) { CURL *eh = NULL; CURLcode res = CURLE_OK; diff --git a/vendor/curl/tests/libtest/lib1550.c b/vendor/curl/tests/libtest/lib1550.c index ddc0c16ab5a..6fedbf68848 100644 --- a/vendor/curl/tests/libtest/lib1550.c +++ b/vendor/curl/tests/libtest/lib1550.c @@ -21,13 +21,13 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" #include -CURLcode test(char *URL) +static CURLcode test_lib1550(const char *URL) { CURLM *handle; CURLcode res = CURLE_OK; diff --git a/vendor/curl/tests/libtest/lib1551.c b/vendor/curl/tests/libtest/lib1551.c index 77834655ade..80020f55566 100644 --- a/vendor/curl/tests/libtest/lib1551.c +++ b/vendor/curl/tests/libtest/lib1551.c @@ -21,13 +21,13 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" #include -CURLcode test(char *URL) +static CURLcode test_lib1551(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; diff --git a/vendor/curl/tests/libtest/lib1552.c b/vendor/curl/tests/libtest/lib1552.c index b61f162ed9a..a5b23fbd8b6 100644 --- a/vendor/curl/tests/libtest/lib1552.c +++ b/vendor/curl/tests/libtest/lib1552.c @@ -21,15 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -CURLcode test(char *URL) +static CURLcode test_lib1552(const char *URL) { CURL *curls = NULL; CURLM *multi = NULL; diff --git a/vendor/curl/tests/libtest/lib1553.c b/vendor/curl/tests/libtest/lib1553.c index a1c04314ee0..5d35adac5c8 100644 --- a/vendor/curl/tests/libtest/lib1553.c +++ b/vendor/curl/tests/libtest/lib1553.c @@ -21,18 +21,14 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" #include "testtrace.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -static int xferinfo(void *p, - curl_off_t dltotal, curl_off_t dlnow, - curl_off_t ultotal, curl_off_t ulnow) +static int t1553_xferinfo(void *p, + curl_off_t dltotal, curl_off_t dlnow, + curl_off_t ultotal, curl_off_t ulnow) { (void)p; (void)dlnow; @@ -43,7 +39,7 @@ static int xferinfo(void *p, return 1; /* fail as fast as we can */ } -CURLcode test(char *URL) +static CURLcode test_lib1553(const char *URL) { CURL *curls = NULL; CURLM *multi = NULL; @@ -72,12 +68,12 @@ CURLcode test(char *URL) easy_setopt(curls, CURLOPT_VERBOSE, 1L); easy_setopt(curls, CURLOPT_MIMEPOST, mime); easy_setopt(curls, CURLOPT_USERPWD, "u:s"); - easy_setopt(curls, CURLOPT_XFERINFOFUNCTION, xferinfo); + easy_setopt(curls, CURLOPT_XFERINFOFUNCTION, t1553_xferinfo); easy_setopt(curls, CURLOPT_NOPROGRESS, 1L); - libtest_debug_config.nohex = 1; - libtest_debug_config.tracetime = 1; - test_setopt(curls, CURLOPT_DEBUGDATA, &libtest_debug_config); + debug_config.nohex = TRUE; + debug_config.tracetime = TRUE; + test_setopt(curls, CURLOPT_DEBUGDATA, &debug_config); easy_setopt(curls, CURLOPT_DEBUGFUNCTION, libtest_debug_cb); easy_setopt(curls, CURLOPT_VERBOSE, 1L); diff --git a/vendor/curl/tests/libtest/lib1554.c b/vendor/curl/tests/libtest/lib1554.c index 4fc408f609f..240fea65779 100644 --- a/vendor/curl/tests/libtest/lib1554.c +++ b/vendor/curl/tests/libtest/lib1554.c @@ -21,7 +21,8 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" + #include "memdebug.h" static const char *ldata_names[] = { @@ -36,8 +37,8 @@ static const char *ldata_names[] = { "NULL", }; -static void test_lock(CURL *handle, curl_lock_data data, - curl_lock_access laccess, void *useptr) +static void t1554_test_lock(CURL *handle, curl_lock_data data, + curl_lock_access laccess, void *useptr) { (void)handle; (void)data; @@ -46,7 +47,7 @@ static void test_lock(CURL *handle, curl_lock_data data, curl_mprintf("-> Mutex lock %s\n", ldata_names[data]); } -static void test_unlock(CURL *handle, curl_lock_data data, void *useptr) +static void t1554_test_unlock(CURL *handle, curl_lock_data data, void *useptr) { (void)handle; (void)data; @@ -55,7 +56,7 @@ static void test_unlock(CURL *handle, curl_lock_data data, void *useptr) } /* test function */ -CURLcode test(char *URL) +static CURLcode test_lib1554(const char *URL) { CURLcode res = CURLE_OK; CURLSH *share = NULL; @@ -70,8 +71,8 @@ CURLcode test(char *URL) } curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); - curl_share_setopt(share, CURLSHOPT_LOCKFUNC, test_lock); - curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, test_unlock); + curl_share_setopt(share, CURLSHOPT_LOCKFUNC, t1554_test_lock); + curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, t1554_test_unlock); /* Loop the transfer and cleanup the handle properly every lap. This will still reuse connections since the pool is in the shared object! */ diff --git a/vendor/curl/tests/libtest/lib1555.c b/vendor/curl/tests/libtest/lib1555.c index eda2328a33c..4ebde5c74c6 100644 --- a/vendor/curl/tests/libtest/lib1555.c +++ b/vendor/curl/tests/libtest/lib1555.c @@ -25,11 +25,11 @@ * Verify that some API functions are locked from being called inside callback */ -#include "test.h" +#include "first.h" #include "memdebug.h" -static CURL *curl; +static CURL *t1555_curl; static int progressCallback(void *arg, double dltotal, @@ -45,36 +45,36 @@ static int progressCallback(void *arg, (void)dlnow; (void)ultotal; (void)ulnow; - res = curl_easy_recv(curl, buffer, 256, &n); + res = curl_easy_recv(t1555_curl, buffer, 256, &n); curl_mprintf("curl_easy_recv returned %d\n", res); - res = curl_easy_send(curl, buffer, n, &n); + res = curl_easy_send(t1555_curl, buffer, n, &n); curl_mprintf("curl_easy_send returned %d\n", res); return 1; } -CURLcode test(char *URL) +static CURLcode test_lib1555(const char *URL) { CURLcode res = CURLE_OK; global_init(CURL_GLOBAL_ALL); - easy_init(curl); + easy_init(t1555_curl); - easy_setopt(curl, CURLOPT_URL, URL); - easy_setopt(curl, CURLOPT_TIMEOUT, (long)7); - easy_setopt(curl, CURLOPT_NOSIGNAL, (long)1); - easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progressCallback); - easy_setopt(curl, CURLOPT_PROGRESSDATA, NULL); - easy_setopt(curl, CURLOPT_NOPROGRESS, (long)0); + easy_setopt(t1555_curl, CURLOPT_URL, URL); + easy_setopt(t1555_curl, CURLOPT_TIMEOUT, 7L); + easy_setopt(t1555_curl, CURLOPT_NOSIGNAL, 1L); + easy_setopt(t1555_curl, CURLOPT_PROGRESSFUNCTION, progressCallback); + easy_setopt(t1555_curl, CURLOPT_PROGRESSDATA, NULL); + easy_setopt(t1555_curl, CURLOPT_NOPROGRESS, 0L); - res = curl_easy_perform(curl); + res = curl_easy_perform(t1555_curl); test_cleanup: /* undocumented cleanup sequence - type UA */ - curl_easy_cleanup(curl); + curl_easy_cleanup(t1555_curl); curl_global_cleanup(); return res; diff --git a/vendor/curl/tests/libtest/lib1556.c b/vendor/curl/tests/libtest/lib1556.c index 6bbf353e1ea..4987fc9f096 100644 --- a/vendor/curl/tests/libtest/lib1556.c +++ b/vendor/curl/tests/libtest/lib1556.c @@ -21,10 +21,8 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" struct headerinfo { @@ -44,7 +42,7 @@ static size_t header(char *ptr, size_t size, size_t nmemb, void *stream) return nmemb * size; } -CURLcode test(char *URL) +static CURLcode test_lib1556(const char *URL) { CURLcode code; CURL *curl = NULL; @@ -69,7 +67,7 @@ CURLcode test(char *URL) goto test_cleanup; } - curl_mprintf("Max = %ld\n", (long)info.largest); + curl_mprintf("Max = %zu\n", info.largest); test_cleanup: diff --git a/vendor/curl/tests/libtest/lib1557.c b/vendor/curl/tests/libtest/lib1557.c index 6f0b99ac50d..2381c07b6a1 100644 --- a/vendor/curl/tests/libtest/lib1557.c +++ b/vendor/curl/tests/libtest/lib1557.c @@ -21,13 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1557(const char *URL) { CURLM *curlm = NULL; CURL *curl1 = NULL; diff --git a/vendor/curl/tests/libtest/lib1558.c b/vendor/curl/tests/libtest/lib1558.c index 9bb18caf8e4..1bbc0f77b75 100644 --- a/vendor/curl/tests/libtest/lib1558.c +++ b/vendor/curl/tests/libtest/lib1558.c @@ -21,13 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1558(const char *URL) { CURLcode res = CURLE_OK; CURL *curl = NULL; diff --git a/vendor/curl/tests/libtest/lib1559.c b/vendor/curl/tests/libtest/lib1559.c index 19448afd8f3..1aa0f830c75 100644 --- a/vendor/curl/tests/libtest/lib1559.c +++ b/vendor/curl/tests/libtest/lib1559.c @@ -21,15 +21,14 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define EXCESSIVE 10*1000*1000 -CURLcode test(char *URL) +static CURLcode test_lib1559(const char *URL) { + static const int EXCESSIVE = 10*1000*1000; + CURLcode res = CURLE_OK; CURL *curl = NULL; char *longurl = NULL; @@ -60,13 +59,13 @@ CURLcode test(char *URL) if(u) { CURLUcode uc = curl_url_set(u, CURLUPART_URL, longurl, 0); curl_mprintf("CURLUPART_URL %d bytes URL == %d (%s)\n", - EXCESSIVE, (int)uc, curl_url_strerror(uc)); + EXCESSIVE, uc, curl_url_strerror(uc)); uc = curl_url_set(u, CURLUPART_SCHEME, longurl, CURLU_NON_SUPPORT_SCHEME); curl_mprintf("CURLUPART_SCHEME %d bytes scheme == %d (%s)\n", - EXCESSIVE, (int)uc, curl_url_strerror(uc)); + EXCESSIVE, uc, curl_url_strerror(uc)); uc = curl_url_set(u, CURLUPART_USER, longurl, 0); curl_mprintf("CURLUPART_USER %d bytes user == %d (%s)\n", - EXCESSIVE, (int)uc, curl_url_strerror(uc)); + EXCESSIVE, uc, curl_url_strerror(uc)); curl_url_cleanup(u); } diff --git a/vendor/curl/tests/libtest/lib1560.c b/vendor/curl/tests/libtest/lib1560.c index a0b9baa1bfa..99112389fec 100644 --- a/vendor/curl/tests/libtest/lib1560.c +++ b/vendor/curl/tests/libtest/lib1560.c @@ -30,21 +30,13 @@ * that this test will assume to be present! */ -#include "test.h" +#include "first.h" #if defined(USE_LIBIDN2) || defined(USE_WIN32_IDN) || defined(USE_APPLE_IDN) #define USE_IDN #endif -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" /* LAST include file */ -struct part { - CURLUPart part; - const char *name; -}; - - static int checkparts(CURLU *u, const char *in, const char *wanted, unsigned int getflags) { @@ -53,6 +45,12 @@ static int checkparts(CURLU *u, const char *in, const char *wanted, char buf[256]; char *bufp = &buf[0]; size_t len = sizeof(buf); + + struct part { + CURLUPart part; + const char *name; + }; + struct part parts[] = { {CURLUPART_SCHEME, "scheme"}, {CURLUPART_USER, "user"}, @@ -75,7 +73,7 @@ static int checkparts(CURLU *u, const char *in, const char *wanted, curl_msnprintf(bufp, len, "%s%s", buf[0]?" | ":"", p); } else - curl_msnprintf(bufp, len, "%s[%d]", buf[0]?" | ":"", (int)rc); + curl_msnprintf(bufp, len, "%s[%d]", buf[0]?" | ":"", rc); n = strlen(bufp); bufp += n; @@ -244,14 +242,14 @@ static const struct testcase get_parts_list[] ={ {"https://" "%e2%84%82%e1%b5%a4%e2%93%87%e2%84%92%e3%80%82%f0%9d%90%92%f0%9f%84%b4", "https | [11] | [12] | [13] | " - "%e2%84%82%e1%b5%a4%e2%93%87%e2%84%92%e3%80%82%f0%9d%90%92%f0%9f%84%b4 " + "%E2%84%82%E1%B5%A4%E2%93%87%E2%84%92%E3%80%82%F0%9D%90%92%F0%9F%84%B4 " "| [15] | / | [16] | [17]", 0, CURLU_URLENCODE, CURLUE_OK}, {"https://" "\xe2\x84\x82\xe1\xb5\xa4\xe2\x93\x87\xe2\x84\x92" "\xe3\x80\x82\xf0\x9d\x90\x92\xf0\x9f\x84\xb4", "https | [11] | [12] | [13] | " - "%e2%84%82%e1%b5%a4%e2%93%87%e2%84%92%e3%80%82%f0%9d%90%92%f0%9f%84%b4 " + "%E2%84%82%E1%B5%A4%E2%93%87%E2%84%92%E3%80%82%F0%9D%90%92%F0%9F%84%B4 " "| [15] | / | [16] | [17]", 0, CURLU_URLENCODE, CURLUE_OK}, {"https://user@example.net?he l lo", @@ -653,7 +651,7 @@ static const struct urltestcase get_url_list[] = { {"http://example.com%2F127.0.0.1/", "", 0, 0, CURLUE_BAD_HOSTNAME}, {"https://%41", "https://A/", 0, 0, CURLUE_OK}, {"https://%20", "", 0, 0, CURLUE_BAD_HOSTNAME}, - {"https://%41%0d", "", 0, 0, CURLUE_BAD_HOSTNAME}, + {"https://%41%0D", "", 0, 0, CURLUE_BAD_HOSTNAME}, {"https://%25", "", 0, 0, CURLUE_BAD_HOSTNAME}, {"https://_%c0_", "https://_\xC0_/", 0, 0, CURLUE_OK}, {"https://_%c0_", "https://_%C0_/", 0, CURLU_URLENCODE, CURLUE_OK}, @@ -897,6 +895,10 @@ static const struct setgetcase setget_parts_list[] = { /* !checksrc! disable SPACEBEFORECOMMA 1 */ static const struct setcase set_parts_list[] = { + {"https://example.com/", + "path=one /$!$&'()*+;=:@{}[]%,", + "https://example.com/one%20/$!$&'()*+;=:@{}[]%25", + 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK}, {NULL, /* start fresh! */ "scheme=https,path=/,url=\"\",", /* incomplete url, redirect to "" */ "https://example.com/", @@ -915,11 +917,11 @@ static const struct setcase set_parts_list[] = { 0, 0, CURLUE_OK, CURLUE_OK}, {"https://example.com/", "path=one\ntwo,", - "https://example.com/one%0atwo", + "https://example.com/one%0Atwo", 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK}, {"https://example.com/", "path=one\rtwo,", - "https://example.com/one%0dtwo", + "https://example.com/one%0Dtwo", 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK}, {"https://example.com/", "host=%43url.se,", @@ -1003,7 +1005,7 @@ static const struct setcase set_parts_list[] = { {"https://example.com/", "query=Al2cO3tDkcDZ3EWE5Lh+LX8TPHs,", /* contains '+' */ - "https://example.com/?Al2cO3tDkcDZ3EWE5Lh%2bLX8TPHs", + "https://example.com/?Al2cO3tDkcDZ3EWE5Lh%2BLX8TPHs", CURLU_URLDECODE, /* decode on get */ CURLU_URLENCODE, /* encode on set */ CURLUE_OK, CURLUE_OK}, @@ -1065,7 +1067,7 @@ static const struct setcase set_parts_list[] = { 0, 0, CURLUE_OK, CURLUE_OK}, {NULL, "scheme=https,user= @:,host=foobar,", - "https://%20%20%20%40%3a@foobar/", + "https://%20%20%20%40%3A@foobar/", 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK}, /* Setting a host name with spaces is not OK: */ {NULL, @@ -1078,7 +1080,7 @@ static const struct setcase set_parts_list[] = { 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK}, {NULL, "scheme=https,host=foobar,path=\xc3\xa4\xc3\xb6\xc3\xbc,", - "https://foobar/%c3%a4%c3%b6%c3%bc", + "https://foobar/%C3%A4%C3%B6%C3%BC", 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK}, {"imap://user:secret;opt@host/", "options=updated,scheme=imaps,password=p4ssw0rd,", @@ -1196,11 +1198,11 @@ static CURLUcode updateurl(CURLU *u, const char *cmd, unsigned int setflags) memset(value, 0, sizeof(value)); /* Avoid valgrind false positive. */ memcpy(buf, p, n); buf[n] = 0; - if(2 == sscanf(buf, "%79[^=]=%79[^,]", part, value)) { + if(sscanf(buf, "%79[^=]=%79[^,]", part, value) == 2) { CURLUPart what = part2id(part); #if 0 /* for debugging this */ - curl_mfprintf(stderr, "%s = \"%s\" [%d]\n", part, value, (int)what); + curl_mfprintf(stderr, "%s = \"%s\" [%d]\n", part, value, what); #endif if(what > CURLUPART_ZONEID) curl_mfprintf(stderr, "UNKNOWN part '%s'\n", part); @@ -1246,7 +1248,7 @@ static const struct redircase set_url_list[] = { "file:///basic?hello#frag", 0, 0, CURLUE_OK}, {"file:///basic?hello", "?q", "file:///basic?q", 0, 0, CURLUE_OK}, - {"http://example.org#withs/ash", "/moo#frag", + {"http://example.org#without/ash", "/moo#frag", "http://example.org/moo#frag", 0, 0, CURLUE_OK}, {"http://example.org/", "../path/././../././../moo", @@ -1397,7 +1399,7 @@ static int set_url(void) if(rc) { curl_mfprintf(stderr, "%s:%d Set URL %s returned %d (%s)\n", __FILE__, __LINE__, set_url_list[i].set, - (int)rc, curl_url_strerror(rc)); + rc, curl_url_strerror(rc)); error++; } else { @@ -1405,7 +1407,7 @@ static int set_url(void) rc = curl_url_get(urlp, CURLUPART_URL, &url, 0); if(rc) { curl_mfprintf(stderr, "%s:%d Get URL returned %d (%s)\n", - __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); + __FILE__, __LINE__, rc, curl_url_strerror(rc)); error++; } else { @@ -1418,7 +1420,7 @@ static int set_url(void) } else if(rc != set_url_list[i].ucode) { curl_mfprintf(stderr, "Set URL\nin: %s\nreturned %d (expected %d)\n", - set_url_list[i].in, (int)rc, set_url_list[i].ucode); + set_url_list[i].in, rc, set_url_list[i].ucode); error++; } curl_url_cleanup(urlp); @@ -1430,45 +1432,51 @@ static int set_url(void) 2. Set one or more parts 3. Extract and compare all parts - not the URL */ -static int setget_parts(void) +static int setget_parts(bool has_utf8) { int i; int error = 0; for(i = 0; setget_parts_list[i].set && !error; i++) { - CURLUcode rc; CURLU *urlp = curl_url(); if(!urlp) { error++; break; } - if(setget_parts_list[i].in) - rc = curl_url_set(urlp, CURLUPART_URL, setget_parts_list[i].in, - setget_parts_list[i].urlflags); - else - rc = CURLUE_OK; - if(!rc) { - char *url = NULL; - CURLUcode uc = updateurl(urlp, setget_parts_list[i].set, - setget_parts_list[i].setflags); - - if(uc != setget_parts_list[i].pcode) { - curl_mfprintf(stderr, "updateurl\nin: %s\nreturned %d (expected %d)\n", - setget_parts_list[i].set, - (int)uc, setget_parts_list[i].pcode); - error++; + if((setget_parts_list[i].getflags != CURLU_PUNYCODE && + setget_parts_list[i].getflags != CURLU_PUNY2IDN) || has_utf8) { + CURLUcode rc; + if(setget_parts_list[i].in) + rc = curl_url_set(urlp, CURLUPART_URL, setget_parts_list[i].in, + setget_parts_list[i].urlflags); + else + rc = CURLUE_OK; + if(!rc) { + char *url = NULL; + CURLUcode uc = updateurl(urlp, setget_parts_list[i].set, + setget_parts_list[i].setflags); + + if(uc != setget_parts_list[i].pcode) { + curl_mfprintf(stderr, + "updateurl\nin: %s\nreturned %d (expected %d)\n", + setget_parts_list[i].set, uc, + setget_parts_list[i].pcode); + error++; + } + if(!uc) { + if(checkparts(urlp, + setget_parts_list[i].set, + setget_parts_list[i].out, + setget_parts_list[i].getflags)) + error++; /* add */ + } + curl_free(url); } - if(!uc) { - if(checkparts(urlp, setget_parts_list[i].set, setget_parts_list[i].out, - setget_parts_list[i].getflags)) - error++; /* add */ + else if(rc != CURLUE_OK) { + curl_mfprintf(stderr, "Set parts\nin: %s\nreturned %d (expected %d)\n", + setget_parts_list[i].in, rc, 0); + error++; } - curl_free(url); - } - else if(rc != CURLUE_OK) { - curl_mfprintf(stderr, "Set parts\nin: %s\nreturned %d (expected %d)\n", - setget_parts_list[i].in, (int)rc, 0); - error++; } curl_url_cleanup(urlp); } @@ -1499,7 +1507,7 @@ static int set_parts(void) if(uc != set_parts_list[i].pcode) { curl_mfprintf(stderr, "updateurl\nin: %s\nreturned %d (expected %d)\n", - set_parts_list[i].set, (int)uc, set_parts_list[i].pcode); + set_parts_list[i].set, uc, set_parts_list[i].pcode); error++; } if(!uc) { @@ -1508,7 +1516,7 @@ static int set_parts(void) if(rc) { curl_mfprintf(stderr, "%s:%d Get URL returned %d (%s)\n", - __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); + __FILE__, __LINE__, rc, curl_url_strerror(rc)); error++; } else if(checkurl(set_parts_list[i].in, url, set_parts_list[i].out)) { @@ -1519,7 +1527,7 @@ static int set_parts(void) } else if(rc != set_parts_list[i].ucode) { curl_mfprintf(stderr, "Set parts\nin: %s\nreturned %d (expected %d)\n", - set_parts_list[i].in, (int)rc, set_parts_list[i].ucode); + set_parts_list[i].in, rc, set_parts_list[i].ucode); error++; } curl_url_cleanup(urlp); @@ -1527,71 +1535,77 @@ static int set_parts(void) return error; } -static int get_url(void) +static int get_url(bool has_utf8) { int i; int error = 0; for(i = 0; get_url_list[i].in && !error; i++) { - CURLUcode rc; CURLU *urlp = curl_url(); if(!urlp) { error++; break; } - rc = curl_url_set(urlp, CURLUPART_URL, get_url_list[i].in, - get_url_list[i].urlflags); - if(!rc) { - char *url = NULL; - rc = curl_url_get(urlp, CURLUPART_URL, &url, get_url_list[i].getflags); + if((get_url_list[i].getflags != CURLU_PUNYCODE && + get_url_list[i].getflags != CURLU_PUNY2IDN) || has_utf8) { + CURLUcode rc; + rc = curl_url_set(urlp, CURLUPART_URL, get_url_list[i].in, + get_url_list[i].urlflags); + if(!rc) { + char *url = NULL; + rc = curl_url_get(urlp, CURLUPART_URL, &url, get_url_list[i].getflags); - if(rc) { - curl_mfprintf(stderr, "%s:%d returned %d (%s). URL: '%s'\n", - __FILE__, __LINE__, (int)rc, curl_url_strerror(rc), - get_url_list[i].in); - error++; - } - else { - if(checkurl(get_url_list[i].in, url, get_url_list[i].out)) { + if(rc) { + curl_mfprintf(stderr, "%s:%d returned %d (%s). URL: '%s'\n", + __FILE__, __LINE__, rc, curl_url_strerror(rc), + get_url_list[i].in); error++; } + else { + if(checkurl(get_url_list[i].in, url, get_url_list[i].out)) { + error++; + } + } + curl_free(url); + } + if(rc != get_url_list[i].ucode) { + curl_mfprintf(stderr, "Get URL\nin: %s\nreturned %d (expected %d)\n", + get_url_list[i].in, rc, get_url_list[i].ucode); + error++; } - curl_free(url); - } - if(rc != get_url_list[i].ucode) { - curl_mfprintf(stderr, "Get URL\nin: %s\nreturned %d (expected %d)\n", - get_url_list[i].in, (int)rc, get_url_list[i].ucode); - error++; } curl_url_cleanup(urlp); } return error; } -static int get_parts(void) +static int get_parts(bool has_utf8) { int i; int error = 0; for(i = 0; get_parts_list[i].in && !error; i++) { - CURLUcode rc; CURLU *urlp = curl_url(); if(!urlp) { error++; break; } - rc = curl_url_set(urlp, CURLUPART_URL, - get_parts_list[i].in, - get_parts_list[i].urlflags); - if(rc != get_parts_list[i].ucode) { - curl_mfprintf(stderr, "Get parts\nin: %s\nreturned %d (expected %d)\n", - get_parts_list[i].in, (int)rc, get_parts_list[i].ucode); - error++; - } - else if(get_parts_list[i].ucode) { - /* the expected error happened */ + if((get_parts_list[i].getflags != CURLU_PUNYCODE && + get_parts_list[i].getflags != CURLU_PUNY2IDN) || has_utf8) { + CURLUcode rc; + rc = curl_url_set(urlp, CURLUPART_URL, + get_parts_list[i].in, + get_parts_list[i].urlflags); + if(rc != get_parts_list[i].ucode) { + curl_mfprintf(stderr, "Get parts\nin: %s\nreturned %d (expected %d)\n", + get_parts_list[i].in, rc, get_parts_list[i].ucode); + error++; + } + else if(get_parts_list[i].ucode) { + /* the expected error happened */ + } + else if(checkparts(urlp, get_parts_list[i].in, get_parts_list[i].out, + get_parts_list[i].getflags)) + error++; } - else if(checkparts(urlp, get_parts_list[i].in, get_parts_list[i].out, - get_parts_list[i].getflags)) - error++; curl_url_cleanup(urlp); } return error; @@ -1600,7 +1614,7 @@ static int get_parts(void) static const struct querycase append_list[] = { {"HTTP://test/?s", "name=joe\x02", "http://test/?s&name=joe%02", 0, CURLU_URLENCODE, CURLUE_OK}, - {"HTTP://test/?size=2#f", "name=joe=", "http://test/?size=2&name=joe%3d#f", + {"HTTP://test/?size=2#f", "name=joe=", "http://test/?size=2&name=joe%3D#f", 0, CURLU_URLENCODE, CURLUE_OK}, {"HTTP://test/?size=2#f", "name=joe doe", "http://test/?size=2&name=joe+doe#f", @@ -1639,7 +1653,7 @@ static int append(void) ; else if(rc != append_list[i].ucode) { curl_mfprintf(stderr, "Append\nin: %s\nreturned %d (expected %d)\n", - append_list[i].in, (int)rc, append_list[i].ucode); + append_list[i].in, rc, append_list[i].ucode); error++; } else if(append_list[i].ucode) { @@ -1650,7 +1664,7 @@ static int append(void) rc = curl_url_get(urlp, CURLUPART_URL, &url, 0); if(rc) { curl_mfprintf(stderr, "%s:%d Get URL returned %d (%s)\n", - __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); + __FILE__, __LINE__, rc, curl_url_strerror(rc)); error++; } else { @@ -1676,7 +1690,7 @@ static int scopeid(void) "https://[fe80::20c:29ff:fe9c:409b%25eth0]/hello.html", 0); if(rc != CURLUE_OK) { curl_mfprintf(stderr, "%s:%d curl_url_set returned %d (%s)\n", - __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); + __FILE__, __LINE__, rc, curl_url_strerror(rc)); error++; } @@ -1684,7 +1698,7 @@ static int scopeid(void) if(rc != CURLUE_OK) { curl_mfprintf(stderr, "%s:%d curl_url_get CURLUPART_HOST returned %d (%s)\n", - __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); + __FILE__, __LINE__, rc, curl_url_strerror(rc)); error++; } else { @@ -1695,7 +1709,7 @@ static int scopeid(void) if(rc != CURLUE_OK) { curl_mfprintf(stderr, "%s:%d curl_url_set CURLUPART_HOST returned %d (%s)\n", - __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); + __FILE__, __LINE__, rc, curl_url_strerror(rc)); error++; } @@ -1703,7 +1717,7 @@ static int scopeid(void) if(rc != CURLUE_OK) { curl_mfprintf(stderr, "%s:%d curl_url_get CURLUPART_URL returned %d (%s)\n", - __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); + __FILE__, __LINE__, rc, curl_url_strerror(rc)); error++; } else { @@ -1714,7 +1728,7 @@ static int scopeid(void) if(rc != CURLUE_OK) { curl_mfprintf(stderr, "%s:%d curl_url_set CURLUPART_HOST returned %d (%s)\n", - __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); + __FILE__, __LINE__, rc, curl_url_strerror(rc)); error++; } @@ -1722,7 +1736,7 @@ static int scopeid(void) if(rc != CURLUE_OK) { curl_mfprintf(stderr, "%s:%d curl_url_get CURLUPART_URL returned %d (%s)\n", - __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); + __FILE__, __LINE__, rc, curl_url_strerror(rc)); error++; } else { @@ -1734,7 +1748,7 @@ static int scopeid(void) if(rc != CURLUE_OK) { curl_mfprintf(stderr, "%s:%d curl_url_set CURLUPART_HOST returned %d (%s)\n", - __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); + __FILE__, __LINE__, rc, curl_url_strerror(rc)); error++; } @@ -1742,7 +1756,7 @@ static int scopeid(void) if(rc != CURLUE_OK) { curl_mfprintf(stderr, "%s:%d curl_url_get CURLUPART_URL returned %d (%s)\n", - __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); + __FILE__, __LINE__, rc, curl_url_strerror(rc)); error++; } else { @@ -1753,7 +1767,7 @@ static int scopeid(void) if(rc != CURLUE_OK) { curl_mfprintf(stderr, "%s:%d curl_url_get CURLUPART_HOST returned %d (%s)\n", - __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); + __FILE__, __LINE__, rc, curl_url_strerror(rc)); error++; } else { @@ -1764,7 +1778,7 @@ static int scopeid(void) if(rc != CURLUE_OK) { curl_mfprintf(stderr, "%s:%d curl_url_get CURLUPART_ZONEID returned %d (%s)\n", - __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); + __FILE__, __LINE__, rc, curl_url_strerror(rc)); error++; } else { @@ -1775,7 +1789,7 @@ static int scopeid(void) if(rc != CURLUE_OK) { curl_mfprintf(stderr, "%s:%d curl_url_set CURLUPART_ZONEID returned %d (%s)\n", - __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); + __FILE__, __LINE__, rc, curl_url_strerror(rc)); error++; } @@ -1783,7 +1797,7 @@ static int scopeid(void) if(rc != CURLUE_OK) { curl_mfprintf(stderr, "%s:%d curl_url_get CURLUPART_URL returned %d (%s)\n", - __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); + __FILE__, __LINE__, rc, curl_url_strerror(rc)); error++; } else { @@ -1838,8 +1852,8 @@ static int get_nothing(void) rc = curl_url_get(u, CURLUPART_ZONEID, &p, 0); if(rc != CURLUE_NO_ZONEID) - curl_mfprintf(stderr, "unexpected return code %u on line %u\n", (int)rc, - __LINE__); + curl_mfprintf(stderr, "unexpected return code %u on line %u\n", rc, + __LINE__); curl_url_cleanup(u); } @@ -1878,8 +1892,8 @@ static int clear_url(void) curl_mfprintf(stderr, "unexpected return code line %u\n", __LINE__); rc = curl_url_get(u, clear_url_list[i].part, &p, 0); - if(rc != clear_url_list[i].ucode || (clear_url_list[i].out && - 0 != strcmp(p, clear_url_list[i].out))) { + if(rc != clear_url_list[i].ucode || + (clear_url_list[i].out && strcmp(p, clear_url_list[i].out) != 0)) { curl_mfprintf(stderr, "unexpected return code line %u\n", __LINE__); error++; @@ -1902,11 +1916,11 @@ static char bigpart[120000]; */ static int huge(void) { - const char *smallpart = "c"; + static const char *smallpart = "c"; int i; CURLU *urlp = curl_url(); CURLUcode rc; - CURLUPart part[]= { + CURLUPart part[] = { CURLUPART_SCHEME, CURLUPART_USER, CURLUPART_PASSWORD, @@ -1956,7 +1970,7 @@ static int huge(void) static int urldup(void) { - const char *url[] = { + static const char *url[] = { "http://" "user:pwd@" "[2a04:4e42:e00::347%25eth0]" @@ -2018,17 +2032,19 @@ static int urldup(void) return 1; } -CURLcode test(char *URL) +static CURLcode test_lib1560(const char *URL) { + bool has_utf8 = !!getenv("CURL_TEST_HAVE_CODESET_UTF8"); + (void)URL; /* not used */ if(urldup()) return (CURLcode)11; - if(setget_parts()) + if(setget_parts(has_utf8)) return (CURLcode)10; - if(get_url()) + if(get_url(has_utf8)) return (CURLcode)3; if(huge()) @@ -2049,7 +2065,7 @@ CURLcode test(char *URL) if(set_parts()) return (CURLcode)2; - if(get_parts()) + if(get_parts(has_utf8)) return (CURLcode)4; if(clear_url()) diff --git a/vendor/curl/tests/libtest/lib1564.c b/vendor/curl/tests/libtest/lib1564.c index 83c774df700..283f9dcf399 100644 --- a/vendor/curl/tests/libtest/lib1564.c +++ b/vendor/curl/tests/libtest/lib1564.c @@ -21,22 +21,19 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 #define WAKEUP_NUM 10 -CURLcode test(char *URL) +static CURLcode test_lib1564(const char *URL) { CURLM *multi = NULL; int numfds; int i; CURLcode res = CURLE_OK; - struct timeval time_before_wait, time_after_wait; + struct curltime time_before_wait, time_after_wait; (void)URL; @@ -48,11 +45,11 @@ CURLcode test(char *URL) /* no wakeup */ - time_before_wait = tutil_tvnow(); + time_before_wait = curlx_now(); multi_poll(multi, NULL, 0, 1000, &numfds); - time_after_wait = tutil_tvnow(); + time_after_wait = curlx_now(); - if(tutil_tvdiff(time_after_wait, time_before_wait) < 500) { + if(curlx_timediff(time_after_wait, time_before_wait) < 500) { curl_mfprintf(stderr, "%s:%d curl_multi_poll returned too early\n", __FILE__, __LINE__); res = TEST_ERR_MAJOR_BAD; @@ -65,11 +62,11 @@ CURLcode test(char *URL) res_multi_wakeup(multi); - time_before_wait = tutil_tvnow(); + time_before_wait = curlx_now(); multi_poll(multi, NULL, 0, 1000, &numfds); - time_after_wait = tutil_tvnow(); + time_after_wait = curlx_now(); - if(tutil_tvdiff(time_after_wait, time_before_wait) > 500) { + if(curlx_timediff(time_after_wait, time_before_wait) > 500) { curl_mfprintf(stderr, "%s:%d curl_multi_poll returned too late\n", __FILE__, __LINE__); res = TEST_ERR_MAJOR_BAD; @@ -80,11 +77,11 @@ CURLcode test(char *URL) /* previous wakeup should not wake up this */ - time_before_wait = tutil_tvnow(); + time_before_wait = curlx_now(); multi_poll(multi, NULL, 0, 1000, &numfds); - time_after_wait = tutil_tvnow(); + time_after_wait = curlx_now(); - if(tutil_tvdiff(time_after_wait, time_before_wait) < 500) { + if(curlx_timediff(time_after_wait, time_before_wait) < 500) { curl_mfprintf(stderr, "%s:%d curl_multi_poll returned too early\n", __FILE__, __LINE__); res = TEST_ERR_MAJOR_BAD; @@ -98,11 +95,11 @@ CURLcode test(char *URL) for(i = 0; i < WAKEUP_NUM; ++i) res_multi_wakeup(multi); - time_before_wait = tutil_tvnow(); + time_before_wait = curlx_now(); multi_poll(multi, NULL, 0, 1000, &numfds); - time_after_wait = tutil_tvnow(); + time_after_wait = curlx_now(); - if(tutil_tvdiff(time_after_wait, time_before_wait) > 500) { + if(curlx_timediff(time_after_wait, time_before_wait) > 500) { curl_mfprintf(stderr, "%s:%d curl_multi_poll returned too late\n", __FILE__, __LINE__); res = TEST_ERR_MAJOR_BAD; @@ -113,11 +110,11 @@ CURLcode test(char *URL) /* Even lots of previous wakeups should not wake up this. */ - time_before_wait = tutil_tvnow(); + time_before_wait = curlx_now(); multi_poll(multi, NULL, 0, 1000, &numfds); - time_after_wait = tutil_tvnow(); + time_after_wait = curlx_now(); - if(tutil_tvdiff(time_after_wait, time_before_wait) < 500) { + if(curlx_timediff(time_after_wait, time_before_wait) < 500) { curl_mfprintf(stderr, "%s:%d curl_multi_poll returned too early\n", __FILE__, __LINE__); res = TEST_ERR_MAJOR_BAD; diff --git a/vendor/curl/tests/libtest/lib1565.c b/vendor/curl/tests/libtest/lib1565.c index d83add89599..3fecdd84ce4 100644 --- a/vendor/curl/tests/libtest/lib1565.c +++ b/vendor/curl/tests/libtest/lib1565.c @@ -21,29 +21,25 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" #ifdef HAVE_PTHREAD_H #include -#include -#define TEST_HANG_TIMEOUT 60 * 1000 #define CONN_NUM 3 #define TIME_BETWEEN_START_SECS 2 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; static CURL *pending_handles[CONN_NUM]; static int pending_num = 0; -static CURLcode test_failure = CURLE_OK; +static CURLcode t1565_test_failure = CURLE_OK; static CURLM *testmulti = NULL; -static const char *url; +static const char *t1565_url; -static void *run_thread(void *ptr) +static void *t1565_run_thread(void *ptr) { CURL *easy = NULL; CURLcode res = CURLE_OK; @@ -52,16 +48,16 @@ static void *run_thread(void *ptr) (void)ptr; for(i = 0; i < CONN_NUM; i++) { - wait_ms(TIME_BETWEEN_START_SECS * 1000); + curlx_wait_ms(TIME_BETWEEN_START_SECS * 1000); easy_init(easy); - easy_setopt(easy, CURLOPT_URL, url); + easy_setopt(easy, CURLOPT_URL, t1565_url); easy_setopt(easy, CURLOPT_VERBOSE, 0L); pthread_mutex_lock(&lock); - if(test_failure) { + if(t1565_test_failure) { pthread_mutex_unlock(&lock); goto test_cleanup; } @@ -81,15 +77,15 @@ static void *run_thread(void *ptr) pthread_mutex_lock(&lock); - if(!test_failure) - test_failure = res; + if(!t1565_test_failure) + t1565_test_failure = res; pthread_mutex_unlock(&lock); return NULL; } -CURLcode test(char *URL) +static CURLcode test_lib1565(const char *URL) { int still_running; int num; @@ -109,9 +105,9 @@ CURLcode test(char *URL) multi_init(testmulti); - url = URL; + t1565_url = URL; - result = pthread_create(&tid, NULL, run_thread, NULL); + result = pthread_create(&tid, NULL, t1565_run_thread, NULL); if(!result) tid_valid = true; else { @@ -136,7 +132,7 @@ CURLcode test(char *URL) else { curl_mfprintf(stderr, "%s:%d Got an unexpected message from curl: %i\n", - __FILE__, __LINE__, (int)message->msg); + __FILE__, __LINE__, message->msg); res = TEST_ERR_MAJOR_BAD; goto test_cleanup; } @@ -185,8 +181,8 @@ CURLcode test(char *URL) test_cleanup: pthread_mutex_lock(&lock); - if(!test_failure) - test_failure = res; + if(!t1565_test_failure) + t1565_test_failure = res; pthread_mutex_unlock(&lock); if(tid_valid) @@ -199,11 +195,11 @@ CURLcode test(char *URL) curl_easy_cleanup(started_handles[i]); curl_global_cleanup(); - return test_failure; + return t1565_test_failure; } #else /* without pthread, this test doesn't work */ -CURLcode test(char *URL) +static CURLcode test_lib1565(const char *URL) { (void)URL; return CURLE_OK; diff --git a/vendor/curl/tests/libtest/lib1567.c b/vendor/curl/tests/libtest/lib1567.c index d1de1637a0a..e0016157256 100644 --- a/vendor/curl/tests/libtest/lib1567.c +++ b/vendor/curl/tests/libtest/lib1567.c @@ -21,13 +21,13 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" #include -CURLcode test(char *URL) +static CURLcode test_lib1567(const char *URL) { CURL *curl = NULL; CURLcode res = CURLE_OK; diff --git a/vendor/curl/tests/libtest/lib1568.c b/vendor/curl/tests/libtest/lib1568.c index 383d517a475..a2451486fd4 100644 --- a/vendor/curl/tests/libtest/lib1568.c +++ b/vendor/curl/tests/libtest/lib1568.c @@ -21,12 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testtrace.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1568(const char *URL) { CURLcode ret; CURL *hnd; @@ -38,7 +37,7 @@ CURLcode test(char *URL) curl_easy_setopt(hnd, CURLOPT_HEADER, 1L); curl_easy_setopt(hnd, CURLOPT_USERPWD, "testuser:testpass"); curl_easy_setopt(hnd, CURLOPT_USERAGENT, "lib1568"); - curl_easy_setopt(hnd, CURLOPT_HTTPAUTH, (long)CURLAUTH_DIGEST); + curl_easy_setopt(hnd, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); curl_easy_setopt(hnd, CURLOPT_PORT, strtol(libtest_arg2, NULL, 10)); diff --git a/vendor/curl/tests/libtest/lib1569.c b/vendor/curl/tests/libtest/lib1569.c index 767d8816822..2846909e88f 100644 --- a/vendor/curl/tests/libtest/lib1569.c +++ b/vendor/curl/tests/libtest/lib1569.c @@ -21,12 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testtrace.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1569(const char *URL) { CURLcode res = CURLE_OK; CURL *hnd; diff --git a/vendor/curl/tests/libtest/lib1571.c b/vendor/curl/tests/libtest/lib1571.c index 599475742e2..622be2f643d 100644 --- a/vendor/curl/tests/libtest/lib1571.c +++ b/vendor/curl/tests/libtest/lib1571.c @@ -21,15 +21,14 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1571(const char *URL) { CURLcode res; CURL *curl; - int testno = atoi(libtest_arg2); if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { curl_mfprintf(stderr, "curl_global_init() failed\n"); @@ -46,15 +45,16 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_HEADER, 1L); test_setopt(curl, CURLOPT_VERBOSE, 1L); test_setopt(curl, CURLOPT_URL, URL); - if((testno == 1571) || (testno == 1575) || (testno == 1581)) { + if((testnum == 1571) || (testnum == 1572) || + (testnum == 1575) || (testnum == 1581)) { test_setopt(curl, CURLOPT_POSTFIELDS, "moo"); } - if(testno == 1581) { - test_setopt(curl, CURLOPT_POSTREDIR, (long)CURL_REDIR_POST_301); + if(testnum == 1581) { + test_setopt(curl, CURLOPT_POSTREDIR, CURL_REDIR_POST_301); } test_setopt(curl, CURLOPT_CUSTOMREQUEST, "IGLOO"); - if((testno == 1574) || (testno == 1575)) { + if((testnum == 1574) || (testnum == 1575)) { test_setopt(curl, CURLOPT_FOLLOWLOCATION, CURLFOLLOW_FIRSTONLY); } else { diff --git a/vendor/curl/tests/libtest/lib1576.c b/vendor/curl/tests/libtest/lib1576.c index 279d6fbc97f..203ef2b9891 100644 --- a/vendor/curl/tests/libtest/lib1576.c +++ b/vendor/curl/tests/libtest/lib1576.c @@ -21,24 +21,24 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -static char testdata[] = "request indicates that the client, which made"; +static char t1576_testdata[] = "request indicates that the client, which made"; -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *stream) +static size_t t1576_read_cb(char *ptr, size_t size, size_t nmemb, void *stream) { - size_t amount = nmemb * size; /* Total bytes curl wants */ - if(amount < strlen(testdata)) { - return strlen(testdata); + size_t amount = nmemb * size; /* Total bytes curl wants */ + if(amount < strlen(t1576_testdata)) { + return strlen(t1576_testdata); } (void)stream; - memcpy(ptr, testdata, strlen(testdata)); - return strlen(testdata); + memcpy(ptr, t1576_testdata, strlen(t1576_testdata)); + return strlen(t1576_testdata); } -static int seek_callback(void *ptr, curl_off_t offset, int origin) +static int t1576_seek_callback(void *ptr, curl_off_t offset, int origin) { (void)ptr; (void)offset; @@ -47,12 +47,11 @@ static int seek_callback(void *ptr, curl_off_t offset, int origin) return CURL_SEEKFUNC_OK; } -CURLcode test(char *URL) +static CURLcode test_lib1576(const char *URL) { CURLcode res; CURL *curl; struct curl_slist *pHeaderList = NULL; - int testno = atoi(libtest_arg2); if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { curl_mfprintf(stderr, "curl_global_init() failed\n"); @@ -70,12 +69,12 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_VERBOSE, 1L); test_setopt(curl, CURLOPT_URL, URL); test_setopt(curl, CURLOPT_UPLOAD, 1L); - test_setopt(curl, CURLOPT_READFUNCTION, read_callback); - test_setopt(curl, CURLOPT_SEEKFUNCTION, seek_callback); - test_setopt(curl, CURLOPT_INFILESIZE, (long)strlen(testdata)); + test_setopt(curl, CURLOPT_READFUNCTION, t1576_read_cb); + test_setopt(curl, CURLOPT_SEEKFUNCTION, t1576_seek_callback); + test_setopt(curl, CURLOPT_INFILESIZE, (long)strlen(t1576_testdata)); test_setopt(curl, CURLOPT_CUSTOMREQUEST, "CURL"); - if(testno == 1578) { + if(testnum == 1578 || testnum == 1580) { test_setopt(curl, CURLOPT_FOLLOWLOCATION, CURLFOLLOW_FIRSTONLY); } else { diff --git a/vendor/curl/tests/libtest/lib1591.c b/vendor/curl/tests/libtest/lib1591.c index 7d1c012698e..3031ba1bb71 100644 --- a/vendor/curl/tests/libtest/lib1591.c +++ b/vendor/curl/tests/libtest/lib1591.c @@ -27,22 +27,23 @@ * from server http header */ -#include "test.h" -#include +#include "first.h" + #include "memdebug.h" -static char testdata[] = "Hello Cloud!\r\n"; static size_t consumed = 0; -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *stream) +static size_t t1591_read_cb(char *ptr, size_t size, size_t nmemb, void *stream) { - size_t amount = nmemb * size; /* Total bytes curl wants */ + static const char testdata[] = "Hello Cloud!\r\n"; + + size_t amount = nmemb * size; /* Total bytes curl wants */ if(consumed == strlen(testdata)) { return 0; } - if(amount > strlen(testdata)-consumed) { + if(amount > strlen(testdata) - consumed) { amount = strlen(testdata); } @@ -55,7 +56,7 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *stream) /* * carefully not leak memory on OOM */ -static int trailers_callback(struct curl_slist **list, void *userdata) +static int t1591_trailers_callback(struct curl_slist **list, void *userdata) { struct curl_slist *nlist = NULL; struct curl_slist *nlist2 = NULL; @@ -73,7 +74,7 @@ static int trailers_callback(struct curl_slist **list, void *userdata) } } -CURLcode test(char *URL) +static CURLcode test_lib1591(const char *URL) { CURL *curl = NULL; CURLcode res = CURLE_FAILED_INIT; @@ -85,7 +86,6 @@ CURLcode test(char *URL) return TEST_ERR_MAJOR_BAD; } - curl = curl_easy_init(); if(!curl) { curl_mfprintf(stderr, "curl_easy_init() failed\n"); @@ -102,8 +102,8 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_URL, URL); test_setopt(curl, CURLOPT_HTTPHEADER, hhl); test_setopt(curl, CURLOPT_UPLOAD, 1L); - test_setopt(curl, CURLOPT_READFUNCTION, read_callback); - test_setopt(curl, CURLOPT_TRAILERFUNCTION, trailers_callback); + test_setopt(curl, CURLOPT_READFUNCTION, t1591_read_cb); + test_setopt(curl, CURLOPT_TRAILERFUNCTION, t1591_trailers_callback); test_setopt(curl, CURLOPT_TRAILERDATA, NULL); res = curl_easy_perform(curl); diff --git a/vendor/curl/tests/libtest/lib1592.c b/vendor/curl/tests/libtest/lib1592.c index 99f088d661b..3f76a19c4f5 100644 --- a/vendor/curl/tests/libtest/lib1592.c +++ b/vendor/curl/tests/libtest/lib1592.c @@ -32,16 +32,13 @@ /* We're willing to wait a very generous two seconds for the removal. This is as low as we can go while still easily supporting SIGALRM timing for the non-threaded blocking resolver. It doesn't matter that much because when - the test passes, we never wait this long. We set it much higher to avoid - issues when running on overloaded CI machines. */ -#define TEST_HANG_TIMEOUT 60 * 1000 + the test passes, we never wait this long. We set it much higher via + the default TEST_HANG_TIMEOUT to avoid issues when running on overloaded + CI machines. */ -#include "test.h" -#include "testutil.h" +#include "first.h" -#include - -CURLcode test(char *URL) +static CURLcode test_lib1592(const char *URL) { int stillRunning; CURLM *multiHandle = NULL; diff --git a/vendor/curl/tests/libtest/lib1593.c b/vendor/curl/tests/libtest/lib1593.c index f5239fda4b7..22a07e29209 100644 --- a/vendor/curl/tests/libtest/lib1593.c +++ b/vendor/curl/tests/libtest/lib1593.c @@ -24,11 +24,11 @@ /* Test suppressing the If-Modified-Since header */ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1593(const char *URL) { struct curl_slist *header = NULL; long unmet; @@ -40,7 +40,7 @@ CURLcode test(char *URL) easy_init(curl); easy_setopt(curl, CURLOPT_URL, URL); - easy_setopt(curl, CURLOPT_TIMECONDITION, (long)CURL_TIMECOND_IFMODSINCE); + easy_setopt(curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE); /* Some TIMEVALUE; it doesn't matter. */ easy_setopt(curl, CURLOPT_TIMEVALUE, 1566210680L); diff --git a/vendor/curl/tests/libtest/lib1594.c b/vendor/curl/tests/libtest/lib1594.c index 8b469e6105c..5c8db3ae92a 100644 --- a/vendor/curl/tests/libtest/lib1594.c +++ b/vendor/curl/tests/libtest/lib1594.c @@ -24,11 +24,11 @@ /* Testing Retry-After header parser */ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1594(const char *URL) { struct curl_slist *header = NULL; curl_off_t retry; diff --git a/vendor/curl/tests/libtest/lib1597.c b/vendor/curl/tests/libtest/lib1597.c index f183d3e4288..251016641e7 100644 --- a/vendor/curl/tests/libtest/lib1597.c +++ b/vendor/curl/tests/libtest/lib1597.c @@ -24,7 +24,7 @@ /* Testing CURLOPT_PROTOCOLS_STR */ -#include "test.h" +#include "first.h" #include "memdebug.h" @@ -33,7 +33,7 @@ struct pair { CURLcode *exp; }; -CURLcode test(char *URL) +static CURLcode test_lib1597(const char *URL) { CURL *curl = NULL; CURLcode res = CURLE_OK; diff --git a/vendor/curl/tests/libtest/lib1598.c b/vendor/curl/tests/libtest/lib1598.c index e2a3cfeb0ac..4120916ff0a 100644 --- a/vendor/curl/tests/libtest/lib1598.c +++ b/vendor/curl/tests/libtest/lib1598.c @@ -27,14 +27,14 @@ * from server http header */ -#include "test.h" -#include +#include "first.h" + #include "memdebug.h" /* * carefully not leak memory on OOM */ -static int trailers_callback(struct curl_slist **list, void *userdata) +static int t1598_trailers_callback(struct curl_slist **list, void *userdata) { struct curl_slist *nlist = NULL; struct curl_slist *nlist2 = NULL; @@ -52,10 +52,10 @@ static int trailers_callback(struct curl_slist **list, void *userdata) } } -static const char *post_data = "xxx=yyy&aaa=bbbbb"; - -CURLcode test(char *URL) +static CURLcode test_lib1598(const char *URL) { + static const char *post_data = "xxx=yyy&aaa=bbbbb"; + CURL *curl = NULL; CURLcode res = CURLE_FAILED_INIT; /* http and proxy header list */ @@ -66,7 +66,6 @@ CURLcode test(char *URL) return TEST_ERR_MAJOR_BAD; } - curl = curl_easy_init(); if(!curl) { curl_mfprintf(stderr, "curl_easy_init() failed\n"); @@ -89,7 +88,7 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_HTTPHEADER, hhl); test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(post_data)); test_setopt(curl, CURLOPT_POSTFIELDS, post_data); - test_setopt(curl, CURLOPT_TRAILERFUNCTION, trailers_callback); + test_setopt(curl, CURLOPT_TRAILERFUNCTION, t1598_trailers_callback); test_setopt(curl, CURLOPT_TRAILERDATA, NULL); test_setopt(curl, CURLOPT_VERBOSE, 1L); diff --git a/vendor/curl/tests/libtest/lib1599.c b/vendor/curl/tests/libtest/lib1599.c new file mode 100644 index 00000000000..5bbdad81b2e --- /dev/null +++ b/vendor/curl/tests/libtest/lib1599.c @@ -0,0 +1,44 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "first.h" + +static CURLcode test_lib1599(const char *URL) +{ + CURL *curl; + CURLcode res = CURLE_OK; + + global_init(CURL_GLOBAL_ALL); + curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, URL); + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_REQUIRED); + curl_easy_setopt(curl, CURLOPT_NETRC_FILE, libtest_arg2); + + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } + curl_global_cleanup(); + return res; +} diff --git a/vendor/curl/tests/libtest/lib1662.c b/vendor/curl/tests/libtest/lib1662.c index 1e9e2b06175..b0ca4c5094c 100644 --- a/vendor/curl/tests/libtest/lib1662.c +++ b/vendor/curl/tests/libtest/lib1662.c @@ -21,17 +21,17 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -static char testdata[]="mooaaa"; - -struct WriteThis { +struct t1662_WriteThis { size_t sizeleft; }; -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) +static size_t t1662_read_cb(char *ptr, size_t size, size_t nmemb, void *userp) { - struct WriteThis *pooh = (struct WriteThis *)userp; + static const char testdata[] = "mooaaa"; + + struct t1662_WriteThis *pooh = (struct t1662_WriteThis *)userp; size_t len = strlen(testdata); if(size*nmemb < len) @@ -46,14 +46,13 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) return 0; /* no more data left to deliver */ } - -CURLcode test(char *URL) +static CURLcode test_lib1662(const char *URL) { CURLcode res = CURLE_OK; CURL *hnd; curl_mime *mime1; curl_mimepart *part1; - struct WriteThis pooh = { 1 }; + struct t1662_WriteThis pooh = { 1 }; mime1 = NULL; @@ -67,15 +66,14 @@ CURLcode test(char *URL) mime1 = curl_mime_init(hnd); if(mime1) { part1 = curl_mime_addpart(mime1); - curl_mime_data_cb(part1, -1, read_callback, NULL, NULL, &pooh); + curl_mime_data_cb(part1, -1, t1662_read_cb, NULL, NULL, &pooh); curl_mime_filename(part1, "poetry.txt"); curl_mime_name(part1, "content"); curl_easy_setopt(hnd, CURLOPT_MIMEPOST, mime1); curl_easy_setopt(hnd, CURLOPT_USERAGENT, "curl/2000"); curl_easy_setopt(hnd, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); - curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, - (long)CURL_HTTP_VERSION_2TLS); + curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS); curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); diff --git a/vendor/curl/tests/libtest/lib1900.c b/vendor/curl/tests/libtest/lib1900.c index 1b26e7b9867..3e9c60f4a8e 100644 --- a/vendor/curl/tests/libtest/lib1900.c +++ b/vendor/curl/tests/libtest/lib1900.c @@ -21,13 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1900(const char *URL) { CURLcode res = CURLE_OK; CURL *hnd = NULL; diff --git a/vendor/curl/tests/libtest/lib1901.c b/vendor/curl/tests/libtest/lib1901.c index 6d5f3d4aa02..cb66001f9bb 100644 --- a/vendor/curl/tests/libtest/lib1901.c +++ b/vendor/curl/tests/libtest/lib1901.c @@ -21,25 +21,19 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" - - -static const char *chunks[]={ - "one", - "two", - "three", - "four", - NULL -}; - - -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *stream) +static size_t t1901_read_cb(char *ptr, size_t size, size_t nmemb, void *stream) { + static const char *chunks[] = { + "one", + "two", + "three", + "four", + NULL + }; static int ix = 0; (void)size; (void)nmemb; @@ -53,7 +47,7 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *stream) return 0; } -CURLcode test(char *URL) +static CURLcode test_lib1901(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; @@ -67,7 +61,7 @@ CURLcode test(char *URL) ignores it */ easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 4L); easy_setopt(curl, CURLOPT_POSTFIELDS, NULL); - easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); + easy_setopt(curl, CURLOPT_READFUNCTION, t1901_read_cb); easy_setopt(curl, CURLOPT_POST, 1L); easy_setopt(curl, CURLOPT_VERBOSE, 1L); easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); diff --git a/vendor/curl/tests/libtest/lib1903.c b/vendor/curl/tests/libtest/lib1903.c index 0ffbb14adc2..af21e946b92 100644 --- a/vendor/curl/tests/libtest/lib1903.c +++ b/vendor/curl/tests/libtest/lib1903.c @@ -21,14 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "timediff.h" -#include "warnless.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1903(const char *URL) { CURLcode res = CURLE_OK; CURL *ch = NULL; diff --git a/vendor/curl/tests/libtest/lib1905.c b/vendor/curl/tests/libtest/lib1905.c index df35de18b20..a227a09beb4 100644 --- a/vendor/curl/tests/libtest/lib1905.c +++ b/vendor/curl/tests/libtest/lib1905.c @@ -21,14 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "timediff.h" -#include "warnless.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1905(const char *URL) { CURLSH *sh = NULL; CURL *ch = NULL; diff --git a/vendor/curl/tests/libtest/lib1906.c b/vendor/curl/tests/libtest/lib1906.c index 61996e25951..72486d6227c 100644 --- a/vendor/curl/tests/libtest/lib1906.c +++ b/vendor/curl/tests/libtest/lib1906.c @@ -21,13 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1906(const char *URL) { CURLcode res = CURLE_OK; char *url_after = NULL; diff --git a/vendor/curl/tests/libtest/lib1907.c b/vendor/curl/tests/libtest/lib1907.c index 2cda08e02cf..2aed8924077 100644 --- a/vendor/curl/tests/libtest/lib1907.c +++ b/vendor/curl/tests/libtest/lib1907.c @@ -21,13 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1907(const char *URL) { char *url_after; CURL *curl; @@ -42,8 +40,8 @@ CURLcode test(char *URL) res = curl_easy_perform(curl); if(!res) curl_mfprintf(stderr, "failure expected, " - "curl_easy_perform returned %ld: <%s>, <%s>\n", - (long) res, curl_easy_strerror(res), error_buffer); + "curl_easy_perform returned %d: <%s>, <%s>\n", + res, curl_easy_strerror(res), error_buffer); /* print the used url */ if(!curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url_after)) diff --git a/vendor/curl/tests/libtest/lib1908.c b/vendor/curl/tests/libtest/lib1908.c index 3c7187c5bc0..98e01fac9a0 100644 --- a/vendor/curl/tests/libtest/lib1908.c +++ b/vendor/curl/tests/libtest/lib1908.c @@ -21,13 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1908(const char *URL) { CURLcode ret = CURLE_OK; CURL *hnd; diff --git a/vendor/curl/tests/libtest/lib1910.c b/vendor/curl/tests/libtest/lib1910.c index 9d3f1b3ab0e..6164d595459 100644 --- a/vendor/curl/tests/libtest/lib1910.c +++ b/vendor/curl/tests/libtest/lib1910.c @@ -21,13 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1910(const char *URL) { CURLcode ret = CURLE_OK; CURL *hnd; diff --git a/vendor/curl/tests/libtest/lib1911.c b/vendor/curl/tests/libtest/lib1911.c index 6dd4dcb1b00..4ffc8085dc1 100644 --- a/vendor/curl/tests/libtest/lib1911.c +++ b/vendor/curl/tests/libtest/lib1911.c @@ -21,20 +21,18 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" /* The maximum string length limit (CURL_MAX_INPUT_LENGTH) is an internal define not publicly exposed so we set our own */ #define MAX_INPUT_LENGTH 8000000 -static char testbuf[MAX_INPUT_LENGTH + 2]; - -CURLcode test(char *URL) +static CURLcode test_lib1911(const char *URL) { + static char testbuf[MAX_INPUT_LENGTH + 2]; + const struct curl_easyoption *o; CURL *easy; int error = 0; @@ -51,7 +49,7 @@ CURLcode test(char *URL) memset(testbuf, 'A', MAX_INPUT_LENGTH + 1); testbuf[MAX_INPUT_LENGTH + 1] = 0; - curl_mprintf("string length: %d\n", (int)strlen(testbuf)); + curl_mprintf("string length: %zu\n", strlen(testbuf)); for(o = curl_easy_option_next(NULL); o; diff --git a/vendor/curl/tests/libtest/lib1912.c b/vendor/curl/tests/libtest/lib1912.c index 7aa2bb9adea..dd3e6388165 100644 --- a/vendor/curl/tests/libtest/lib1912.c +++ b/vendor/curl/tests/libtest/lib1912.c @@ -21,17 +21,15 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" #define print_err(name, exp) \ curl_mfprintf(stderr, "Type mismatch for CURLOPT_%s (expected %s)\n", \ - name, exp); + name, exp) -CURLcode test(char *URL) +static CURLcode test_lib1912(const char *URL) { /* Only test if GCC typechecking is available */ int error = 0; diff --git a/vendor/curl/tests/libtest/lib1913.c b/vendor/curl/tests/libtest/lib1913.c index 84684200574..e0519aef296 100644 --- a/vendor/curl/tests/libtest/lib1913.c +++ b/vendor/curl/tests/libtest/lib1913.c @@ -21,13 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1913(const char *URL) { CURLcode ret = CURLE_OK; CURL *hnd; diff --git a/vendor/curl/tests/libtest/lib1915.c b/vendor/curl/tests/libtest/lib1915.c index 02c225a3237..c4cc39455fe 100644 --- a/vendor/curl/tests/libtest/lib1915.c +++ b/vendor/curl/tests/libtest/lib1915.c @@ -21,32 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "testtrace.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -struct entry { - const char *name; - const char *exp; -}; - -static const struct entry preload_hosts[] = { -#if (SIZEOF_TIME_T < 5) - { "1.example.com", "20370320 01:02:03" }, - { "2.example.com", "20370320 03:02:01" }, - { "3.example.com", "20370319 01:02:03" }, -#else - { "1.example.com", "25250320 01:02:03" }, - { "2.example.com", "25250320 03:02:01" }, - { "3.example.com", "25250319 01:02:03" }, -#endif - { "4.example.com", "" }, - { NULL, NULL } /* end of list marker */ -}; - struct state { int index; }; @@ -55,6 +34,25 @@ struct state { static CURLSTScode hstsread(CURL *easy, struct curl_hstsentry *e, void *userp) { + struct entry { + const char *name; + const char *exp; + }; + + static const struct entry preload_hosts[] = { +#if (SIZEOF_TIME_T < 5) + { "1.example.com", "20370320 01:02:03" }, + { "2.example.com", "20370320 03:02:01" }, + { "3.example.com", "20370319 01:02:03" }, +#else + { "1.example.com", "25250320 01:02:03" }, + { "2.example.com", "25250320 03:02:01" }, + { "3.example.com", "25250319 01:02:03" }, +#endif + { "4.example.com", "" }, + { NULL, NULL } /* end of list marker */ + }; + const char *host; const char *expire; struct state *s = (struct state *)userp; @@ -97,7 +95,7 @@ static CURLSTScode hstswrite(CURL *easy, struct curl_hstsentry *e, * Read/write HSTS cache entries via callback. */ -CURLcode test(char *URL) +static CURLcode test_lib1915(const char *URL) { CURLcode res = CURLE_OK; CURL *hnd; @@ -105,8 +103,8 @@ CURLcode test(char *URL) global_init(CURL_GLOBAL_ALL); - libtest_debug_config.nohex = 1; - libtest_debug_config.tracetime = 1; + debug_config.nohex = TRUE; + debug_config.tracetime = TRUE; easy_init(hnd); easy_setopt(hnd, CURLOPT_URL, URL); @@ -116,7 +114,7 @@ CURLcode test(char *URL) easy_setopt(hnd, CURLOPT_HSTSWRITEFUNCTION, hstswrite); easy_setopt(hnd, CURLOPT_HSTSWRITEDATA, &st); easy_setopt(hnd, CURLOPT_HSTS_CTRL, CURLHSTS_ENABLE); - easy_setopt(hnd, CURLOPT_DEBUGDATA, &libtest_debug_config); + easy_setopt(hnd, CURLOPT_DEBUGDATA, &debug_config); easy_setopt(hnd, CURLOPT_DEBUGFUNCTION, libtest_debug_cb); easy_setopt(hnd, CURLOPT_VERBOSE, 1L); res = curl_easy_perform(hnd); @@ -135,7 +133,7 @@ CURLcode test(char *URL) easy_setopt(hnd, CURLOPT_HSTSWRITEFUNCTION, hstswrite); easy_setopt(hnd, CURLOPT_HSTSWRITEDATA, &st); easy_setopt(hnd, CURLOPT_HSTS_CTRL, CURLHSTS_ENABLE); - easy_setopt(hnd, CURLOPT_DEBUGDATA, &libtest_debug_config); + easy_setopt(hnd, CURLOPT_DEBUGDATA, &debug_config); easy_setopt(hnd, CURLOPT_DEBUGFUNCTION, libtest_debug_cb); easy_setopt(hnd, CURLOPT_VERBOSE, 1L); res = curl_easy_perform(hnd); diff --git a/vendor/curl/tests/libtest/lib1916.c b/vendor/curl/tests/libtest/lib1916.c index b8655191eee..24583ab8a18 100644 --- a/vendor/curl/tests/libtest/lib1916.c +++ b/vendor/curl/tests/libtest/lib1916.c @@ -21,12 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "warnless.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1916(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; @@ -39,12 +38,13 @@ CURLcode test(char *URL) curl = curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, URL); -#ifdef LIB1917 - /* without any postfields set! */ - curl_easy_setopt(curl, CURLOPT_POST, 1L); -#else - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, ""); -#endif + if(testnum == 1917) { + /* without any postfields set! */ + curl_easy_setopt(curl, CURLOPT_POST, 1L); + } + else { + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, ""); + } res = curl_easy_perform(curl); if(res) { curl_mprintf("res: %d\n", res); diff --git a/vendor/curl/tests/libtest/lib1918.c b/vendor/curl/tests/libtest/lib1918.c index 359c64e4727..86fa84c92f5 100644 --- a/vendor/curl/tests/libtest/lib1918.c +++ b/vendor/curl/tests/libtest/lib1918.c @@ -21,13 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1918(const char *URL) { const struct curl_easyoption *o; (void)URL; diff --git a/vendor/curl/tests/libtest/lib1919.c b/vendor/curl/tests/libtest/lib1919.c index 68ce7a194bc..a619850dc71 100644 --- a/vendor/curl/tests/libtest/lib1919.c +++ b/vendor/curl/tests/libtest/lib1919.c @@ -21,13 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1919(const char *URL) { CURLcode res = CURLE_OK; CURL *curl; diff --git a/vendor/curl/tests/libtest/lib1933.c b/vendor/curl/tests/libtest/lib1933.c index e5d2af5bf61..bdd914a641e 100644 --- a/vendor/curl/tests/libtest/lib1933.c +++ b/vendor/curl/tests/libtest/lib1933.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1933(const char *URL) { CURL *curl; CURLcode res = TEST_ERR_MAJOR_BAD; diff --git a/vendor/curl/tests/libtest/lib1934.c b/vendor/curl/tests/libtest/lib1934.c index 92c442af468..2cffaa9bc79 100644 --- a/vendor/curl/tests/libtest/lib1934.c +++ b/vendor/curl/tests/libtest/lib1934.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1934(const char *URL) { CURL *curl; CURLcode res = TEST_ERR_MAJOR_BAD; diff --git a/vendor/curl/tests/libtest/lib1935.c b/vendor/curl/tests/libtest/lib1935.c index 7efdeac219e..4f6a1ebb731 100644 --- a/vendor/curl/tests/libtest/lib1935.c +++ b/vendor/curl/tests/libtest/lib1935.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1935(const char *URL) { CURL *curl; CURLcode res = TEST_ERR_MAJOR_BAD; diff --git a/vendor/curl/tests/libtest/lib1936.c b/vendor/curl/tests/libtest/lib1936.c index 83124840b66..438cf92c58e 100644 --- a/vendor/curl/tests/libtest/lib1936.c +++ b/vendor/curl/tests/libtest/lib1936.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1936(const char *URL) { CURL *curl; CURLcode res = TEST_ERR_MAJOR_BAD; diff --git a/vendor/curl/tests/libtest/lib1937.c b/vendor/curl/tests/libtest/lib1937.c index 1d1e093da72..4903f7409a5 100644 --- a/vendor/curl/tests/libtest/lib1937.c +++ b/vendor/curl/tests/libtest/lib1937.c @@ -21,12 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ - -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1937(const char *URL) { CURL *curl; CURLcode res = TEST_ERR_MAJOR_BAD; diff --git a/vendor/curl/tests/libtest/lib1938.c b/vendor/curl/tests/libtest/lib1938.c index 7084d95c032..c0bfb6b8ced 100644 --- a/vendor/curl/tests/libtest/lib1938.c +++ b/vendor/curl/tests/libtest/lib1938.c @@ -21,12 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ - -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1938(const char *URL) { CURL *curl; CURLcode res = TEST_ERR_MAJOR_BAD; diff --git a/vendor/curl/tests/libtest/lib1939.c b/vendor/curl/tests/libtest/lib1939.c index 680b5c23634..61199900df4 100644 --- a/vendor/curl/tests/libtest/lib1939.c +++ b/vendor/curl/tests/libtest/lib1939.c @@ -21,12 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ - -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1939(const char *URL) { CURLM *multi; CURL *easy; diff --git a/vendor/curl/tests/libtest/lib1940.c b/vendor/curl/tests/libtest/lib1940.c index c90a3e0a53b..50f4010e94e 100644 --- a/vendor/curl/tests/libtest/lib1940.c +++ b/vendor/curl/tests/libtest/lib1940.c @@ -21,50 +21,51 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ - -#include "test.h" +#include "first.h" #include "memdebug.h" -static const char *testdata[]={ - "daTE", - "Server", - "content-type", - "content-length", - "location", - "set-cookie", - "silly-thing", - "fold", - "blank", - "Blank2", - NULL -}; - -#ifdef LIB1946 -#define HEADER_REQUEST 0 -#else -#define HEADER_REQUEST -1 -#endif +static size_t t1940_write_cb(char *data, size_t n, size_t l, void *userp) +{ + /* take care of the data here, ignored in this example */ + (void)data; + (void)userp; + return n*l; +} -static void showem(CURL *easy, unsigned int type) +static void t1940_showem(CURL *easy, int header_request, unsigned int type) { + static const char *testdata[] = { + "daTE", + "Server", + "content-type", + "content-length", + "location", + "set-cookie", + "silly-thing", + "fold", + "blank", + "Blank2", + NULL + }; + int i; struct curl_header *header; for(i = 0; testdata[i]; i++) { - if(CURLHE_OK == curl_easy_header(easy, testdata[i], 0, type, - HEADER_REQUEST, &header)) { + if(CURLHE_OK == curl_easy_header(easy, testdata[i], 0, + type, header_request, &header)) { if(header->amount > 1) { /* more than one, iterate over them */ size_t index = 0; size_t amount = header->amount; do { - curl_mprintf("- %s == %s (%u/%u)\n", header->name, header->value, - (int)index, (int)amount); + curl_mprintf("- %s == %s (%zu/%zu)\n", header->name, header->value, + index, amount); if(++index == amount) break; - if(CURLHE_OK != curl_easy_header(easy, testdata[i], index, type, - HEADER_REQUEST, &header)) + if(CURLHE_OK != curl_easy_header(easy, testdata[i], index, + type, header_request, &header)) break; } while(1); } @@ -76,25 +77,26 @@ static void showem(CURL *easy, unsigned int type) } } -static size_t write_cb(char *data, size_t n, size_t l, void *userp) -{ - /* take care of the data here, ignored in this example */ - (void)data; - (void)userp; - return n*l; -} -CURLcode test(char *URL) +static CURLcode test_lib1940(const char *URL) { CURL *easy = NULL; CURLcode res = CURLE_OK; + int header_request; + if(testnum == 1946) { + header_request = 0; + } + else { + header_request = -1; + } + global_init(CURL_GLOBAL_DEFAULT); easy_init(easy); easy_setopt(easy, CURLOPT_URL, URL); easy_setopt(easy, CURLOPT_VERBOSE, 1L); easy_setopt(easy, CURLOPT_FOLLOWLOCATION, 1L); /* ignores any content */ - easy_setopt(easy, CURLOPT_WRITEFUNCTION, write_cb); + easy_setopt(easy, CURLOPT_WRITEFUNCTION, t1940_write_cb); /* if there's a proxy set, use it */ if(libtest_arg2 && *libtest_arg2) { @@ -105,13 +107,13 @@ CURLcode test(char *URL) if(res) goto test_cleanup; - showem(easy, CURLH_HEADER); + t1940_showem(easy, header_request, CURLH_HEADER); if(libtest_arg2 && *libtest_arg2) { /* now show connect headers only */ - showem(easy, CURLH_CONNECT); + t1940_showem(easy, header_request, CURLH_CONNECT); } - showem(easy, CURLH_1XX); - showem(easy, CURLH_TRAILER); + t1940_showem(easy, header_request, CURLH_1XX); + t1940_showem(easy, header_request, CURLH_TRAILER); test_cleanup: curl_easy_cleanup(easy); diff --git a/vendor/curl/tests/libtest/lib1945.c b/vendor/curl/tests/libtest/lib1945.c index 5a4361fbd14..6e693bda625 100644 --- a/vendor/curl/tests/libtest/lib1945.c +++ b/vendor/curl/tests/libtest/lib1945.c @@ -21,32 +21,32 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ - -#include "test.h" +#include "first.h" #include "memdebug.h" -static void showem(CURL *easy, unsigned int type) +static void t1945_showem(CURL *easy, unsigned int type) { struct curl_header *header = NULL; struct curl_header *prev = NULL; /* !checksrc! disable EQUALSNULL 1 */ while((header = curl_easy_nextheader(easy, type, 0, prev)) != NULL) { - curl_mprintf(" %s == %s (%u/%u)\n", header->name, header->value, - (int)header->index, (int)header->amount); + curl_mprintf(" %s == %s (%zu/%zu)\n", header->name, header->value, + header->index, header->amount); prev = header; } } -static size_t write_cb(char *data, size_t n, size_t l, void *userp) +static size_t t1945_write_cb(char *data, size_t n, size_t l, void *userp) { /* take care of the data here, ignored in this example */ (void)data; (void)userp; return n*l; } -CURLcode test(char *URL) + +static CURLcode test_lib1945(const char *URL) { CURL *easy; CURLcode res = CURLE_OK; @@ -58,7 +58,7 @@ CURLcode test(char *URL) curl_easy_setopt(easy, CURLOPT_VERBOSE, 1L); curl_easy_setopt(easy, CURLOPT_FOLLOWLOCATION, 1L); /* ignores any content */ - curl_easy_setopt(easy, CURLOPT_WRITEFUNCTION, write_cb); + curl_easy_setopt(easy, CURLOPT_WRITEFUNCTION, t1945_write_cb); /* if there's a proxy set, use it */ if(libtest_arg2 && *libtest_arg2) { @@ -69,7 +69,7 @@ CURLcode test(char *URL) if(res) { curl_mprintf("badness: %d\n", res); } - showem(easy, CURLH_CONNECT|CURLH_HEADER|CURLH_TRAILER|CURLH_1XX); + t1945_showem(easy, CURLH_CONNECT|CURLH_HEADER|CURLH_TRAILER|CURLH_1XX); test_cleanup: curl_easy_cleanup(easy); diff --git a/vendor/curl/tests/libtest/lib1947.c b/vendor/curl/tests/libtest/lib1947.c index 3288939fca3..19fbcb7af41 100644 --- a/vendor/curl/tests/libtest/lib1947.c +++ b/vendor/curl/tests/libtest/lib1947.c @@ -21,19 +21,19 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ - -#include "test.h" +#include "first.h" #include "memdebug.h" -static size_t writecb(char *data, size_t n, size_t l, void *userp) +static size_t t1947_write_cb(char *data, size_t n, size_t l, void *userp) { /* ignore the data */ (void)data; (void)userp; return n*l; } -CURLcode test(char *URL) + +static CURLcode test_lib1947(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; @@ -47,7 +47,7 @@ CURLcode test(char *URL) /* perform a request that involves redirection */ easy_setopt(curl, CURLOPT_URL, URL); - easy_setopt(curl, CURLOPT_WRITEFUNCTION, writecb); + easy_setopt(curl, CURLOPT_WRITEFUNCTION, t1947_write_cb); easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); res = curl_easy_perform(curl); if(res) { diff --git a/vendor/curl/tests/libtest/lib1948.c b/vendor/curl/tests/libtest/lib1948.c index 766b1ecd559..2a138ac6955 100644 --- a/vendor/curl/tests/libtest/lib1948.c +++ b/vendor/curl/tests/libtest/lib1948.c @@ -21,12 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ - -#include "test.h" +#include "first.h" typedef struct { - char *buf; + const char *buf; size_t len; } put_buffer; @@ -41,11 +40,11 @@ static size_t put_callback(char *ptr, size_t size, size_t nmemb, void *stream) return tocopy; } -CURLcode test(char *URL) +static CURLcode test_lib1948(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; - const char *testput = "This is test PUT data\n"; + static const char *testput = "This is test PUT data\n"; put_buffer pbuf; curl_global_init(CURL_GLOBAL_DEFAULT); @@ -56,7 +55,7 @@ CURLcode test(char *URL) easy_setopt(curl, CURLOPT_UPLOAD, 1L); easy_setopt(curl, CURLOPT_HEADER, 1L); easy_setopt(curl, CURLOPT_READFUNCTION, put_callback); - pbuf.buf = (char *)CURL_UNCONST(testput); + pbuf.buf = testput; pbuf.len = strlen(testput); easy_setopt(curl, CURLOPT_READDATA, &pbuf); easy_setopt(curl, CURLOPT_INFILESIZE, (long)strlen(testput)); diff --git a/vendor/curl/tests/libtest/lib1955.c b/vendor/curl/tests/libtest/lib1955.c index ff496f7a622..e47a52275e7 100644 --- a/vendor/curl/tests/libtest/lib1955.c +++ b/vendor/curl/tests/libtest/lib1955.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1955(const char *URL) { CURL *curl; CURLcode res = TEST_ERR_MAJOR_BAD; diff --git a/vendor/curl/tests/libtest/lib1956.c b/vendor/curl/tests/libtest/lib1956.c index 91402785848..0f1c72e3d2e 100644 --- a/vendor/curl/tests/libtest/lib1956.c +++ b/vendor/curl/tests/libtest/lib1956.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1956(const char *URL) { CURL *curl; CURLcode res = TEST_ERR_MAJOR_BAD; diff --git a/vendor/curl/tests/libtest/lib1957.c b/vendor/curl/tests/libtest/lib1957.c index 37e30322663..8eeed09b7c3 100644 --- a/vendor/curl/tests/libtest/lib1957.c +++ b/vendor/curl/tests/libtest/lib1957.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1957(const char *URL) { CURL *curl; CURLcode res = TEST_ERR_MAJOR_BAD; diff --git a/vendor/curl/tests/libtest/lib1958.c b/vendor/curl/tests/libtest/lib1958.c index a276b734ef4..7a94c76709a 100644 --- a/vendor/curl/tests/libtest/lib1958.c +++ b/vendor/curl/tests/libtest/lib1958.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1958(const char *URL) { CURL *curl; CURLcode res = TEST_ERR_MAJOR_BAD; diff --git a/vendor/curl/tests/libtest/lib1959.c b/vendor/curl/tests/libtest/lib1959.c index cddefbb0950..d718149772e 100644 --- a/vendor/curl/tests/libtest/lib1959.c +++ b/vendor/curl/tests/libtest/lib1959.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1959(const char *URL) { CURL *curl; CURLcode res = TEST_ERR_MAJOR_BAD; diff --git a/vendor/curl/tests/libtest/lib1960.c b/vendor/curl/tests/libtest/lib1960.c index 509515e3cdb..5cdc0224260 100644 --- a/vendor/curl/tests/libtest/lib1960.c +++ b/vendor/curl/tests/libtest/lib1960.c @@ -21,16 +21,13 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #ifdef HAVE_INET_PTON #ifdef HAVE_NETINET_IN_H #include #endif -#ifdef HAVE_SYS_SOCKET_H -#include -#endif #ifdef HAVE_ARPA_INET_H #include #endif @@ -67,7 +64,7 @@ static int sockopt_cb(void *clientp, return CURL_SOCKOPT_ALREADY_CONNECTED; } -#if defined(__AMIGA__) +#ifdef __AMIGA__ #define my_inet_pton(x,y,z) inet_pton(x,(unsigned char *)y,z) #else #define my_inet_pton(x,y,z) inet_pton(x,y,z) @@ -75,7 +72,7 @@ static int sockopt_cb(void *clientp, /* Expected args: URL IP PORT */ -CURLcode test(char *URL) +static CURLcode test_lib1960(const char *URL) { CURL *curl = NULL; CURLcode res = TEST_ERR_MAJOR_BAD; @@ -147,7 +144,7 @@ CURLcode test(char *URL) return res; } #else -CURLcode test(char *URL) +static CURLcode test_lib1960(const char *URL) { (void)URL; curl_mprintf("lacks inet_pton\n"); diff --git a/vendor/curl/tests/libtest/lib1964.c b/vendor/curl/tests/libtest/lib1964.c index ab8cbd750ff..cbad31dcc00 100644 --- a/vendor/curl/tests/libtest/lib1964.c +++ b/vendor/curl/tests/libtest/lib1964.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1964(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; diff --git a/vendor/curl/tests/libtest/lib1970.c b/vendor/curl/tests/libtest/lib1970.c index 3131f9d303c..5ba51f6a58f 100644 --- a/vendor/curl/tests/libtest/lib1970.c +++ b/vendor/curl/tests/libtest/lib1970.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1970(const char *URL) { CURL *curl; CURLcode res = TEST_ERR_MAJOR_BAD; diff --git a/vendor/curl/tests/libtest/lib1971.c b/vendor/curl/tests/libtest/lib1971.c index c36a0c2bc6d..03b254c1c57 100644 --- a/vendor/curl/tests/libtest/lib1971.c +++ b/vendor/curl/tests/libtest/lib1971.c @@ -21,21 +21,20 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -static size_t read_callback(char *buffer, size_t size, size_t nitems, - void *userdata) +static size_t t1971_read_cb(char *ptr, size_t size, size_t nitems, void *userp) { - (void)buffer; /* unused */ + (void)ptr; /* unused */ (void)size; /* unused */ (void)nitems; /* unused */ - (void)userdata; /* unused */ + (void)userp; /* unused */ return 0; } -CURLcode test(char *URL) +static CURLcode test_lib1971(const char *URL) { CURL *curl; CURLcode res = TEST_ERR_MAJOR_BAD; @@ -55,7 +54,7 @@ CURLcode test(char *URL) } test_setopt(curl, CURLOPT_UPLOAD, 1L); - test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + test_setopt(curl, CURLOPT_READFUNCTION, t1971_read_cb); test_setopt(curl, CURLOPT_VERBOSE, 1L); test_setopt(curl, CURLOPT_AWS_SIGV4, "aws:amz:us-east-1:s3"); test_setopt(curl, CURLOPT_USERPWD, "xxx"); diff --git a/vendor/curl/tests/libtest/lib1972.c b/vendor/curl/tests/libtest/lib1972.c index d711e9b3a5e..ec9c9b06988 100644 --- a/vendor/curl/tests/libtest/lib1972.c +++ b/vendor/curl/tests/libtest/lib1972.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1972(const char *URL) { CURL *curl; curl_mime *mime = NULL; diff --git a/vendor/curl/tests/libtest/lib1973.c b/vendor/curl/tests/libtest/lib1973.c index d4b5155c477..e887e80c2e0 100644 --- a/vendor/curl/tests/libtest/lib1973.c +++ b/vendor/curl/tests/libtest/lib1973.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1973(const char *URL) { CURL *curl; CURLcode res = TEST_ERR_MAJOR_BAD; diff --git a/vendor/curl/tests/libtest/lib1974.c b/vendor/curl/tests/libtest/lib1974.c index 0cf96261034..b2d0b59450e 100644 --- a/vendor/curl/tests/libtest/lib1974.c +++ b/vendor/curl/tests/libtest/lib1974.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1974(const char *URL) { CURL *curl; CURLcode res = TEST_ERR_MAJOR_BAD; diff --git a/vendor/curl/tests/libtest/lib1975.c b/vendor/curl/tests/libtest/lib1975.c index b9fdc84786e..95db9ae58df 100644 --- a/vendor/curl/tests/libtest/lib1975.c +++ b/vendor/curl/tests/libtest/lib1975.c @@ -21,21 +21,20 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -static size_t read_callback(char *buffer, size_t size, size_t nitems, - void *userdata) +static size_t t1975_read_cb(char *ptr, size_t size, size_t nitems, void *userp) { - (void)buffer; /* unused */ + (void)ptr; /* unused */ (void)size; /* unused */ (void)nitems; /* unused */ - (void)userdata; /* unused */ + (void)userp; /* unused */ return 0; } -CURLcode test(char *URL) +static CURLcode test_lib1975(const char *URL) { CURL *curl; CURLcode res = TEST_ERR_MAJOR_BAD; @@ -55,7 +54,7 @@ CURLcode test(char *URL) } test_setopt(curl, CURLOPT_UPLOAD, 1L); - test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + test_setopt(curl, CURLOPT_READFUNCTION, t1975_read_cb); test_setopt(curl, CURLOPT_VERBOSE, 1L); test_setopt(curl, CURLOPT_AWS_SIGV4, "aws:amz:us-east-1:s3"); test_setopt(curl, CURLOPT_USERPWD, "xxx"); diff --git a/vendor/curl/tests/libtest/lib1977.c b/vendor/curl/tests/libtest/lib1977.c index 5f030f493e0..dae8bcbae70 100644 --- a/vendor/curl/tests/libtest/lib1977.c +++ b/vendor/curl/tests/libtest/lib1977.c @@ -21,13 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1977(const char *URL) { CURLcode res = CURLE_OK; CURLU *curlu = curl_url(); diff --git a/vendor/curl/tests/libtest/lib1978.c b/vendor/curl/tests/libtest/lib1978.c index 2647019b89a..113f06da8f3 100644 --- a/vendor/curl/tests/libtest/lib1978.c +++ b/vendor/curl/tests/libtest/lib1978.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib1978(const char *URL) { CURL *curl; CURLcode res = TEST_ERR_MAJOR_BAD; diff --git a/vendor/curl/tests/libtest/lib2023.c b/vendor/curl/tests/libtest/lib2023.c new file mode 100644 index 00000000000..8c181fa0933 --- /dev/null +++ b/vendor/curl/tests/libtest/lib2023.c @@ -0,0 +1,150 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 + * + ***************************************************************************/ +/* argv1 = URL + * argv2 = main auth type + * argv3 = second auth type + */ + +#include "first.h" + +#include "memdebug.h" + +static CURLcode send_request(CURL *curl, const char *url, int seq, + long auth_scheme, const char *userpwd) +{ + CURLcode res; + size_t len = strlen(url) + 4 + 1; + char *full_url = malloc(len); + if(!full_url) { + curl_mfprintf(stderr, "Not enough memory for full url\n"); + return CURLE_OUT_OF_MEMORY; + } + + curl_msnprintf(full_url, len, "%s%04d", url, seq); + curl_mfprintf(stderr, "Sending new request %d to %s with credential %s " + "(auth %ld)\n", seq, full_url, userpwd, auth_scheme); + test_setopt(curl, CURLOPT_URL, full_url); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_HEADER, 1L); + test_setopt(curl, CURLOPT_HTTPGET, 1L); + test_setopt(curl, CURLOPT_USERPWD, userpwd); + test_setopt(curl, CURLOPT_HTTPAUTH, auth_scheme); + + res = curl_easy_perform(curl); + +test_cleanup: + free(full_url); + return res; +} + +static CURLcode send_wrong_password(CURL *curl, const char *url, int seq, + long auth_scheme) +{ + return send_request(curl, url, seq, auth_scheme, "testuser:wrongpass"); +} + +static CURLcode send_right_password(CURL *curl, const char *url, int seq, + long auth_scheme) +{ + return send_request(curl, url, seq, auth_scheme, "testuser:testpass"); +} + +static long parse_auth_name(const char *arg) +{ + if(!arg) + return CURLAUTH_NONE; + if(curl_strequal(arg, "basic")) + return CURLAUTH_BASIC; + if(curl_strequal(arg, "digest")) + return CURLAUTH_DIGEST; + if(curl_strequal(arg, "ntlm")) + return CURLAUTH_NTLM; + return CURLAUTH_NONE; +} + +static CURLcode test_lib2023(const char *URL) /* libauthretry */ +{ + CURLcode res; + CURL *curl = NULL; + + long main_auth_scheme = parse_auth_name(libtest_arg2); + long fallback_auth_scheme = parse_auth_name(libtest_arg3); + + if(main_auth_scheme == CURLAUTH_NONE || + fallback_auth_scheme == CURLAUTH_NONE) { + curl_mfprintf(stderr, "auth schemes not found on commandline\n"); + return TEST_ERR_MAJOR_BAD; + } + + if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + curl_mfprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + /* Send wrong password, then right password */ + + curl = curl_easy_init(); + if(!curl) { + curl_mfprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + res = send_wrong_password(curl, URL, 100, main_auth_scheme); + if(res != CURLE_OK) + goto test_cleanup; + + res = send_right_password(curl, URL, 200, fallback_auth_scheme); + if(res != CURLE_OK) + goto test_cleanup; + + curl_easy_cleanup(curl); + + /* Send wrong password twice, then right password */ + curl = curl_easy_init(); + if(!curl) { + curl_mfprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + res = send_wrong_password(curl, URL, 300, main_auth_scheme); + if(res != CURLE_OK) + goto test_cleanup; + + res = send_wrong_password(curl, URL, 400, fallback_auth_scheme); + if(res != CURLE_OK) + goto test_cleanup; + + res = send_right_password(curl, URL, 500, fallback_auth_scheme); + if(res != CURLE_OK) + goto test_cleanup; + +test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} diff --git a/vendor/curl/tests/libtest/lib2032.c b/vendor/curl/tests/libtest/lib2032.c new file mode 100644 index 00000000000..25de34d5302 --- /dev/null +++ b/vendor/curl/tests/libtest/lib2032.c @@ -0,0 +1,236 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "first.h" + +#include "memdebug.h" + +#define MAX_EASY_HANDLES 3 + +static int ntlm_counter[MAX_EASY_HANDLES]; +static CURL *ntlm_easy[MAX_EASY_HANDLES]; +static curl_socket_t ntlm_sockets[MAX_EASY_HANDLES]; +static CURLcode ntlmcb_res = CURLE_OK; + +static size_t callback(char *ptr, size_t size, size_t nmemb, void *data) +{ + ssize_t idx = ((CURL **) data) - ntlm_easy; + curl_socket_t sock; + long longdata; + CURLcode code; + const size_t failure = (size && nmemb) ? 0 : 1; + (void)ptr; + + ntlm_counter[idx] += (int)(size * nmemb); + + /* Get socket being used for this easy handle, otherwise CURL_SOCKET_BAD */ + code = curl_easy_getinfo(ntlm_easy[idx], CURLINFO_LASTSOCKET, &longdata); + + if(CURLE_OK != code) { + curl_mfprintf(stderr, "%s:%d curl_easy_getinfo() failed, " + "with code %d (%s)\n", + __FILE__, __LINE__, code, curl_easy_strerror(code)); + ntlmcb_res = TEST_ERR_MAJOR_BAD; + return failure; + } + if(longdata == -1L) + sock = CURL_SOCKET_BAD; + else + sock = (curl_socket_t)longdata; + + if(sock != CURL_SOCKET_BAD) { + /* Track relationship between this easy handle and the socket. */ + if(ntlm_sockets[idx] == CURL_SOCKET_BAD) { + /* An easy handle without previous socket, record the socket. */ + ntlm_sockets[idx] = sock; + } + else if(sock != ntlm_sockets[idx]) { + /* An easy handle with a socket different to previously + tracked one, log and fail right away. Known bug #37. */ + curl_mfprintf(stderr, "Handle %zd started on socket %" FMT_SOCKET_T + " and moved to %" FMT_SOCKET_T "\n", + idx, ntlm_sockets[idx], sock); + ntlmcb_res = TEST_ERR_MAJOR_BAD; + return failure; + } + } + return size * nmemb; +} + +static CURLcode test_lib2032(const char *URL) /* libntlmconnect */ +{ + enum HandleState { + ReadyForNewHandle, + NeedSocketForNewHandle, + NoMoreHandles + }; + + CURLcode res = CURLE_OK; + CURLM *multi = NULL; + int running; + int i; + int num_handles = 0; + enum HandleState state = ReadyForNewHandle; + size_t urllen = strlen(URL) + 4 + 1; + char *full_url = malloc(urllen); + + start_test_timing(); + + if(!full_url) { + curl_mfprintf(stderr, "Not enough memory for full url\n"); + return TEST_ERR_MAJOR_BAD; + } + + for(i = 0; i < MAX_EASY_HANDLES; ++i) { + ntlm_easy[i] = NULL; + ntlm_sockets[i] = CURL_SOCKET_BAD; + } + + res_global_init(CURL_GLOBAL_ALL); + if(res) { + free(full_url); + return res; + } + + multi_init(multi); + + for(;;) { + struct timeval interval; + fd_set fdread; + fd_set fdwrite; + fd_set fdexcep; + long timeout = -99; + int maxfd = -99; + bool found_new_socket = FALSE; + + /* Start a new handle if we aren't at the max */ + if(state == ReadyForNewHandle) { + easy_init(ntlm_easy[num_handles]); + + if(num_handles % 3 == 2) { + curl_msnprintf(full_url, urllen, "%s0200", URL); + easy_setopt(ntlm_easy[num_handles], CURLOPT_HTTPAUTH, CURLAUTH_NTLM); + } + else { + curl_msnprintf(full_url, urllen, "%s0100", URL); + easy_setopt(ntlm_easy[num_handles], CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + } + easy_setopt(ntlm_easy[num_handles], CURLOPT_FRESH_CONNECT, 1L); + easy_setopt(ntlm_easy[num_handles], CURLOPT_URL, full_url); + easy_setopt(ntlm_easy[num_handles], CURLOPT_VERBOSE, 1L); + easy_setopt(ntlm_easy[num_handles], CURLOPT_HTTPGET, 1L); + easy_setopt(ntlm_easy[num_handles], CURLOPT_USERPWD, + "testuser:testpass"); + easy_setopt(ntlm_easy[num_handles], CURLOPT_WRITEFUNCTION, callback); + easy_setopt(ntlm_easy[num_handles], CURLOPT_WRITEDATA, + (void *)(ntlm_easy + num_handles)); + easy_setopt(ntlm_easy[num_handles], CURLOPT_HEADER, 1L); + + multi_add_handle(multi, ntlm_easy[num_handles]); + num_handles += 1; + state = NeedSocketForNewHandle; + res = ntlmcb_res; + } + + multi_perform(multi, &running); + + curl_mfprintf(stderr, "%s:%d running %d state %d\n", + __FILE__, __LINE__, running, state); + + abort_on_test_timeout(); + + if(!running && state == NoMoreHandles) + break; /* done */ + + FD_ZERO(&fdread); + FD_ZERO(&fdwrite); + FD_ZERO(&fdexcep); + + multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd); + + /* At this point, maxfd is guaranteed to be greater or equal than -1. */ + + if(state == NeedSocketForNewHandle) { + if(maxfd != -1 && !found_new_socket) { + curl_mfprintf(stderr, + "Warning: socket did not open immediately for new " + "handle (trying again)\n"); + continue; + } + state = num_handles < MAX_EASY_HANDLES ? ReadyForNewHandle + : NoMoreHandles; + curl_mfprintf(stderr, "%s:%d new state %d\n", + __FILE__, __LINE__, state); + } + + multi_timeout(multi, &timeout); + + /* At this point, timeout is guaranteed to be greater or equal than -1. */ + + curl_mfprintf(stderr, "%s:%d num_handles %d timeout %ld running %d\n", + __FILE__, __LINE__, num_handles, timeout, running); + + if(timeout != -1L) { + int itimeout; +#if LONG_MAX > INT_MAX + itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout; +#else + itimeout = (int)timeout; +#endif + interval.tv_sec = itimeout/1000; + interval.tv_usec = (itimeout%1000)*1000; + } + else { + interval.tv_sec = 0; + interval.tv_usec = 5000; + + /* if there's no timeout and we get here on the last handle, we may + already have read the last part of the stream so waiting makes no + sense */ + if(!running && num_handles == MAX_EASY_HANDLES) { + break; + } + } + + select_test(maxfd + 1, &fdread, &fdwrite, &fdexcep, &interval); + + abort_on_test_timeout(); + } + +test_cleanup: + + /* proper cleanup sequence - type PB */ + + for(i = 0; i < MAX_EASY_HANDLES; i++) { + curl_mprintf("Data connection %d: %d\n", i, ntlm_counter[i]); + curl_multi_remove_handle(multi, ntlm_easy[i]); + curl_easy_cleanup(ntlm_easy[i]); + } + + curl_multi_cleanup(multi); + curl_global_cleanup(); + + free(full_url); + + return res; +} diff --git a/vendor/curl/tests/libtest/lib2082.c b/vendor/curl/tests/libtest/lib2082.c new file mode 100644 index 00000000000..093eebda315 --- /dev/null +++ b/vendor/curl/tests/libtest/lib2082.c @@ -0,0 +1,100 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) Max Dymond, + * + * 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 "first.h" + +struct prcs { + int prereq_retcode; + int ipv6; +}; + +static int prereq_callback(void *clientp, + char *conn_primary_ip, + char *conn_local_ip, + int conn_primary_port, + int conn_local_port) +{ + struct prcs *prereq_cb = (struct prcs *)clientp; + + if(prereq_cb->ipv6) { + curl_mprintf("Connected to [%s]\n", conn_primary_ip); + curl_mprintf("Connected from [%s]\n", conn_local_ip); + } + else { + curl_mprintf("Connected to %s\n", conn_primary_ip); + curl_mprintf("Connected from %s\n", conn_local_ip); + } + + curl_mprintf("Remote port = %d\n", conn_primary_port); + curl_mprintf("Local port = %d\n", conn_local_port); + curl_mprintf("Returning = %d\n", prereq_cb->prereq_retcode); + return prereq_cb->prereq_retcode; +} + +static CURLcode test_lib2082(const char *URL) /* libprereq */ +{ + struct prcs prereq_cb; + CURLcode ret = CURLE_OK; + CURL *curl = NULL; + + prereq_cb.prereq_retcode = CURL_PREREQFUNC_OK; + prereq_cb.ipv6 = 0; + + curl_global_init(CURL_GLOBAL_ALL); + curl = curl_easy_init(); + + if(curl) { + if(strstr(URL, "#ipv6")) { + /* The IP addresses should be surrounded by brackets! */ + prereq_cb.ipv6 = 1; + } + if(strstr(URL, "#err")) { + /* Set the callback to exit with failure */ + prereq_cb.prereq_retcode = CURL_PREREQFUNC_ABORT; + } + + curl_easy_setopt(curl, CURLOPT_URL, URL); + curl_easy_setopt(curl, CURLOPT_PREREQFUNCTION, prereq_callback); + curl_easy_setopt(curl, CURLOPT_PREREQDATA, &prereq_cb); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, stderr); + + if(strstr(URL, "#redir")) { + /* Enable follow-location */ + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + } + + ret = curl_easy_perform(curl); + if(ret) { + curl_mfprintf(stderr, + "%s:%d curl_easy_perform() failed with code %d (%s)\n", + __FILE__, __LINE__, ret, curl_easy_strerror(ret)); + goto test_cleanup; + } + } + +test_cleanup: + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return ret; +} diff --git a/vendor/curl/tests/libtest/lib2301.c b/vendor/curl/tests/libtest/lib2301.c index 8a370928a32..cc6c00a1d43 100644 --- a/vendor/curl/tests/libtest/lib2301.c +++ b/vendor/curl/tests/libtest/lib2301.c @@ -21,78 +21,26 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ - -#include "test.h" +#include "first.h" #ifndef CURL_DISABLE_WEBSOCKETS #if 0 - -static CURLcode send_ping(CURL *curl, const char *send_payload) -{ - size_t sent; - CURLcode result = - curl_ws_send(curl, send_payload, strlen(send_payload), &sent, CURLWS_PING); - curl_mfprintf(stderr, - "ws: curl_ws_send returned %d, sent %d\n", result, (int)sent); - - return result; -} - -static CURLcode recv_pong(CURL *curl, const char *expected_payload) -{ - size_t rlen; - unsigned int rflags; - char buffer[256]; - CURLcode result = - curl_ws_recv(curl, buffer, sizeof(buffer), &rlen, &rflags); - if(rflags & CURLWS_PONG) { - int same = 0; - curl_mfprintf(stderr, "ws: got PONG back\n"); - if(rlen == strlen(expected_payload)) { - if(!memcmp(expected_payload, buffer, rlen)) { - curl_mfprintf(stderr, "ws: got the same payload back\n"); - same = 1; - } - } - if(!same) - curl_mfprintf(stderr, "ws: did NOT get the same payload back\n"); - } - else { - curl_mfprintf(stderr, "recv_pong: got %d bytes rflags %x\n", - (int)rlen, rflags); - } - curl_mfprintf(stderr, "ws: curl_ws_recv returned %d, received %d\n", result, - (int)rlen); - return result; -} - -/* just close the connection */ -static void websocket_close(CURL *curl) -{ - size_t sent; - CURLcode result = - curl_ws_send(curl, "", 0, &sent, CURLWS_CLOSE); - curl_mfprintf(stderr, - "ws: curl_ws_send returned %d, sent %d\n", result, (int)sent); -} - -static void websocket(CURL *curl) +static void t2301_websocket(CURL *curl) { int i = 0; curl_mfprintf(stderr, "ws: websocket() starts\n"); do { - if(send_ping(curl, "foobar")) + if(ws_send_ping(curl, "foobar")) return; - if(recv_pong(curl, "foobar")) + if(ws_recv_pong(curl, "foobar")) return; - sleep(2); + curlx_wait_ms(2000); } while(i++ < 10); - websocket_close(curl); + ws_close(curl); } - #endif -static size_t writecb(char *b, size_t size, size_t nitems, void *p) +static size_t t2301_write_cb(char *b, size_t size, size_t nitems, void *p) { CURL *easy = p; unsigned char *buffer = (unsigned char *)b; @@ -102,8 +50,8 @@ static size_t writecb(char *b, size_t size, size_t nitems, void *p) 0x8a, 0x0 }; size_t incoming = nitems; - curl_mfprintf(stderr, "Called CURLOPT_WRITEFUNCTION with %d bytes: ", - (int)nitems); + curl_mfprintf(stderr, "Called CURLOPT_WRITEFUNCTION with %zu bytes: ", + nitems); for(i = 0; i < nitems; i++) curl_mfprintf(stderr, "%02x ", (unsigned char)buffer[i]); curl_mfprintf(stderr, "\n"); @@ -119,9 +67,11 @@ static size_t writecb(char *b, size_t size, size_t nitems, void *p) curl_mfprintf(stderr, "returns error from callback\n"); return nitems; } +#endif -CURLcode test(char *URL) +static CURLcode test_lib2301(const char *URL) { +#ifndef CURL_DISABLE_WEBSOCKETS CURL *curl; CURLcode res = CURLE_OK; @@ -134,22 +84,21 @@ CURLcode test(char *URL) /* use the callback style */ curl_easy_setopt(curl, CURLOPT_USERAGENT, "webbie-sox/3"); curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); - curl_easy_setopt(curl, CURLOPT_WS_OPTIONS, (long)CURLWS_RAW_MODE); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writecb); + curl_easy_setopt(curl, CURLOPT_WS_OPTIONS, CURLWS_RAW_MODE); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, t2301_write_cb); curl_easy_setopt(curl, CURLOPT_WRITEDATA, curl); res = curl_easy_perform(curl); curl_mfprintf(stderr, "curl_easy_perform() returned %d\n", res); #if 0 if(res == CURLE_OK) - websocket(curl); + t2301_websocket(curl); #endif /* always cleanup */ curl_easy_cleanup(curl); } curl_global_cleanup(); return res; -} - -#else /* no WebSockets */ -NO_SUPPORT_BUILT_IN +#else + NO_SUPPORT_BUILT_IN #endif +} diff --git a/vendor/curl/tests/libtest/lib2302.c b/vendor/curl/tests/libtest/lib2302.c index 1207a3a9af1..d72761a8510 100644 --- a/vendor/curl/tests/libtest/lib2302.c +++ b/vendor/curl/tests/libtest/lib2302.c @@ -21,8 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ - -#include "test.h" +#include "first.h" #ifndef CURL_DISABLE_WEBSOCKETS @@ -77,8 +76,7 @@ static size_t add_data(struct ws_data *wd, const char *buf, size_t blen, return blen; } - -static size_t writecb(char *buffer, size_t size, size_t nitems, void *p) +static size_t t2302_write_cb(char *buffer, size_t size, size_t nitems, void *p) { struct ws_data *ws_data = p; size_t incoming = nitems; @@ -92,9 +90,11 @@ static size_t writecb(char *buffer, size_t size, size_t nitems, void *p) curl_mfprintf(stderr, "returns error from callback\n"); return nitems; } +#endif -CURLcode test(char *URL) +static CURLcode test_lib2302(const char *URL) { +#ifndef CURL_DISABLE_WEBSOCKETS CURL *curl; CURLcode res = CURLE_OK; struct ws_data ws_data; @@ -112,7 +112,7 @@ CURLcode test(char *URL) /* use the callback style */ curl_easy_setopt(curl, CURLOPT_USERAGENT, "webbie-sox/3"); curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writecb); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, t2302_write_cb); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ws_data); res = curl_easy_perform(curl); curl_mfprintf(stderr, "curl_easy_perform() returned %d\n", res); @@ -124,8 +124,7 @@ CURLcode test(char *URL) } curl_global_cleanup(); return res; -} - #else -NO_SUPPORT_BUILT_IN + NO_SUPPORT_BUILT_IN #endif +} diff --git a/vendor/curl/tests/libtest/lib2304.c b/vendor/curl/tests/libtest/lib2304.c index 74053538bf4..4a2abe5f7b1 100644 --- a/vendor/curl/tests/libtest/lib2304.c +++ b/vendor/curl/tests/libtest/lib2304.c @@ -21,52 +21,9 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ - -#include "test.h" +#include "first.h" #ifndef CURL_DISABLE_WEBSOCKETS - -static CURLcode send_ping(CURL *curl, const char *send_payload) -{ - size_t sent; - CURLcode result = - curl_ws_send(curl, send_payload, strlen(send_payload), &sent, 0, - CURLWS_PING); - curl_mfprintf(stderr, - "ws: curl_ws_send returned %d, sent %d\n", result, (int)sent); - - return result; -} - -static CURLcode recv_pong(CURL *curl, const char *expected_payload) -{ - size_t rlen; - const struct curl_ws_frame *meta; - char buffer[256]; - CURLcode result = curl_ws_recv(curl, buffer, sizeof(buffer), &rlen, &meta); - if(!result) { - if(meta->flags & CURLWS_PONG) { - int same = 0; - curl_mfprintf(stderr, "ws: got PONG back\n"); - if(rlen == strlen(expected_payload)) { - if(!memcmp(expected_payload, buffer, rlen)) { - curl_mfprintf(stderr, "ws: got the same payload back\n"); - same = 1; - } - } - if(!same) - curl_mfprintf(stderr, "ws: did NOT get the same payload back\n"); - } - else { - curl_mfprintf(stderr, "recv_pong: got %d bytes rflags %x\n", (int)rlen, - meta->flags); - } - } - curl_mfprintf(stderr, "ws: curl_ws_recv returned %d, received %d\n", result, - (int)rlen); - return result; -} - static CURLcode recv_any(CURL *curl) { size_t rlen; @@ -76,42 +33,34 @@ static CURLcode recv_any(CURL *curl) if(result) return result; - curl_mfprintf(stderr, "recv_any: got %u bytes rflags %x\n", (int)rlen, + curl_mfprintf(stderr, "recv_any: got %zu bytes rflags %x\n", rlen, meta->flags); return CURLE_OK; } -/* just close the connection */ -static void websocket_close(CURL *curl) -{ - size_t sent; - CURLcode result = - curl_ws_send(curl, "", 0, &sent, 0, CURLWS_CLOSE); - curl_mfprintf(stderr, - "ws: curl_ws_send returned %d, sent %u\n", result, (int)sent); -} - -static void websocket(CURL *curl) +static void t2304_websocket(CURL *curl) { int i = 0; curl_mfprintf(stderr, "ws: websocket() starts\n"); do { recv_any(curl); curl_mfprintf(stderr, "Send ping\n"); - if(send_ping(curl, "foobar")) + if(ws_send_ping(curl, "foobar")) return; curl_mfprintf(stderr, "Receive pong\n"); - if(recv_pong(curl, "foobar")) { + if(ws_recv_pong(curl, "foobar")) { curl_mprintf("Connection closed\n"); return; } - sleep(2); + curlx_wait_ms(2000); } while(i++ < 10); - websocket_close(curl); + ws_close(curl); } +#endif -CURLcode test(char *URL) +static CURLcode test_lib2304(const char *URL) { +#ifndef CURL_DISABLE_WEBSOCKETS CURL *curl; CURLcode res = CURLE_OK; @@ -128,15 +77,14 @@ CURLcode test(char *URL) res = curl_easy_perform(curl); curl_mfprintf(stderr, "curl_easy_perform() returned %d\n", res); if(res == CURLE_OK) - websocket(curl); + t2304_websocket(curl); /* always cleanup */ curl_easy_cleanup(curl); } curl_global_cleanup(); return res; -} - #else -NO_SUPPORT_BUILT_IN + NO_SUPPORT_BUILT_IN #endif +} diff --git a/vendor/curl/tests/libtest/lib2306.c b/vendor/curl/tests/libtest/lib2306.c index cde75193315..d2832e1cb21 100644 --- a/vendor/curl/tests/libtest/lib2306.c +++ b/vendor/curl/tests/libtest/lib2306.c @@ -21,15 +21,9 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ +#include "first.h" -#include "test.h" -#include "testtrace.h" - -#include - -#define URL2 libtest_arg2 - -CURLcode test(char *URL) +static CURLcode test_lib2306(const char *URL) { /* first a fine GET response, then a bad one */ CURL *cl; @@ -45,7 +39,7 @@ CURLcode test(char *URL) goto test_cleanup; /* reuse handle, do a second transfer */ - easy_setopt(cl, CURLOPT_URL, URL2); + easy_setopt(cl, CURLOPT_URL, libtest_arg2); res = curl_easy_perform(cl); test_cleanup: diff --git a/vendor/curl/tests/libtest/lib2308.c b/vendor/curl/tests/libtest/lib2308.c index 68f1357d3f8..1f7e6a4a2f4 100644 --- a/vendor/curl/tests/libtest/lib2308.c +++ b/vendor/curl/tests/libtest/lib2308.c @@ -21,11 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ - -#include "test.h" -#include "testtrace.h" - -#include +#include "first.h" static size_t cb_curl(char *buffer, size_t size, size_t nmemb, void *userp) { @@ -36,7 +32,7 @@ static size_t cb_curl(char *buffer, size_t size, size_t nmemb, void *userp) return CURL_WRITEFUNC_ERROR; } -CURLcode test(char *URL) +static CURLcode test_lib2308(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; diff --git a/vendor/curl/tests/libtest/lib2309.c b/vendor/curl/tests/libtest/lib2309.c index 23519c29c64..afc92803d01 100644 --- a/vendor/curl/tests/libtest/lib2309.c +++ b/vendor/curl/tests/libtest/lib2309.c @@ -21,11 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ - -#include "test.h" -#include "testtrace.h" - -#include +#include "first.h" static size_t cb_ignore(char *buffer, size_t size, size_t nmemb, void *userp) { @@ -36,7 +32,7 @@ static size_t cb_ignore(char *buffer, size_t size, size_t nmemb, void *userp) return CURL_WRITEFUNC_ERROR; } -CURLcode test(char *URL) +static CURLcode test_lib2309(const char *URL) { CURL *curl; CURL *curldupe; @@ -49,7 +45,7 @@ CURLcode test(char *URL) curl_easy_setopt(curl, CURLOPT_URL, URL); curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); curl_easy_setopt(curl, CURLOPT_PROXY, libtest_arg3); - curl_easy_setopt(curl, CURLOPT_NETRC, (long)CURL_NETRC_REQUIRED); + curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_REQUIRED); curl_easy_setopt(curl, CURLOPT_NETRC_FILE, libtest_arg2); curldupe = curl_easy_duphandle(curl); diff --git a/vendor/curl/tests/libtest/lib2402.c b/vendor/curl/tests/libtest/lib2402.c index 9e3e8fba790..ef3dc226a09 100644 --- a/vendor/curl/tests/libtest/lib2402.c +++ b/vendor/curl/tests/libtest/lib2402.c @@ -21,28 +21,22 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -#define NUM_HANDLES 4 - -CURLcode test(char *URL) +static CURLcode test_lib2402(const char *URL) { CURLcode res = CURLE_OK; CURL *curl[NUM_HANDLES] = {0}; int running; CURLM *m = NULL; - int i; + size_t i; char target_url[256]; char dnsentry[256]; struct curl_slist *slist = NULL; - char *port = libtest_arg3; - char *address = libtest_arg2; + const char *port = libtest_arg3; + const char *address = libtest_arg2; (void)URL; @@ -63,13 +57,13 @@ CURLcode test(char *URL) multi_setopt(m, CURLMOPT_MAXCONNECTS, 1L); - /* get NUM_HANDLES easy handles */ - for(i = 0; i < NUM_HANDLES; i++) { + /* get each easy handle */ + for(i = 0; i < CURL_ARRAYSIZE(curl); i++) { /* get an easy handle */ easy_init(curl[i]); /* specify target */ curl_msnprintf(target_url, sizeof(target_url), - "https://localhost:%s/path/2402%04i", + "https://localhost:%s/path/2402%04zu", port, i + 1); target_url[sizeof(target_url) - 1] = '\0'; easy_setopt(curl[i], CURLOPT_URL, target_url); @@ -90,7 +84,7 @@ CURLcode test(char *URL) curl_mfprintf(stderr, "Start at URL 0\n"); - for(i = 0; i < NUM_HANDLES; i++) { + for(i = 0; i < CURL_ARRAYSIZE(curl); i++) { /* add handle to multi */ multi_add_handle(m, curl[i]); @@ -121,14 +115,14 @@ CURLcode test(char *URL) abort_on_test_timeout(); } - wait_ms(1); /* to ensure different end times */ + curlx_wait_ms(1); /* to ensure different end times */ } test_cleanup: /* proper cleanup sequence - type PB */ - for(i = 0; i < NUM_HANDLES; i++) { + for(i = 0; i < CURL_ARRAYSIZE(curl); i++) { curl_multi_remove_handle(m, curl[i]); curl_easy_cleanup(curl[i]); } diff --git a/vendor/curl/tests/libtest/lib2404.c b/vendor/curl/tests/libtest/lib2404.c index c4d8e5df58b..8551957e0b4 100644 --- a/vendor/curl/tests/libtest/lib2404.c +++ b/vendor/curl/tests/libtest/lib2404.c @@ -21,28 +21,22 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -#define NUM_HANDLES 4 - -CURLcode test(char *URL) +static CURLcode test_lib2404(const char *URL) { CURLcode res = CURLE_OK; CURL *curl[NUM_HANDLES] = {0}; int running; CURLM *m = NULL; - int i; + size_t i; char target_url[256]; char dnsentry[256]; struct curl_slist *slist = NULL; - char *port = libtest_arg3; - char *address = libtest_arg2; + const char *port = libtest_arg3; + const char *address = libtest_arg2; (void)URL; @@ -63,13 +57,13 @@ CURLcode test(char *URL) multi_setopt(m, CURLMOPT_MAXCONNECTS, 1L); - /* get NUM_HANDLES easy handles */ - for(i = 0; i < NUM_HANDLES; i++) { + /* get each easy handle */ + for(i = 0; i < CURL_ARRAYSIZE(curl); i++) { /* get an easy handle */ easy_init(curl[i]); /* specify target */ curl_msnprintf(target_url, sizeof(target_url), - "https://localhost:%s/path/2404%04i", + "https://localhost:%s/path/2404%04zu", port, i + 1); target_url[sizeof(target_url) - 1] = '\0'; easy_setopt(curl[i], CURLOPT_URL, target_url); @@ -87,12 +81,12 @@ CURLcode test(char *URL) easy_setopt(curl[i], CURLOPT_RESOLVE, slist); - easy_setopt(curl[i], CURLOPT_STREAM_WEIGHT, (long)128 + i); + easy_setopt(curl[i], CURLOPT_STREAM_WEIGHT, (long)i + 128); } curl_mfprintf(stderr, "Start at URL 0\n"); - for(i = 0; i < NUM_HANDLES; i++) { + for(i = 0; i < CURL_ARRAYSIZE(curl); i++) { /* add handle to multi */ multi_add_handle(m, curl[i]); @@ -123,14 +117,14 @@ CURLcode test(char *URL) abort_on_test_timeout(); } - wait_ms(1); /* to ensure different end times */ + curlx_wait_ms(1); /* to ensure different end times */ } test_cleanup: /* proper cleanup sequence - type PB */ - for(i = 0; i < NUM_HANDLES; i++) { + for(i = 0; i < CURL_ARRAYSIZE(curl); i++) { curl_multi_remove_handle(m, curl[i]); curl_easy_cleanup(curl[i]); } diff --git a/vendor/curl/tests/libtest/lib2405.c b/vendor/curl/tests/libtest/lib2405.c index 3d6919e298e..571a0bcaa80 100644 --- a/vendor/curl/tests/libtest/lib2405.c +++ b/vendor/curl/tests/libtest/lib2405.c @@ -37,14 +37,11 @@ * successfully. */ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" - - /* ---------------------------------------------------------------- */ +/* ---------------------------------------------------------------- */ #define test_check(expected_fds) \ if(res != CURLE_OK) { \ @@ -63,7 +60,7 @@ test_check(expected_fds); \ } while(0) - /* ---------------------------------------------------------------- */ +/* ---------------------------------------------------------------- */ enum { TEST_USE_HTTP1 = 0, @@ -77,7 +74,7 @@ static size_t emptyWriteFunc(void *ptr, size_t size, size_t nmemb, return size * nmemb; } -static CURLcode set_easy(char *URL, CURL *easy, long option) +static CURLcode set_easy(const char *URL, CURL *easy, long option) { CURLcode res = CURLE_OK; @@ -119,7 +116,8 @@ static CURLcode set_easy(char *URL, CURL *easy, long option) return res; } -static CURLcode test_run(char *URL, long option, unsigned int *max_fd_count) +static CURLcode test_run(const char *URL, long option, + unsigned int *max_fd_count) { CURLMcode mc = CURLM_OK; CURLM *multi = NULL; @@ -237,7 +235,7 @@ static CURLcode test_run(char *URL, long option, unsigned int *max_fd_count) if(fd_count_chk < fd_count) { curl_mfprintf(stderr, - "curl_multi_waitfds() sould return the amount of fds " + "curl_multi_waitfds() should return the amount of fds " "needed if enough isn't passed in.\n"); res = TEST_ERR_FAILURE; break; @@ -264,7 +262,7 @@ static CURLcode test_run(char *URL, long option, unsigned int *max_fd_count) if(fd_count_chk < fd_count) { curl_mfprintf(stderr, - "curl_multi_waitfds() sould return the amount of fds " + "curl_multi_waitfds() should return the amount of fds " "needed if enough isn't passed in.\n"); res = TEST_ERR_FAILURE; break; @@ -342,8 +340,7 @@ static CURLcode empty_multi_test(void) /* calling curl_multi_waitfds() on multi handle with added easy handle. */ easy_init(easy); - if(set_easy((char *)CURL_UNCONST("http://example.com"), easy, - TEST_USE_HTTP1) != CURLE_OK) + if(set_easy("http://example.com", easy, TEST_USE_HTTP1) != CURLE_OK) goto test_cleanup; multi_add_handle(multi, easy); @@ -370,7 +367,7 @@ static CURLcode empty_multi_test(void) return res; } -CURLcode test(char *URL) +static CURLcode test_lib2405(const char *URL) { CURLcode res = CURLE_OK; unsigned int fd_count = 0; diff --git a/vendor/curl/tests/libtest/lib2502.c b/vendor/curl/tests/libtest/lib2502.c index 8979d19b052..ba7da99a070 100644 --- a/vendor/curl/tests/libtest/lib2502.c +++ b/vendor/curl/tests/libtest/lib2502.c @@ -21,29 +21,23 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "testtrace.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -#define NUM_HANDLES 4 - -CURLcode test(char *URL) +static CURLcode test_lib2502(const char *URL) { CURLcode res = CURLE_OK; CURL *curl[NUM_HANDLES] = {0}; int running; CURLM *m = NULL; - int i; + size_t i; char target_url[256]; char dnsentry[256]; struct curl_slist *slist = NULL; - char *port = libtest_arg3; - char *address = libtest_arg2; + const char *port = libtest_arg3; + const char *address = libtest_arg2; (void)URL; @@ -64,26 +58,26 @@ CURLcode test(char *URL) multi_setopt(m, CURLMOPT_MAXCONNECTS, 1L); - /* get NUM_HANDLES easy handles */ - for(i = 0; i < NUM_HANDLES; i++) { + /* get each easy handle */ + for(i = 0; i < CURL_ARRAYSIZE(curl); i++) { /* get an easy handle */ easy_init(curl[i]); /* specify target */ curl_msnprintf(target_url, sizeof(target_url), - "https://localhost:%s/path/2502%04i", + "https://localhost:%s/path/2502%04zu", port, i + 1); target_url[sizeof(target_url) - 1] = '\0'; easy_setopt(curl[i], CURLOPT_URL, target_url); /* go http2 */ easy_setopt(curl[i], CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_3ONLY); - easy_setopt(curl[i], CURLOPT_CONNECTTIMEOUT_MS, (long)5000); + easy_setopt(curl[i], CURLOPT_CONNECTTIMEOUT_MS, 5000L); easy_setopt(curl[i], CURLOPT_CAINFO, libtest_arg4); /* wait for first connection established to see if we can share it */ easy_setopt(curl[i], CURLOPT_PIPEWAIT, 1L); /* go verbose */ - libtest_debug_config.nohex = 1; - libtest_debug_config.tracetime = 0; - test_setopt(curl[i], CURLOPT_DEBUGDATA, &libtest_debug_config); + debug_config.nohex = TRUE; + debug_config.tracetime = FALSE; + test_setopt(curl[i], CURLOPT_DEBUGDATA, &debug_config); easy_setopt(curl[i], CURLOPT_DEBUGFUNCTION, libtest_debug_cb); easy_setopt(curl[i], CURLOPT_VERBOSE, 1L); /* include headers */ @@ -94,7 +88,7 @@ CURLcode test(char *URL) curl_mfprintf(stderr, "Start at URL 0\n"); - for(i = 0; i < NUM_HANDLES; i++) { + for(i = 0; i < CURL_ARRAYSIZE(curl); i++) { /* add handle to multi */ multi_add_handle(m, curl[i]); @@ -125,14 +119,14 @@ CURLcode test(char *URL) abort_on_test_timeout(); } - wait_ms(1); /* to ensure different end times */ + curlx_wait_ms(1); /* to ensure different end times */ } test_cleanup: /* proper cleanup sequence - type PB */ - for(i = 0; i < NUM_HANDLES; i++) { + for(i = 0; i < CURL_ARRAYSIZE(curl); i++) { curl_multi_remove_handle(m, curl[i]); curl_easy_cleanup(curl[i]); } diff --git a/vendor/curl/tests/libtest/lib2700.c b/vendor/curl/tests/libtest/lib2700.c index ecec6809c9f..f5090896454 100644 --- a/vendor/curl/tests/libtest/lib2700.c +++ b/vendor/curl/tests/libtest/lib2700.c @@ -21,8 +21,8 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ +#include "first.h" -#include "test.h" #include "testtrace.h" #include "memdebug.h" @@ -207,9 +207,11 @@ static CURLcode recv_frame(CURL *curl, bool *stop) return res; } +#endif -CURLcode test(char *URL) +static CURLcode test_lib2700(const char *URL) { +#ifndef CURL_DISABLE_WEBSOCKETS CURLcode res = CURLE_OK; bool stop = false; CURL *curl; @@ -220,14 +222,14 @@ CURLcode test(char *URL) easy_setopt(curl, CURLOPT_URL, URL); easy_setopt(curl, CURLOPT_USERAGENT, "client/test2700"); - libtest_debug_config.nohex = 1; - libtest_debug_config.tracetime = 1; - easy_setopt(curl, CURLOPT_DEBUGDATA, &libtest_debug_config); + debug_config.nohex = TRUE; + debug_config.tracetime = TRUE; + easy_setopt(curl, CURLOPT_DEBUGDATA, &debug_config); easy_setopt(curl, CURLOPT_DEBUGFUNCTION, libtest_debug_cb); easy_setopt(curl, CURLOPT_VERBOSE, 1L); easy_setopt(curl, CURLOPT_CONNECT_ONLY, 2L); - if(!getenv("LIB2700_AUTO_PONG")) - easy_setopt(curl, CURLOPT_WS_OPTIONS, (long)CURLWS_NOAUTOPONG); + if(testnum != 2708) + easy_setopt(curl, CURLOPT_WS_OPTIONS, CURLWS_NOAUTOPONG); res = curl_easy_perform(curl); if(res) { @@ -247,8 +249,7 @@ CURLcode test(char *URL) curl_easy_cleanup(curl); curl_global_cleanup(); return res; -} - #else -NO_SUPPORT_BUILT_IN + NO_SUPPORT_BUILT_IN #endif +} diff --git a/vendor/curl/tests/libtest/lib3010.c b/vendor/curl/tests/libtest/lib3010.c index dbeb3223d19..58271772ab4 100644 --- a/vendor/curl/tests/libtest/lib3010.c +++ b/vendor/curl/tests/libtest/lib3010.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib3010(const char *URL) { CURLcode ret = CURLE_OK; CURL *curl = NULL; diff --git a/vendor/curl/tests/libtest/lib3025.c b/vendor/curl/tests/libtest/lib3025.c index 41929500bca..b0056193b77 100644 --- a/vendor/curl/tests/libtest/lib3025.c +++ b/vendor/curl/tests/libtest/lib3025.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib3025(const char *URL) { CURLcode res; CURL *curl; diff --git a/vendor/curl/tests/libtest/lib3026.c b/vendor/curl/tests/libtest/lib3026.c index a94b1a271df..2b35a258417 100644 --- a/vendor/curl/tests/libtest/lib3026.c +++ b/vendor/curl/tests/libtest/lib3026.c @@ -21,19 +21,16 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" - -#include "testutil.h" -#include "warnless.h" +#include "first.h" #define NUM_THREADS 100 #ifdef _WIN32 #if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE) -static DWORD WINAPI run_thread(LPVOID ptr) +static DWORD WINAPI t3026_run_thread(LPVOID ptr) #else #include -static unsigned int WINAPI run_thread(void *ptr) +static unsigned int WINAPI t3026_run_thread(void *ptr) #endif { CURLcode *result = ptr; @@ -45,7 +42,7 @@ static unsigned int WINAPI run_thread(void *ptr) return 0; } -CURLcode test(char *URL) +static CURLcode test_lib3026(const char *URL) { #if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE) typedef HANDLE curl_win_thread_handle_t; @@ -53,11 +50,11 @@ CURLcode test(char *URL) typedef uintptr_t curl_win_thread_handle_t; #endif CURLcode results[NUM_THREADS]; - curl_win_thread_handle_t ths[NUM_THREADS]; + curl_win_thread_handle_t thread_handles[NUM_THREADS]; unsigned tid_count = NUM_THREADS, i; CURLcode test_failure = CURLE_OK; curl_version_info_data *ver; - (void) URL; + (void)URL; ver = curl_version_info(CURLVERSION_NOW); if((ver->features & CURL_VERSION_THREADSAFE) == 0) { @@ -71,9 +68,9 @@ CURLcode test(char *URL) curl_win_thread_handle_t th; results[i] = CURL_LAST; /* initialize with invalid value */ #if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE) - th = CreateThread(NULL, 0, run_thread, &results[i], 0, NULL); + th = CreateThread(NULL, 0, t3026_run_thread, &results[i], 0, NULL); #else - th = _beginthreadex(NULL, 0, run_thread, &results[i], 0, NULL); + th = _beginthreadex(NULL, 0, t3026_run_thread, &results[i], 0, NULL); #endif if(!th) { curl_mfprintf(stderr, "%s:%d Couldn't create thread, errno %lu\n", @@ -82,17 +79,17 @@ CURLcode test(char *URL) test_failure = TEST_ERR_MAJOR_BAD; goto cleanup; } - ths[i] = th; + thread_handles[i] = th; } cleanup: for(i = 0; i < tid_count; i++) { - WaitForSingleObject((HANDLE)ths[i], INFINITE); - CloseHandle((HANDLE)ths[i]); + WaitForSingleObject((HANDLE)thread_handles[i], INFINITE); + CloseHandle((HANDLE)thread_handles[i]); if(results[i] != CURLE_OK) { curl_mfprintf(stderr, "%s:%d thread[%u]: curl_global_init() failed," "with code %d (%s)\n", __FILE__, __LINE__, - i, (int) results[i], curl_easy_strerror(results[i])); + i, results[i], curl_easy_strerror(results[i])); test_failure = TEST_ERR_MAJOR_BAD; } } @@ -102,9 +99,8 @@ CURLcode test(char *URL) #elif defined(HAVE_PTHREAD_H) #include -#include -static void *run_thread(void *ptr) +static void *t3026_run_thread(void *ptr) { CURLcode *result = ptr; @@ -115,14 +111,14 @@ static void *run_thread(void *ptr) return NULL; } -CURLcode test(char *URL) +static CURLcode test_lib3026(const char *URL) { CURLcode results[NUM_THREADS]; pthread_t tids[NUM_THREADS]; unsigned tid_count = NUM_THREADS, i; CURLcode test_failure = CURLE_OK; curl_version_info_data *ver; - (void) URL; + (void)URL; ver = curl_version_info(CURLVERSION_NOW); if((ver->features & CURL_VERSION_THREADSAFE) == 0) { @@ -135,7 +131,7 @@ CURLcode test(char *URL) for(i = 0; i < tid_count; i++) { int res; results[i] = CURL_LAST; /* initialize with invalid value */ - res = pthread_create(&tids[i], NULL, run_thread, &results[i]); + res = pthread_create(&tids[i], NULL, t3026_run_thread, &results[i]); if(res) { curl_mfprintf(stderr, "%s:%d Couldn't create thread, errno %d\n", __FILE__, __LINE__, res); @@ -151,7 +147,7 @@ CURLcode test(char *URL) if(results[i] != CURLE_OK) { curl_mfprintf(stderr, "%s:%d thread[%u]: curl_global_init() failed," "with code %d (%s)\n", __FILE__, __LINE__, - i, (int) results[i], curl_easy_strerror(results[i])); + i, results[i], curl_easy_strerror(results[i])); test_failure = TEST_ERR_MAJOR_BAD; } } @@ -160,7 +156,7 @@ CURLcode test(char *URL) } #else /* without pthread or Windows, this test doesn't work */ -CURLcode test(char *URL) +static CURLcode test_lib3026(const char *URL) { curl_version_info_data *ver; (void)URL; diff --git a/vendor/curl/tests/libtest/lib3027.c b/vendor/curl/tests/libtest/lib3027.c index 4ddee1b6b29..735f4c96e96 100644 --- a/vendor/curl/tests/libtest/lib3027.c +++ b/vendor/curl/tests/libtest/lib3027.c @@ -21,13 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib3027(const char *URL) { CURLcode ret = CURLE_OK; CURL *hnd; diff --git a/vendor/curl/tests/libtest/lib3033.c b/vendor/curl/tests/libtest/lib3033.c new file mode 100644 index 00000000000..1c0b9856fce --- /dev/null +++ b/vendor/curl/tests/libtest/lib3033.c @@ -0,0 +1,130 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "first.h" + +#include "testtrace.h" + +#include "memdebug.h" + +static CURLcode t3033_req_test(CURLM *multi, CURL *easy, + const char *URL, int index) +{ + CURLMsg *msg = NULL; + CURLcode res = CURLE_OK; + int still_running = 0; + + if(index == 1) { + curl_multi_setopt(multi, CURLMOPT_NETWORK_CHANGED, + CURLMNWC_CLEAR_CONNS); + curl_mprintf("[1] signal network change\n"); + } + else { + curl_mprintf("[%d] no network change\n", index); + } + + curl_easy_reset(easy); + curl_easy_setopt(easy, CURLOPT_URL, URL); + easy_setopt(easy, CURLOPT_DEBUGDATA, &debug_config); + easy_setopt(easy, CURLOPT_DEBUGFUNCTION, libtest_debug_cb); + easy_setopt(easy, CURLOPT_VERBOSE, 1L); + + curl_multi_add_handle(multi, easy); + + do { + CURLMcode mres; + int num; + curl_multi_perform(multi, &still_running); + mres = curl_multi_wait(multi, NULL, 0, TEST_HANG_TIMEOUT, &num); + if(mres != CURLM_OK) { + curl_mfprintf(stderr, "curl_multi_wait() returned %d\n", mres); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + } while(still_running); + + do { + long num_connects = 0L; + msg = curl_multi_info_read(multi, &still_running); + if(msg) { + if(msg->msg != CURLMSG_DONE) + continue; + + res = msg->data.result; + if(res != CURLE_OK) { + curl_mfprintf(stderr, "curl_multi_info_read() returned %d\n", res); + goto test_cleanup; + } + + curl_easy_getinfo(easy, CURLINFO_NUM_CONNECTS, &num_connects); + if(index == 1 && num_connects == 0) { + curl_mprintf("[1] should not reuse connection in pool\n"); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + else if(index == 2 && num_connects) { + curl_mprintf("[2] should have reused connection from [1]\n"); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + } + } while(msg); + +test_cleanup: + + curl_multi_remove_handle(multi, easy); + + return res; +} + +static CURLcode test_lib3033(const char *URL) +{ + CURL *curl = NULL; + CURLM *multi = NULL; + CURLcode res = CURLE_OK; + + global_init(CURL_GLOBAL_ALL); + multi_init(multi); + easy_init(curl); + + debug_config.nohex = TRUE; + debug_config.tracetime = TRUE; + + res = t3033_req_test(multi, curl, URL, 0); + if(res != CURLE_OK) + goto test_cleanup; + res = t3033_req_test(multi, curl, URL, 1); + if(res != CURLE_OK) + goto test_cleanup; + res = t3033_req_test(multi, curl, URL, 2); + if(res != CURLE_OK) + goto test_cleanup; + +test_cleanup: + + curl_easy_cleanup(curl); + curl_multi_cleanup(multi); + curl_global_cleanup(); + + return res; /* return the final return code */ +} diff --git a/vendor/curl/tests/libtest/lib3034.c b/vendor/curl/tests/libtest/lib3034.c new file mode 100644 index 00000000000..b21c68d153f --- /dev/null +++ b/vendor/curl/tests/libtest/lib3034.c @@ -0,0 +1,77 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "first.h" + +static const char data_3034[] = "hello"; + +static size_t t3034_read_cb(char *ptr, size_t size, size_t nmemb, void *userp) +{ + size_t len = size * nmemb; + size_t tocopy = sizeof(data_3034) < len ? sizeof(data_3034) : len; + (void)userp; + memcpy(ptr, data_3034, tocopy); + return tocopy; +} + +static CURLcode test_lib3034(const char *URL) +{ + CURL *curl; + CURLcode res = CURLE_OK; + + global_init(CURL_GLOBAL_ALL); + easy_init(curl); + + /* This first request will receive a redirect response; deliberately only + * set the CURLOPT_READFUNCTION but not the CURLOPT_SEEKFUNCTION to force a + * rewind failure (CURLE_SEND_FAIL_REWIND). + */ + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + test_setopt(curl, CURLOPT_UPLOAD, 1L); + test_setopt(curl, CURLOPT_INFILESIZE, 5L); + test_setopt(curl, CURLOPT_READFUNCTION, t3034_read_cb); + + res = curl_easy_perform(curl); + if(res != CURLE_SEND_FAIL_REWIND) { + curl_mfprintf(stderr, + "%s:%d curl_easy_perform() failed with code %d (%s)\n", + __FILE__, __LINE__, res, curl_easy_strerror(res)); + goto test_cleanup; + } + + /* Reset the easy handle, which should clear the rewind failure. */ + curl_easy_reset(curl); + + /* Perform a second request, which should succeed. */ + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_URL, URL); + + res = curl_easy_perform(curl); + +test_cleanup: + curl_easy_cleanup(curl); + curl_global_cleanup(); + return res; +} diff --git a/vendor/curl/tests/libtest/lib3100.c b/vendor/curl/tests/libtest/lib3100.c index 7a1037b6e38..b661aa76ceb 100644 --- a/vendor/curl/tests/libtest/lib3100.c +++ b/vendor/curl/tests/libtest/lib3100.c @@ -21,10 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" + #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib3100(const char *URL) { CURLcode res; CURL *curl; diff --git a/vendor/curl/tests/libtest/lib3101.c b/vendor/curl/tests/libtest/lib3101.c index 13e977313de..3f5cbce17cb 100644 --- a/vendor/curl/tests/libtest/lib3101.c +++ b/vendor/curl/tests/libtest/lib3101.c @@ -21,10 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" + #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib3101(const char *URL) { CURLcode res; CURL *curl; diff --git a/vendor/curl/tests/libtest/lib3102.c b/vendor/curl/tests/libtest/lib3102.c index df95bcd6ee2..136ec0a1b73 100644 --- a/vendor/curl/tests/libtest/lib3102.c +++ b/vendor/curl/tests/libtest/lib3102.c @@ -21,7 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" @@ -46,8 +46,8 @@ static bool is_chain_in_order(struct curl_certinfo *cert_info) /* Find the certificate issuer and subject by enumerating each field */ for(; slist && (!issuer || !subject); slist = slist->next) { - const char issuer_prefix[] = "Issuer:"; - const char subject_prefix[] = "Subject:"; + static const char issuer_prefix[] = "Issuer:"; + static const char subject_prefix[] = "Subject:"; if(!strncmp(slist->data, issuer_prefix, sizeof(issuer_prefix)-1)) { issuer = slist->data + sizeof(issuer_prefix)-1; @@ -89,7 +89,7 @@ static size_t wrfu(void *ptr, size_t size, size_t nmemb, void *stream) return size * nmemb; } -CURLcode test(char *URL) +static CURLcode test_lib3102(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; diff --git a/vendor/curl/tests/libtest/lib3103.c b/vendor/curl/tests/libtest/lib3103.c index cad9de7ae38..5b25e1cd417 100644 --- a/vendor/curl/tests/libtest/lib3103.c +++ b/vendor/curl/tests/libtest/lib3103.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib3103(const char *URL) { CURLcode res = CURLE_OK; CURLSH *share; diff --git a/vendor/curl/tests/libtest/lib3104.c b/vendor/curl/tests/libtest/lib3104.c index da92be5d47a..dd1500ede55 100644 --- a/vendor/curl/tests/libtest/lib3104.c +++ b/vendor/curl/tests/libtest/lib3104.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib3104(const char *URL) { CURLcode res = CURLE_OK; CURLSH *share; diff --git a/vendor/curl/tests/libtest/lib3105.c b/vendor/curl/tests/libtest/lib3105.c index c41a59a1b6a..29dfdae00c3 100644 --- a/vendor/curl/tests/libtest/lib3105.c +++ b/vendor/curl/tests/libtest/lib3105.c @@ -21,15 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -CURLcode test(char *URL) +static CURLcode test_lib3105(const char *URL) { CURL *curls = NULL; CURLM *multi = NULL; @@ -51,7 +47,7 @@ CURLcode test(char *URL) mc += curl_multi_remove_handle(multi, curls); if(mc) { - curl_mfprintf(stderr, "%d was unexpected\n", (int)mc); + curl_mfprintf(stderr, "%d was unexpected\n", mc); i = CURLE_FAILED_INIT; } diff --git a/vendor/curl/tests/libtest/lib3207.c b/vendor/curl/tests/libtest/lib3207.c index 5baec357d1f..446d98a0008 100644 --- a/vendor/curl/tests/libtest/lib3207.c +++ b/vendor/curl/tests/libtest/lib3207.c @@ -21,20 +21,16 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" -#include "testutil.h" -#include "memdebug.h" +#include "first.h" -#include +#include "memdebug.h" -#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) -#if defined(USE_THREADS_POSIX) +#ifdef USE_THREADS_POSIX #include #endif + #include "curl_threads.h" -#endif -#define CAINFO libtest_arg2 #define THREAD_SIZE 16 #define PER_THREAD_SIZE 8 @@ -42,7 +38,7 @@ struct Ctx { const char *URL; CURLSH *share; CURLcode result; - int thread_id; + size_t thread_id; struct curl_slist *contents; }; @@ -72,18 +68,7 @@ static size_t write_memory_callback(char *contents, size_t size, return realsize; } -static -#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) -#if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE) -DWORD -#else -unsigned int -#endif -CURL_STDCALL -#else -unsigned int -#endif -test_thread(void *ptr) +static CURL_THREAD_RETURN_T CURL_STDCALL test_thread(void *ptr) { struct Ctx *ctx = (struct Ctx *)ptr; CURLcode res = CURLE_OK; @@ -95,11 +80,11 @@ test_thread(void *ptr) for(i = 0; i < PER_THREAD_SIZE; i++) { CURL *curl = curl_easy_init(); if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, (char *)CURL_UNCONST(ctx->URL)); + curl_easy_setopt(curl, CURLOPT_URL, ctx->URL); /* use the share object */ curl_easy_setopt(curl, CURLOPT_SHARE, ctx->share); - curl_easy_setopt(curl, CURLOPT_CAINFO, CAINFO); + curl_easy_setopt(curl, CURLOPT_CAINFO, libtest_arg2); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_memory_callback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, ptr); @@ -126,8 +111,8 @@ test_thread(void *ptr) #if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) -static void test_lock(CURL *handle, curl_lock_data data, - curl_lock_access laccess, void *useptr) +static void t3207_test_lock(CURL *handle, curl_lock_data data, + curl_lock_access laccess, void *useptr) { curl_mutex_t *mutexes = (curl_mutex_t*) useptr; (void)handle; @@ -135,7 +120,7 @@ static void test_lock(CURL *handle, curl_lock_data data, Curl_mutex_acquire(&mutexes[data]); } -static void test_unlock(CURL *handle, curl_lock_data data, void *useptr) +static void t3207_test_unlock(CURL *handle, curl_lock_data data, void *useptr) { curl_mutex_t *mutexes = (curl_mutex_t*) useptr; (void)handle; @@ -144,21 +129,21 @@ static void test_unlock(CURL *handle, curl_lock_data data, void *useptr) static void execute(CURLSH *share, struct Ctx *ctx) { - int i; + size_t i; curl_mutex_t mutexes[CURL_LOCK_DATA_LAST - 1]; curl_thread_t thread[THREAD_SIZE]; - for(i = 0; i < CURL_LOCK_DATA_LAST - 1; i++) { + for(i = 0; i < CURL_ARRAYSIZE(mutexes); i++) { Curl_mutex_init(&mutexes[i]); } - curl_share_setopt(share, CURLSHOPT_LOCKFUNC, test_lock); - curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, test_unlock); + curl_share_setopt(share, CURLSHOPT_LOCKFUNC, t3207_test_lock); + curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, t3207_test_unlock); curl_share_setopt(share, CURLSHOPT_USERDATA, (void *)mutexes); curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION); - for(i = 0; i < THREAD_SIZE; i++) { + for(i = 0; i < CURL_ARRAYSIZE(thread); i++) { thread[i] = Curl_thread_create(test_thread, (void *)&ctx[i]); } - for(i = 0; i < THREAD_SIZE; i++) { + for(i = 0; i < CURL_ARRAYSIZE(thread); i++) { if(thread[i]) { Curl_thread_join(&thread[i]); Curl_thread_destroy(&thread[i]); @@ -166,7 +151,7 @@ static void execute(CURLSH *share, struct Ctx *ctx) } curl_share_setopt(share, CURLSHOPT_LOCKFUNC, NULL); curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, NULL); - for(i = 0; i < CURL_LOCK_DATA_LAST - 1; i++) { + for(i = 0; i < CURL_ARRAYSIZE(mutexes); i++) { Curl_mutex_destroy(&mutexes[i]); } } @@ -175,8 +160,8 @@ static void execute(CURLSH *share, struct Ctx *ctx) static void execute(CURLSH *share, struct Ctx *ctx) { - int i; - (void) share; + size_t i; + (void)share; for(i = 0; i < THREAD_SIZE; i++) { test_thread((void *)&ctx[i]); } @@ -184,10 +169,10 @@ static void execute(CURLSH *share, struct Ctx *ctx) #endif -CURLcode test(char *URL) +static CURLcode test_lib3207(const char *URL) { CURLcode res = CURLE_OK; - int i; + size_t i; CURLSH* share; struct Ctx ctx[THREAD_SIZE]; @@ -199,7 +184,7 @@ CURLcode test(char *URL) goto test_cleanup; } - for(i = 0; i < THREAD_SIZE; i++) { + for(i = 0; i < CURL_ARRAYSIZE(ctx); i++) { ctx[i].share = share; ctx[i].URL = URL; ctx[i].thread_id = i; @@ -209,7 +194,7 @@ CURLcode test(char *URL) execute(share, ctx); - for(i = 0; i < THREAD_SIZE; i++) { + for(i = 0; i < CURL_ARRAYSIZE(ctx); i++) { if(ctx[i].result) { res = ctx[i].result; } diff --git a/vendor/curl/tests/libtest/lib3208.c b/vendor/curl/tests/libtest/lib3208.c index ce3a4cbe9cf..39585c15977 100644 --- a/vendor/curl/tests/libtest/lib3208.c +++ b/vendor/curl/tests/libtest/lib3208.c @@ -21,15 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -CURLcode test(char *URL) +static CURLcode test_lib3208(const char *URL) { CURL *curl = NULL; CURLM *multi = NULL; diff --git a/vendor/curl/tests/libtest/lib500.c b/vendor/curl/tests/libtest/lib500.c index 1a9222edc82..0586c1407f9 100644 --- a/vendor/curl/tests/libtest/lib500.c +++ b/vendor/curl/tests/libtest/lib500.c @@ -21,13 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "testtrace.h" #include "memdebug.h" -#ifdef LIB585 - static int testcounter; static curl_socket_t tst_opensocket(void *clientp, @@ -54,12 +52,7 @@ static void setupcallbacks(CURL *curl) testcounter = 0; } -#else -#define setupcallbacks(x) Curl_nop_stmt -#endif - - -CURLcode test(char *URL) +static CURLcode test_lib500(const char *URL) { CURLcode res; CURL *curl; @@ -80,16 +73,17 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_URL, URL); test_setopt(curl, CURLOPT_HEADER, 1L); - libtest_debug_config.nohex = 1; - libtest_debug_config.tracetime = 1; - test_setopt(curl, CURLOPT_DEBUGDATA, &libtest_debug_config); + debug_config.nohex = TRUE; + debug_config.tracetime = TRUE; + test_setopt(curl, CURLOPT_DEBUGDATA, &debug_config); test_setopt(curl, CURLOPT_DEBUGFUNCTION, libtest_debug_cb); test_setopt(curl, CURLOPT_VERBOSE, 1L); if(libtest_arg3 && !strcmp(libtest_arg3, "activeftp")) test_setopt(curl, CURLOPT_FTPPORT, "-"); - setupcallbacks(curl); + if(testnum == 585 || testnum == 586 || testnum == 595 || testnum == 596) + setupcallbacks(curl); res = curl_easy_perform(curl); @@ -181,5 +175,3 @@ CURLcode test(char *URL) return res; } - -#undef setupcallbacks diff --git a/vendor/curl/tests/libtest/lib501.c b/vendor/curl/tests/libtest/lib501.c index c1aecdc56c1..d32e4397b8f 100644 --- a/vendor/curl/tests/libtest/lib501.c +++ b/vendor/curl/tests/libtest/lib501.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib501(const char *URL) { CURLcode res; CURL *curl; diff --git a/vendor/curl/tests/libtest/lib502.c b/vendor/curl/tests/libtest/lib502.c index 44ad6f67902..9a51267aae0 100644 --- a/vendor/curl/tests/libtest/lib502.c +++ b/vendor/curl/tests/libtest/lib502.c @@ -21,19 +21,15 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - /* * Get a single URL without select(). */ -CURLcode test(char *URL) +static CURLcode test_lib502(const char *URL) { CURL *c = NULL; CURLM *m = NULL; diff --git a/vendor/curl/tests/libtest/lib503.c b/vendor/curl/tests/libtest/lib503.c index cac2a755cbc..f7529d47b79 100644 --- a/vendor/curl/tests/libtest/lib503.c +++ b/vendor/curl/tests/libtest/lib503.c @@ -21,14 +21,10 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - /* * Source code in here hugely as reported in bug report 651460 by * Christopher R. Palmer. @@ -37,7 +33,7 @@ * auth info. */ -CURLcode test(char *URL) +static CURLcode test_lib503(const char *URL) { CURL *c = NULL; CURLM *m = NULL; diff --git a/vendor/curl/tests/libtest/lib504.c b/vendor/curl/tests/libtest/lib504.c index 93d38a0b246..07b46345bbf 100644 --- a/vendor/curl/tests/libtest/lib504.c +++ b/vendor/curl/tests/libtest/lib504.c @@ -21,14 +21,10 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - /* * Source code in here hugely as reported in bug report 651464 by * Christopher R. Palmer. @@ -36,7 +32,7 @@ * Use multi interface to get document over proxy with bad port number. * This caused the interface to "hang" in libcurl 7.10.2. */ -CURLcode test(char *URL) +static CURLcode test_lib504(const char *URL) { CURL *c = NULL; CURLcode res = CURLE_OK; diff --git a/vendor/curl/tests/libtest/lib505.c b/vendor/curl/tests/libtest/lib505.c index 5c3799a230e..2285208e9f3 100644 --- a/vendor/curl/tests/libtest/lib505.c +++ b/vendor/curl/tests/libtest/lib505.c @@ -21,11 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" - -#ifdef HAVE_FCNTL_H -#include -#endif +#include "first.h" #include "memdebug.h" @@ -36,7 +32,7 @@ * Example based on source code provided by Erick Nuwendam. Thanks! */ -CURLcode test(char *URL) +static CURLcode test_lib505(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; @@ -46,8 +42,9 @@ CURLcode test(char *URL) struct curl_slist *hl; struct curl_slist *headerlist = NULL; - const char *buf_1 = "RNFR 505"; - const char *buf_2 = "RNTO 505-forreal"; + + static const char *buf_1 = "RNFR 505"; + static const char *buf_2 = "RNTO 505-forreal"; if(!libtest_arg2) { curl_mfprintf(stderr, "Usage: \n"); diff --git a/vendor/curl/tests/libtest/lib506.c b/vendor/curl/tests/libtest/lib506.c index 8680c6ec6d8..4b6eb05f814 100644 --- a/vendor/curl/tests/libtest/lib506.c +++ b/vendor/curl/tests/libtest/lib506.c @@ -21,20 +21,20 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" + +#include "testutil.h" #include "memdebug.h" -static const char * const HOSTHEADER = "Host: www.host.foo.com"; -#define JAR libtest_arg2 #define THREADS 2 /* struct containing data of a thread */ -struct Tdata { +struct t506_Tdata { CURLSH *share; char *url; }; -struct userdata { +struct t506_userdata { const char *text; int counter; }; @@ -42,11 +42,11 @@ struct userdata { static int locks[3]; /* lock callback */ -static void test_lock(CURL *handle, curl_lock_data data, - curl_lock_access laccess, void *useptr) +static void t506_test_lock(CURL *handle, curl_lock_data data, + curl_lock_access laccess, void *useptr) { const char *what; - struct userdata *user = (struct userdata *)useptr; + struct t506_userdata *user = (struct t506_userdata *)useptr; int locknum; (void)handle; @@ -66,7 +66,7 @@ static void test_lock(CURL *handle, curl_lock_data data, locknum = 2; break; default: - curl_mfprintf(stderr, "lock: no such data: %d\n", (int)data); + curl_mfprintf(stderr, "lock: no such data: %d\n", data); return; } @@ -82,10 +82,10 @@ static void test_lock(CURL *handle, curl_lock_data data, } /* unlock callback */ -static void test_unlock(CURL *handle, curl_lock_data data, void *useptr) +static void t506_test_unlock(CURL *handle, curl_lock_data data, void *useptr) { const char *what; - struct userdata *user = (struct userdata *)useptr; + struct t506_userdata *user = (struct t506_userdata *)useptr; int locknum; (void)handle; switch(data) { @@ -102,7 +102,7 @@ static void test_unlock(CURL *handle, curl_lock_data data, void *useptr) locknum = 2; break; default: - curl_mfprintf(stderr, "unlock: no such data: %d\n", (int)data); + curl_mfprintf(stderr, "unlock: no such data: %d\n", data); return; } @@ -117,21 +117,19 @@ static void test_unlock(CURL *handle, curl_lock_data data, void *useptr) user->counter++; } - /* build host entry */ static struct curl_slist *sethost(struct curl_slist *headers) { (void)headers; - return curl_slist_append(NULL, HOSTHEADER); + return curl_slist_append(NULL, "Host: www.host.foo.com"); } - /* the dummy thread function */ -static void *test_fire(void *ptr) +static void *t506_test_fire(void *ptr) { CURLcode code; struct curl_slist *headers; - struct Tdata *tdata = (struct Tdata*)ptr; + struct t506_Tdata *tdata = (struct t506_Tdata*)ptr; CURL *curl; curl = curl_easy_init(); @@ -153,7 +151,7 @@ static void *test_fire(void *ptr) if(code) { int i = 0; curl_mfprintf(stderr, "perform url '%s' repeat %d failed, curlcode %d\n", - tdata->url, i, (int)code); + tdata->url, i, code); } curl_mprintf("CLEANUP\n"); @@ -163,29 +161,23 @@ static void *test_fire(void *ptr) return NULL; } - -/* build request url */ -static char *suburl(const char *base, int i) -{ - return curl_maprintf("%s%.4d", base, i); -} - - /* test function */ -CURLcode test(char *URL) +static CURLcode test_lib506(const char *URL) { CURLcode res; CURLSHcode scode = CURLSHE_OK; CURLcode code = CURLE_OK; char *url = NULL; - struct Tdata tdata; + struct t506_Tdata tdata; CURL *curl; CURLSH *share; struct curl_slist *headers = NULL; struct curl_slist *cookies = NULL; struct curl_slist *next_cookie = NULL; int i; - struct userdata user; + struct t506_userdata user; + + const char *jar = libtest_arg2; user.text = "Pigs in space"; user.counter = 0; @@ -207,11 +199,11 @@ CURLcode test(char *URL) if(CURLSHE_OK == scode) { curl_mprintf("CURLSHOPT_LOCKFUNC\n"); - scode = curl_share_setopt(share, CURLSHOPT_LOCKFUNC, test_lock); + scode = curl_share_setopt(share, CURLSHOPT_LOCKFUNC, t506_test_lock); } if(CURLSHE_OK == scode) { curl_mprintf("CURLSHOPT_UNLOCKFUNC\n"); - scode = curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, test_unlock); + scode = curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, t506_test_unlock); } if(CURLSHE_OK == scode) { curl_mprintf("CURLSHOPT_USERDATA\n"); @@ -265,12 +257,12 @@ CURLcode test(char *URL) for(i = 1; i <= THREADS; i++) { /* set thread data */ - tdata.url = suburl(URL, i); /* must be curl_free()d */ + tdata.url = tutil_suburl(URL, i); /* must be curl_free()d */ tdata.share = share; /* simulate thread, direct call of "thread" function */ curl_mprintf("*** run %d\n",i); - test_fire(&tdata); + t506_test_fire(&tdata); curl_free(tdata.url); } @@ -286,14 +278,14 @@ CURLcode test(char *URL) return TEST_ERR_MAJOR_BAD; } - url = suburl(URL, i); + url = tutil_suburl(URL, i); headers = sethost(NULL); test_setopt(curl, CURLOPT_HTTPHEADER, headers); test_setopt(curl, CURLOPT_URL, url); curl_mprintf("CURLOPT_SHARE\n"); test_setopt(curl, CURLOPT_SHARE, share); curl_mprintf("CURLOPT_COOKIEJAR\n"); - test_setopt(curl, CURLOPT_COOKIEJAR, JAR); + test_setopt(curl, CURLOPT_COOKIEJAR, jar); curl_mprintf("CURLOPT_COOKIELIST FLUSH\n"); test_setopt(curl, CURLOPT_COOKIELIST, "FLUSH"); @@ -313,7 +305,7 @@ CURLcode test(char *URL) curl_global_cleanup(); return TEST_ERR_MAJOR_BAD; } - url = suburl(URL, i); + url = tutil_suburl(URL, i); headers = sethost(NULL); test_setopt(curl, CURLOPT_HTTPHEADER, headers); test_setopt(curl, CURLOPT_URL, url); @@ -322,7 +314,7 @@ CURLcode test(char *URL) curl_mprintf("CURLOPT_COOKIELIST ALL\n"); test_setopt(curl, CURLOPT_COOKIELIST, "ALL"); curl_mprintf("CURLOPT_COOKIEJAR\n"); - test_setopt(curl, CURLOPT_COOKIEFILE, JAR); + test_setopt(curl, CURLOPT_COOKIEFILE, jar); curl_mprintf("CURLOPT_COOKIELIST RELOAD\n"); test_setopt(curl, CURLOPT_COOKIELIST, "RELOAD"); @@ -336,7 +328,7 @@ CURLcode test(char *URL) } curl_mprintf("loaded cookies:\n"); if(!cookies) { - curl_mfprintf(stderr, " reloading cookies from '%s' failed\n", JAR); + curl_mfprintf(stderr, " reloading cookies from '%s' failed\n", jar); res = TEST_ERR_MAJOR_BAD; goto test_cleanup; } @@ -372,8 +364,7 @@ CURLcode test(char *URL) curl_mprintf("SHARE_CLEANUP\n"); scode = curl_share_cleanup(share); if(scode != CURLSHE_OK) - curl_mfprintf(stderr, "curl_share_cleanup failed, code errno %d\n", - (int)scode); + curl_mfprintf(stderr, "curl_share_cleanup failed, code errno %d\n", scode); curl_mprintf("GLOBAL_CLEANUP\n"); curl_global_cleanup(); diff --git a/vendor/curl/tests/libtest/lib507.c b/vendor/curl/tests/libtest/lib507.c index f86ee79b923..de23b02f0a3 100644 --- a/vendor/curl/tests/libtest/lib507.c +++ b/vendor/curl/tests/libtest/lib507.c @@ -21,15 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -CURLcode test(char *URL) +static CURLcode test_lib507(const char *URL) { CURL *curls = NULL; CURLM *multi = NULL; diff --git a/vendor/curl/tests/libtest/lib508.c b/vendor/curl/tests/libtest/lib508.c index 8480cd7d144..a4c25b7918f 100644 --- a/vendor/curl/tests/libtest/lib508.c +++ b/vendor/curl/tests/libtest/lib508.c @@ -21,20 +21,18 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -static char testdata[]="this is what we post to the silly web server\n"; - -struct WriteThis { - char *readptr; +struct t508_WriteThis { + const char *readptr; size_t sizeleft; }; -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) +static size_t t508_read_cb(char *ptr, size_t size, size_t nmemb, void *userp) { - struct WriteThis *pooh = (struct WriteThis *)userp; + struct t508_WriteThis *pooh = (struct t508_WriteThis *)userp; if(size*nmemb < 1) return 0; @@ -49,12 +47,15 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) return 0; /* no more data left to deliver */ } -CURLcode test(char *URL) +static CURLcode test_lib508(const char *URL) { + static const char testdata[] = + "this is what we post to the silly web server\n"; + CURL *curl; CURLcode res = CURLE_OK; - struct WriteThis pooh; + struct t508_WriteThis pooh; pooh.readptr = testdata; pooh.sizeleft = strlen(testdata); @@ -81,7 +82,7 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)pooh.sizeleft); /* we want to use our own read function */ - test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + test_setopt(curl, CURLOPT_READFUNCTION, t508_read_cb); /* pointer to pass to our read function */ test_setopt(curl, CURLOPT_READDATA, &pooh); diff --git a/vendor/curl/tests/libtest/lib509.c b/vendor/curl/tests/libtest/lib509.c index 3b2a9320777..a8be3eae522 100644 --- a/vendor/curl/tests/libtest/lib509.c +++ b/vendor/curl/tests/libtest/lib509.c @@ -21,9 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" - -#include +#include "first.h" /* * This test uses these funny custom memory callbacks for the only purpose @@ -69,10 +67,10 @@ static void custom_free(void *ptr) } -CURLcode test(char *URL) +static CURLcode test_lib509(const char *URL) { - unsigned char a[] = {0x2f, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x91, 0xa2, 0xb3, 0xc4, 0xd5, 0xe6, 0xf7}; + static const unsigned char a[] = {0x2f, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x91, 0xa2, 0xb3, 0xc4, 0xd5, 0xe6, 0xf7}; CURLcode res; CURL *curl; int asize; @@ -100,7 +98,7 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_USERAGENT, "test509"); /* uses strdup() */ asize = (int)sizeof(a); - str = curl_easy_escape(curl, (char *)a, asize); /* uses realloc() */ + str = curl_easy_escape(curl, (const char *)a, asize); /* uses realloc() */ if(seen) curl_mprintf("Callbacks were invoked!\n"); diff --git a/vendor/curl/tests/libtest/lib510.c b/vendor/curl/tests/libtest/lib510.c index 0c7a7d14935..da270c1c921 100644 --- a/vendor/curl/tests/libtest/lib510.c +++ b/vendor/curl/tests/libtest/lib510.c @@ -21,26 +21,25 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -static const char * const testpost[]={ - "one", - "two", - "three", - "and a final longer crap: four", - NULL -}; - - -struct WriteThis { +struct t510_WriteThis { int counter; }; -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) +static size_t t510_read_cb(char *ptr, size_t size, size_t nmemb, void *userp) { - struct WriteThis *pooh = (struct WriteThis *)userp; + static const char * const testpost[] = { + "one", + "two", + "three", + "and a final longer crap: four", + NULL + }; + + struct t510_WriteThis *pooh = (struct t510_WriteThis *)userp; const char *data; if(size*nmemb < 1) @@ -61,12 +60,12 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) return 0; /* no more data left to deliver */ } -CURLcode test(char *URL) +static CURLcode test_lib510(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; struct curl_slist *slist = NULL; - struct WriteThis pooh; + struct t510_WriteThis pooh; pooh.counter = 0; if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { @@ -96,7 +95,7 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_POST, 1L); /* we want to use our own read function */ - test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + test_setopt(curl, CURLOPT_READFUNCTION, t510_read_cb); /* pointer to pass to our read function */ test_setopt(curl, CURLOPT_READDATA, &pooh); @@ -110,10 +109,10 @@ CURLcode test(char *URL) /* enforce chunked transfer by setting the header */ test_setopt(curl, CURLOPT_HTTPHEADER, slist); -#ifdef LIB565 - test_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_DIGEST); - test_setopt(curl, CURLOPT_USERPWD, "foo:bar"); -#endif + if(testnum == 565) { + test_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); + test_setopt(curl, CURLOPT_USERPWD, "foo:bar"); + } /* Perform the request, res will get the return code */ res = curl_easy_perform(curl); diff --git a/vendor/curl/tests/libtest/lib511.c b/vendor/curl/tests/libtest/lib511.c index baa704a746a..1db40937809 100644 --- a/vendor/curl/tests/libtest/lib511.c +++ b/vendor/curl/tests/libtest/lib511.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib511(const char *URL) { CURLcode res; CURL *curl; diff --git a/vendor/curl/tests/libtest/lib512.c b/vendor/curl/tests/libtest/lib512.c index 02e0d487c3e..59a1cd7595d 100644 --- a/vendor/curl/tests/libtest/lib512.c +++ b/vendor/curl/tests/libtest/lib512.c @@ -21,14 +21,14 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" /* Test case code based on source in a bug report filed by James Bursa on 28 Apr 2004 */ -CURLcode test(char *URL) +static CURLcode test_lib512(const char *URL) { CURLcode code; int rc = 99; diff --git a/vendor/curl/tests/libtest/lib513.c b/vendor/curl/tests/libtest/lib513.c index af40e6ee09d..3d0afb1191b 100644 --- a/vendor/curl/tests/libtest/lib513.c +++ b/vendor/curl/tests/libtest/lib513.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) +static size_t t513_read_cb(char *ptr, size_t size, size_t nmemb, void *userp) { (void)ptr; (void)size; @@ -34,7 +34,7 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) return CURL_READFUNC_ABORT; } -CURLcode test(char *URL) +static CURLcode test_lib513(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; @@ -61,7 +61,7 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_POSTFIELDSIZE, 1L); /* we want to use our own read function */ - test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + test_setopt(curl, CURLOPT_READFUNCTION, t513_read_cb); /* pointer to pass to our read function */ test_setopt(curl, CURLOPT_READDATA, NULL); diff --git a/vendor/curl/tests/libtest/lib514.c b/vendor/curl/tests/libtest/lib514.c index b0dadf21af6..f47cdb321d5 100644 --- a/vendor/curl/tests/libtest/lib514.c +++ b/vendor/curl/tests/libtest/lib514.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib514(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; diff --git a/vendor/curl/tests/libtest/lib515.c b/vendor/curl/tests/libtest/lib515.c index 4aa7245ac92..d9814525df5 100644 --- a/vendor/curl/tests/libtest/lib515.c +++ b/vendor/curl/tests/libtest/lib515.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib515(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; diff --git a/vendor/curl/tests/libtest/lib516.c b/vendor/curl/tests/libtest/lib516.c index 60eb4e4c70d..b7778a6a76c 100644 --- a/vendor/curl/tests/libtest/lib516.c +++ b/vendor/curl/tests/libtest/lib516.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib516(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; diff --git a/vendor/curl/tests/libtest/lib517.c b/vendor/curl/tests/libtest/lib517.c index 503fc428a33..cf1a14d31c6 100644 --- a/vendor/curl/tests/libtest/lib517.c +++ b/vendor/curl/tests/libtest/lib517.c @@ -21,149 +21,146 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -struct dcheck { - const char *input; - time_t output; -}; +static CURLcode test_lib517(const char *URL) +{ + struct dcheck { + const char *input; + time_t output; + }; -static const struct dcheck dates[] = { - {"Sun, 06 Nov 1994 08:49:37 GMT", 784111777 }, - {"Sunday, 06-Nov-94 08:49:37 GMT", 784111777 }, - {"Sun Nov 6 08:49:37 1994", 784111777 }, - {"Sun Nov 6 8:49:37 1994", 784111777 }, - {"Sun Nov 6 8:9:37 1994", 784109377 }, - {"Sun Nov 6 008:09:37 1994", -1 }, - {"Nov Sun 6 8:9:7 1994", 784109347 }, - {"06 Nov 1994 08:49:37 GMT", 784111777 }, - {"06-Nov-94 08:49:37 GMT", 784111777 }, - {"Nov 6 08:49:37 1994", 784111777 }, - {"06 Nov 1994 08:49:37", 784111777 }, - {"06-Nov-94 08:49:37", 784111777 }, - {"1994 Nov 6 08:49:37", 784111777 }, - {"GMT 08:49:37 06-Nov-94 Sunday", 784111777 }, - {"94 6 Nov 08:49:37", 784111777 }, - {"1994 Nov 6", 784080000 }, - {"06-Nov-94", 784080000 }, - {"Sun Nov 6 94", 784080000 }, - {"1994.Nov.6", 784080000 }, - {"Sun/Nov/6/94/GMT", 784080000 }, - {"Sun, 06 Nov 1994 08:49:37 CET", 784108177 }, - {"06 Nov 1994 08:49:37 EST", 784129777 }, - {"Sun, 06 Nov 1994 08:49:37 UT", 784111777 }, - {"Sun, 12 Sep 2004 15:05:58 -0700", 1095026758 }, - {"Sat, 11 Sep 2004 21:32:11 +0200", 1094931131 }, - {"20040912 15:05:58 -0700", 1095026758 }, - {"20040911 +0200", 1094853600 }, - {"Thu, 01-Jan-1970 00:59:59 GMT", 3599 }, - {"Thu, 01-Jan-1970 01:00:00 GMT", 3600 }, - {"Sat, 15-Apr-17 21:01:22 GMT", 1492290082 }, - {"Thu, 19-Apr-2007 16:00:00 GMT", 1176998400 }, - {"Wed, 25 Apr 2007 21:02:13 GMT", 1177534933 }, - {"Thu, 19/Apr\\2007 16:00:00 GMT", 1176998400 }, - {"Fri, 1 Jan 2010 01:01:50 GMT", 1262307710 }, - {"Wednesday, 1-Jan-2003 00:00:00 GMT", 1041379200 }, - {", 1-Jan-2003 00:00:00 GMT", 1041379200 }, - {"1-Jan-2003 00:00:00 GMT", 1041379200 }, - {"1-Jan-2003 00:00:00 GMT", 1041379200 }, - {"Wed,18-Apr-07 22:50:12 GMT", 1176936612 }, - {"WillyWonka , 18-Apr-07 22:50:12 GMT", -1 }, - {"WillyWonka , 18-Apr-07 22:50:12", -1 }, - {"WillyWonka , 18-apr-07 22:50:12", -1 }, - {"Mon, 18-Apr-1977 22:50:13 GMT", 230251813 }, - {"Mon, 18-Apr-77 22:50:13 GMT", 230251813 }, - {"Sat, 15-Apr-17\"21:01:22\"GMT", 1492290082 }, - {"Partyday, 18- April-07 22:50:12", -1 }, - {"Partyday, 18 - Apri-07 22:50:12", -1 }, - {"Wednes, 1-Januar-2003 00:00:00 GMT", -1 }, - {"Sat, 15-Apr-17 21:01:22", 1492290082 }, - {"Sat, 15-Apr-17 21:01:22 GMT-2", 1492290082 }, - {"Sat, 15-Apr-17 21:01:22 GMT BLAH", 1492290082 }, - {"Sat, 15-Apr-17 21:01:22 GMT-0400", 1492290082 }, - {"Sat, 15-Apr-17 21:01:22 GMT-0400 (EDT)", 1492290082 }, - {"Sat, 15-Apr-17 21:01:22 DST", -1 }, - {"Sat, 15-Apr-17 21:01:22 -0400", 1492304482 }, - {"Sat, 15-Apr-17 21:01:22 (hello there)", -1 }, - {"Sat, 15-Apr-17 21:01:22 11:22:33", -1 }, - {"Sat, 15-Apr-17 ::00 21:01:22", -1 }, - {"Sat, 15-Apr-17 boink:z 21:01:22", -1 }, - {"Sat, 15-Apr-17 91:22:33 21:01:22", -1 }, - {"Thu Apr 18 22:50:12 2007 GMT", 1176936612 }, - {"22:50:12 Thu Apr 18 2007 GMT", 1176936612 }, - {"Thu 22:50:12 Apr 18 2007 GMT", 1176936612 }, - {"Thu Apr 22:50:12 18 2007 GMT", 1176936612 }, - {"Thu Apr 18 22:50:12 2007 GMT", 1176936612 }, - {"Thu Apr 18 2007 22:50:12 GMT", 1176936612 }, - {"Thu Apr 18 2007 GMT 22:50:12", 1176936612 }, + static const struct dcheck dates[] = { + {"Sun, 06 Nov 1994 08:49:37 GMT", 784111777 }, + {"Sunday, 06-Nov-94 08:49:37 GMT", 784111777 }, + {"Sun Nov 6 08:49:37 1994", 784111777 }, + {"Sun Nov 6 8:49:37 1994", 784111777 }, + {"Sun Nov 6 8:9:37 1994", 784109377 }, + {"Sun Nov 6 008:09:37 1994", -1 }, + {"Nov Sun 6 8:9:7 1994", 784109347 }, + {"06 Nov 1994 08:49:37 GMT", 784111777 }, + {"06-Nov-94 08:49:37 GMT", 784111777 }, + {"Nov 6 08:49:37 1994", 784111777 }, + {"06 Nov 1994 08:49:37", 784111777 }, + {"06-Nov-94 08:49:37", 784111777 }, + {"1994 Nov 6 08:49:37", 784111777 }, + {"GMT 08:49:37 06-Nov-94 Sunday", 784111777 }, + {"94 6 Nov 08:49:37", 784111777 }, + {"1994 Nov 6", 784080000 }, + {"06-Nov-94", 784080000 }, + {"Sun Nov 6 94", 784080000 }, + {"1994.Nov.6", 784080000 }, + {"Sun/Nov/6/94/GMT", 784080000 }, + {"Sun, 06 Nov 1994 08:49:37 CET", 784108177 }, + {"06 Nov 1994 08:49:37 EST", 784129777 }, + {"Sun, 06 Nov 1994 08:49:37 UT", 784111777 }, + {"Sun, 12 Sep 2004 15:05:58 -0700", 1095026758 }, + {"Sat, 11 Sep 2004 21:32:11 +0200", 1094931131 }, + {"20040912 15:05:58 -0700", 1095026758 }, + {"20040911 +0200", 1094853600 }, + {"Thu, 01-Jan-1970 00:59:59 GMT", 3599 }, + {"Thu, 01-Jan-1970 01:00:00 GMT", 3600 }, + {"Sat, 15-Apr-17 21:01:22 GMT", 1492290082 }, + {"Thu, 19-Apr-2007 16:00:00 GMT", 1176998400 }, + {"Wed, 25 Apr 2007 21:02:13 GMT", 1177534933 }, + {"Thu, 19/Apr\\2007 16:00:00 GMT", 1176998400 }, + {"Fri, 1 Jan 2010 01:01:50 GMT", 1262307710 }, + {"Wednesday, 1-Jan-2003 00:00:00 GMT", 1041379200 }, + {", 1-Jan-2003 00:00:00 GMT", 1041379200 }, + {"1-Jan-2003 00:00:00 GMT", 1041379200 }, + {"1-Jan-2003 00:00:00 GMT", 1041379200 }, + {"Wed,18-Apr-07 22:50:12 GMT", 1176936612 }, + {"WillyWonka , 18-Apr-07 22:50:12 GMT", -1 }, + {"WillyWonka , 18-Apr-07 22:50:12", -1 }, + {"WillyWonka , 18-apr-07 22:50:12", -1 }, + {"Mon, 18-Apr-1977 22:50:13 GMT", 230251813 }, + {"Mon, 18-Apr-77 22:50:13 GMT", 230251813 }, + {"Sat, 15-Apr-17\"21:01:22\"GMT", 1492290082 }, + {"Partyday, 18- April-07 22:50:12", -1 }, + {"Partyday, 18 - Apri-07 22:50:12", -1 }, + {"Wednes, 1-Januar-2003 00:00:00 GMT", -1 }, + {"Sat, 15-Apr-17 21:01:22", 1492290082 }, + {"Sat, 15-Apr-17 21:01:22 GMT-2", 1492290082 }, + {"Sat, 15-Apr-17 21:01:22 GMT BLAH", 1492290082 }, + {"Sat, 15-Apr-17 21:01:22 GMT-0400", 1492290082 }, + {"Sat, 15-Apr-17 21:01:22 GMT-0400 (EDT)", 1492290082 }, + {"Sat, 15-Apr-17 21:01:22 DST", -1 }, + {"Sat, 15-Apr-17 21:01:22 -0400", 1492304482 }, + {"Sat, 15-Apr-17 21:01:22 (hello there)", -1 }, + {"Sat, 15-Apr-17 21:01:22 11:22:33", -1 }, + {"Sat, 15-Apr-17 ::00 21:01:22", -1 }, + {"Sat, 15-Apr-17 boink:z 21:01:22", -1 }, + {"Sat, 15-Apr-17 91:22:33 21:01:22", -1 }, + {"Thu Apr 18 22:50:12 2007 GMT", 1176936612 }, + {"22:50:12 Thu Apr 18 2007 GMT", 1176936612 }, + {"Thu 22:50:12 Apr 18 2007 GMT", 1176936612 }, + {"Thu Apr 22:50:12 18 2007 GMT", 1176936612 }, + {"Thu Apr 18 22:50:12 2007 GMT", 1176936612 }, + {"Thu Apr 18 2007 22:50:12 GMT", 1176936612 }, + {"Thu Apr 18 2007 GMT 22:50:12", 1176936612 }, - {"\"Thu Apr 18 22:50:12 2007 GMT\"", 1176936612 }, - {"-\"22:50:12 Thu Apr 18 2007 GMT\"", 1176936612 }, - {"*\"Thu 22:50:12 Apr 18 2007 GMT\"", 1176936612 }, - {";\"Thu Apr 22:50:12 18 2007 GMT\"", 1176936612 }, - {".\"Thu Apr 18 22:50:12 2007 GMT\"", 1176936612 }, - {"\"Thu Apr 18 2007 22:50:12 GMT\"", 1176936612 }, - {"\"Thu Apr 18 2007 GMT 22:50:12\"", 1176936612 }, + {"\"Thu Apr 18 22:50:12 2007 GMT\"", 1176936612 }, + {"-\"22:50:12 Thu Apr 18 2007 GMT\"", 1176936612 }, + {"*\"Thu 22:50:12 Apr 18 2007 GMT\"", 1176936612 }, + {";\"Thu Apr 22:50:12 18 2007 GMT\"", 1176936612 }, + {".\"Thu Apr 18 22:50:12 2007 GMT\"", 1176936612 }, + {"\"Thu Apr 18 2007 22:50:12 GMT\"", 1176936612 }, + {"\"Thu Apr 18 2007 GMT 22:50:12\"", 1176936612 }, - {"Sat, 15-Apr-17 21:01:22 GMT", 1492290082 }, - {"15-Sat, Apr-17 21:01:22 GMT", 1492290082 }, - {"15-Sat, Apr 21:01:22 GMT 17", 1492290082 }, - {"15-Sat, Apr 21:01:22 GMT 2017", 1492290082 }, - {"15 Apr 21:01:22 2017", 1492290082 }, - {"15 17 Apr 21:01:22", 1492290082 }, - {"Apr 15 17 21:01:22", 1492290082 }, - {"Apr 15 21:01:22 17", 1492290082 }, - {"2017 April 15 21:01:22", -1 }, - {"15 April 2017 21:01:22", -1 }, - {"98 April 17 21:01:22", -1 }, - {"Thu, 012-Aug-2008 20:49:07 GMT", 1218574147 }, - {"Thu, 999999999999-Aug-2007 20:49:07 GMT", -1 }, - {"Thu, 12-Aug-2007 20:61:99999999999 GMT", -1 }, - {"IAintNoDateFool", -1 }, - {"Thu Apr 18 22:50 2007 GMT", 1176936600 }, - {"20110623 12:34:56", 1308832496 }, - {"20110632 12:34:56", -1 }, - {"20110623 56:34:56", -1 }, - {"20111323 12:34:56", -1 }, - {"20110623 12:34:79", -1 }, - {"Wed, 31 Dec 2008 23:59:60 GMT", 1230768000 }, - {"Wed, 31 Dec 2008 23:59:61 GMT", -1 }, - {"Wed, 31 Dec 2008 24:00:00 GMT", -1 }, - {"Wed, 31 Dec 2008 23:60:59 GMT", -1 }, - {"20110623 12:3", 1308830580 }, - {"20110623 1:3", 1308790980 }, - {"20110623 1:30", 1308792600 }, - {"20110623 12:12:3", 1308831123 }, - {"20110623 01:12:3", 1308791523 }, - {"20110623 01:99:30", -1 }, - {"Thu, 01-Jan-1970 00:00:00 GMT", 0 }, - {"Thu, 31-Dec-1969 23:59:58 GMT", -2 }, - {"Thu, 31-Dec-1969 23:59:59 GMT", 0 }, /* avoids -1 ! */ + {"Sat, 15-Apr-17 21:01:22 GMT", 1492290082 }, + {"15-Sat, Apr-17 21:01:22 GMT", 1492290082 }, + {"15-Sat, Apr 21:01:22 GMT 17", 1492290082 }, + {"15-Sat, Apr 21:01:22 GMT 2017", 1492290082 }, + {"15 Apr 21:01:22 2017", 1492290082 }, + {"15 17 Apr 21:01:22", 1492290082 }, + {"Apr 15 17 21:01:22", 1492290082 }, + {"Apr 15 21:01:22 17", 1492290082 }, + {"2017 April 15 21:01:22", -1 }, + {"15 April 2017 21:01:22", -1 }, + {"98 April 17 21:01:22", -1 }, + {"Thu, 012-Aug-2008 20:49:07 GMT", 1218574147 }, + {"Thu, 999999999999-Aug-2007 20:49:07 GMT", -1 }, + {"Thu, 12-Aug-2007 20:61:99999999999 GMT", -1 }, + {"IAintNoDateFool", -1 }, + {"Thu Apr 18 22:50 2007 GMT", 1176936600 }, + {"20110623 12:34:56", 1308832496 }, + {"20110632 12:34:56", -1 }, + {"20110623 56:34:56", -1 }, + {"20111323 12:34:56", -1 }, + {"20110623 12:34:79", -1 }, + {"Wed, 31 Dec 2008 23:59:60 GMT", 1230768000 }, + {"Wed, 31 Dec 2008 23:59:61 GMT", -1 }, + {"Wed, 31 Dec 2008 24:00:00 GMT", -1 }, + {"Wed, 31 Dec 2008 23:60:59 GMT", -1 }, + {"20110623 12:3", 1308830580 }, + {"20110623 1:3", 1308790980 }, + {"20110623 1:30", 1308792600 }, + {"20110623 12:12:3", 1308831123 }, + {"20110623 01:12:3", 1308791523 }, + {"20110623 01:99:30", -1 }, + {"Thu, 01-Jan-1970 00:00:00 GMT", 0 }, + {"Thu, 31-Dec-1969 23:59:58 GMT", -2 }, + {"Thu, 31-Dec-1969 23:59:59 GMT", 0 }, /* avoids -1 ! */ #if SIZEOF_TIME_T > 4 - {"Sun, 06 Nov 2044 08:49:37 GMT", (time_t) CURL_OFF_TU_C(2362034977) }, - {"Sun, 06 Nov 3144 08:49:37 GMT", 37074617377 }, + {"Sun, 06 Nov 2044 08:49:37 GMT", (time_t)2362034977LL }, + {"Sun, 06 Nov 3144 08:49:37 GMT", 37074617377 }, #ifndef HAVE_TIME_T_UNSIGNED -#if 0 - /* causes warning on MSVC */ - {"Sun, 06 Nov 1900 08:49:37 GMT", -2182259423 }, -#endif - {"Sun, 06 Nov 1800 08:49:37 GMT", -5337933023 }, - {"Thu, 01-Jan-1583 00:00:00 GMT", -12212553600 }, -#endif - {"Thu, 01-Jan-1499 00:00:00 GMT", -1 }, + {"Sun, 06 Nov 1900 08:49:37 GMT", (time_t)-2182259423LL }, + {"Sun, 06 Nov 1800 08:49:37 GMT", -5337933023 }, + {"Thu, 01-Jan-1583 00:00:00 GMT", -12212553600 }, +#endif /* HAVE_TIME_T_UNSIGNED */ + {"Thu, 01-Jan-1499 00:00:00 GMT", -1 }, #else - {"Sun, 06 Nov 2044 08:49:37 GMT", -1 }, -#endif + {"Sun, 06 Nov 2044 08:49:37 GMT", -1 }, +#endif /* SIZEOF_TIME_T > 4 */ #ifndef HAVE_TIME_T_UNSIGNED - {"Sun, 06 Nov 1968 08:49:37 GMT", -36342623 }, -#endif - { NULL, 0 } -}; + {"Sun, 06 Nov 1968 08:49:37 GMT", -36342623 }, +#endif /* !HAVE_TIME_T_UNSIGNED */ + { NULL, 0 } + }; -CURLcode test(char *URL) -{ int i; int error = 0; @@ -172,8 +169,10 @@ CURLcode test(char *URL) for(i = 0; dates[i].input; i++) { time_t out = curl_getdate(dates[i].input, NULL); if(out != dates[i].output) { - curl_mprintf("WRONGLY %s => %ld (instead of %ld)\n", - dates[i].input, (long)out, (long)dates[i].output); + curl_mprintf("WRONGLY %s => %" CURL_FORMAT_CURL_OFF_T + " (instead of %" CURL_FORMAT_CURL_OFF_T ")\n", + dates[i].input, + (curl_off_t)out, (curl_off_t)dates[i].output); error++; } } diff --git a/vendor/curl/tests/libtest/lib518.c b/vendor/curl/tests/libtest/lib518.c index 3bc2fa5ed97..86eddec003e 100644 --- a/vendor/curl/tests/libtest/lib518.c +++ b/vendor/curl/tests/libtest/lib518.c @@ -21,26 +21,19 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#ifdef HAVE_SYS_RESOURCE_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#include - -#include "warnless.h" +#include "testutil.h" #include "memdebug.h" #ifndef FD_SETSIZE #error "this test requires FD_SETSIZE" #endif -#define SAFETY_MARGIN (16) +#define T518_SAFETY_MARGIN (16) + #define NUM_OPEN (FD_SETSIZE + 10) -#define NUM_NEEDED (NUM_OPEN + SAFETY_MARGIN) +#define NUM_NEEDED (NUM_OPEN + T518_SAFETY_MARGIN) #if defined(_WIN32) || defined(MSDOS) #define DEV_NULL "NUL" @@ -50,31 +43,31 @@ #if defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) -static int *testfd = NULL; -static struct rlimit num_open; -static char msgbuff[256]; +static int *t518_testfd = NULL; +static struct rlimit t518_num_open; +static char t518_msgbuff[256]; -static void store_errmsg(const char *msg, int err) +static void t518_store_errmsg(const char *msg, int err) { if(!err) - curl_msnprintf(msgbuff, sizeof(msgbuff), "%s", msg); + curl_msnprintf(t518_msgbuff, sizeof(t518_msgbuff), "%s", msg); else - curl_msnprintf(msgbuff, sizeof(msgbuff), "%s, errno %d, %s", msg, - err, strerror(err)); + curl_msnprintf(t518_msgbuff, sizeof(t518_msgbuff), "%s, errno %d, %s", msg, + err, strerror(err)); } -static void close_file_descriptors(void) +static void t518_close_file_descriptors(void) { - for(num_open.rlim_cur = 0; - num_open.rlim_cur < num_open.rlim_max; - num_open.rlim_cur++) - if(testfd[num_open.rlim_cur] > 0) - close(testfd[num_open.rlim_cur]); - free(testfd); - testfd = NULL; + for(t518_num_open.rlim_cur = 0; + t518_num_open.rlim_cur < t518_num_open.rlim_max; + t518_num_open.rlim_cur++) + if(t518_testfd[t518_num_open.rlim_cur] > 0) + close(t518_testfd[t518_num_open.rlim_cur]); + free(t518_testfd); + t518_testfd = NULL; } -static int fopen_works(void) +static int t518_fopen_works(void) { FILE *fpa[3]; int i; @@ -86,8 +79,8 @@ static int fopen_works(void) for(i = 0; i < 3; i++) { fpa[i] = fopen(DEV_NULL, FOPEN_READTEXT); if(!fpa[i]) { - store_errmsg("fopen failed", errno); - curl_mfprintf(stderr, "%s\n", msgbuff); + t518_store_errmsg("fopen failed", errno); + curl_mfprintf(stderr, "%s\n", t518_msgbuff); ret = 0; break; } @@ -99,28 +92,7 @@ static int fopen_works(void) return ret; } -static void rlim2str(char *buf, size_t len, rlim_t val) -{ -#ifdef RLIM_INFINITY - if(val == RLIM_INFINITY) { - curl_msnprintf(buf, len, "INFINITY"); - return; - } -#endif -#ifdef HAVE_LONGLONG - if(sizeof(rlim_t) > sizeof(long)) - curl_msnprintf(buf, len, "%llu", (unsigned long long)val); - else -#endif - { - if(sizeof(rlim_t) < sizeof(long)) - curl_msnprintf(buf, len, "%u", (unsigned int)val); - else - curl_msnprintf(buf, len, "%lu", (unsigned long)val); - } -} - -static int test_rlimit(int keep_open) +static int t518_test_rlimit(int keep_open) { rlim_t nitems, i; int *memchunk = NULL; @@ -132,17 +104,17 @@ static int test_rlimit(int keep_open) /* get initial open file limits */ if(getrlimit(RLIMIT_NOFILE, &rl) != 0) { - store_errmsg("getrlimit() failed", errno); - curl_mfprintf(stderr, "%s\n", msgbuff); + t518_store_errmsg("getrlimit() failed", errno); + curl_mfprintf(stderr, "%s\n", t518_msgbuff); return -1; } /* show initial open file limits */ - rlim2str(strbuff, sizeof(strbuff), rl.rlim_cur); + tutil_rlim2str(strbuff, sizeof(strbuff), rl.rlim_cur); curl_mfprintf(stderr, "initial soft limit: %s\n", strbuff); - rlim2str(strbuff, sizeof(strbuff), rl.rlim_max); + tutil_rlim2str(strbuff, sizeof(strbuff), rl.rlim_max); curl_mfprintf(stderr, "initial hard limit: %s\n", strbuff); /* show our constants */ @@ -169,9 +141,9 @@ static int test_rlimit(int keep_open) rl.rlim_cur = OPEN_MAX; if(setrlimit(RLIMIT_NOFILE, &rl) != 0) { /* on failure don't abort just issue a warning */ - store_errmsg("setrlimit() failed", errno); - curl_mfprintf(stderr, "%s\n", msgbuff); - msgbuff[0] = '\0'; + t518_store_errmsg("setrlimit() failed", errno); + curl_mfprintf(stderr, "%s\n", t518_msgbuff); + t518_msgbuff[0] = '\0'; } } #endif @@ -180,25 +152,25 @@ static int test_rlimit(int keep_open) rl.rlim_cur = rl.rlim_max; if(setrlimit(RLIMIT_NOFILE, &rl) != 0) { /* on failure don't abort just issue a warning */ - store_errmsg("setrlimit() failed", errno); - curl_mfprintf(stderr, "%s\n", msgbuff); - msgbuff[0] = '\0'; + t518_store_errmsg("setrlimit() failed", errno); + curl_mfprintf(stderr, "%s\n", t518_msgbuff); + t518_msgbuff[0] = '\0'; } /* get current open file limits */ if(getrlimit(RLIMIT_NOFILE, &rl) != 0) { - store_errmsg("getrlimit() failed", errno); - curl_mfprintf(stderr, "%s\n", msgbuff); + t518_store_errmsg("getrlimit() failed", errno); + curl_mfprintf(stderr, "%s\n", t518_msgbuff); return -3; } /* show current open file limits */ - rlim2str(strbuff, sizeof(strbuff), rl.rlim_cur); + tutil_rlim2str(strbuff, sizeof(strbuff), rl.rlim_cur); curl_mfprintf(stderr, "current soft limit: %s\n", strbuff); - rlim2str(strbuff, sizeof(strbuff), rl.rlim_max); + tutil_rlim2str(strbuff, sizeof(strbuff), rl.rlim_max); curl_mfprintf(stderr, "current hard limit: %s\n", strbuff); } /* (rl.rlim_cur != rl.rlim_max) */ @@ -214,23 +186,23 @@ static int test_rlimit(int keep_open) /* * verify that soft limit is higher than NUM_NEEDED, * which is the number of file descriptors we would - * try to open plus SAFETY_MARGIN to not exhaust the + * try to open plus T518_SAFETY_MARGIN to not exhaust the * file descriptor pool */ - num_open.rlim_cur = NUM_NEEDED; + t518_num_open.rlim_cur = NUM_NEEDED; if((rl.rlim_cur > 0) && #ifdef RLIM_INFINITY (rl.rlim_cur != RLIM_INFINITY) && #endif - (rl.rlim_cur <= num_open.rlim_cur)) { - rlim2str(strbuff2, sizeof(strbuff2), rl.rlim_cur); - rlim2str(strbuff1, sizeof(strbuff1), num_open.rlim_cur); + (rl.rlim_cur <= t518_num_open.rlim_cur)) { + tutil_rlim2str(strbuff2, sizeof(strbuff2), rl.rlim_cur); + tutil_rlim2str(strbuff1, sizeof(strbuff1), t518_num_open.rlim_cur); curl_msnprintf(strbuff, sizeof(strbuff), "fds needed %s > system limit %s", - strbuff1, strbuff2); - store_errmsg(strbuff, 0); - curl_mfprintf(stderr, "%s\n", msgbuff); + strbuff1, strbuff2); + t518_store_errmsg(strbuff, 0); + curl_mfprintf(stderr, "%s\n", t518_msgbuff); return -4; } @@ -239,7 +211,7 @@ static int test_rlimit(int keep_open) * avoid a low memory condition once the file descriptors are * open. System conditions that could make the test fail should * be addressed in the precheck phase. This chunk of memory shall - * be always free()ed before exiting the test_rlimit() function so + * be always free()ed before exiting the t518_test_rlimit() function so * that it becomes available to the test. */ @@ -248,8 +220,8 @@ static int test_rlimit(int keep_open) if(nitems > 0x7fff) nitems = 0x40000; do { - num_open.rlim_max = sizeof(*memchunk) * nitems; - rlim2str(strbuff, sizeof(strbuff), num_open.rlim_max); + t518_num_open.rlim_max = sizeof(*memchunk) * nitems; + tutil_rlim2str(strbuff, sizeof(strbuff), t518_num_open.rlim_max); curl_mfprintf(stderr, "allocating memchunk %s byte array\n", strbuff); memchunk = malloc(sizeof(*memchunk) * (size_t)nitems); if(!memchunk) { @@ -258,8 +230,8 @@ static int test_rlimit(int keep_open) } } while(nitems && !memchunk); if(!memchunk) { - store_errmsg("memchunk, malloc() failed", errno); - curl_mfprintf(stderr, "%s\n", msgbuff); + t518_store_errmsg("memchunk, malloc() failed", errno); + curl_mfprintf(stderr, "%s\n", t518_msgbuff); return -5; } @@ -272,30 +244,31 @@ static int test_rlimit(int keep_open) /* set the number of file descriptors we will try to open */ - num_open.rlim_max = NUM_OPEN; + t518_num_open.rlim_max = NUM_OPEN; /* verify that we won't overflow size_t in malloc() */ - if((size_t)(num_open.rlim_max) > ((size_t)-1) / sizeof(*testfd)) { - rlim2str(strbuff1, sizeof(strbuff1), num_open.rlim_max); + if((size_t)(t518_num_open.rlim_max) > ((size_t)-1) / sizeof(*t518_testfd)) { + tutil_rlim2str(strbuff1, sizeof(strbuff1), t518_num_open.rlim_max); curl_msnprintf(strbuff, sizeof(strbuff), "unable to allocate an array for %s " "file descriptors, would overflow size_t", strbuff1); - store_errmsg(strbuff, 0); - curl_mfprintf(stderr, "%s\n", msgbuff); + t518_store_errmsg(strbuff, 0); + curl_mfprintf(stderr, "%s\n", t518_msgbuff); free(memchunk); return -6; } /* allocate array for file descriptors */ - rlim2str(strbuff, sizeof(strbuff), num_open.rlim_max); + tutil_rlim2str(strbuff, sizeof(strbuff), t518_num_open.rlim_max); curl_mfprintf(stderr, "allocating array for %s file descriptors\n", strbuff); - testfd = malloc(sizeof(*testfd) * (size_t)(num_open.rlim_max)); - if(!testfd) { - store_errmsg("testfd, malloc() failed", errno); - curl_mfprintf(stderr, "%s\n", msgbuff); + t518_testfd = malloc(sizeof(*t518_testfd) * + (size_t)(t518_num_open.rlim_max)); + if(!t518_testfd) { + t518_store_errmsg("testfd, malloc() failed", errno); + curl_mfprintf(stderr, "%s\n", t518_msgbuff); free(memchunk); return -7; } @@ -304,70 +277,70 @@ static int test_rlimit(int keep_open) curl_mfprintf(stderr, "initializing testfd array\n"); - for(num_open.rlim_cur = 0; - num_open.rlim_cur < num_open.rlim_max; - num_open.rlim_cur++) - testfd[num_open.rlim_cur] = -1; + for(t518_num_open.rlim_cur = 0; + t518_num_open.rlim_cur < t518_num_open.rlim_max; + t518_num_open.rlim_cur++) + t518_testfd[t518_num_open.rlim_cur] = -1; - rlim2str(strbuff, sizeof(strbuff), num_open.rlim_max); + tutil_rlim2str(strbuff, sizeof(strbuff), t518_num_open.rlim_max); curl_mfprintf(stderr, "trying to open %s file descriptors\n", strbuff); /* open a dummy descriptor */ - testfd[0] = open(DEV_NULL, O_RDONLY); - if(testfd[0] < 0) { + t518_testfd[0] = open(DEV_NULL, O_RDONLY); + if(t518_testfd[0] < 0) { curl_msnprintf(strbuff, sizeof(strbuff), "opening of %s failed", DEV_NULL); - store_errmsg(strbuff, errno); - curl_mfprintf(stderr, "%s\n", msgbuff); - free(testfd); - testfd = NULL; + t518_store_errmsg(strbuff, errno); + curl_mfprintf(stderr, "%s\n", t518_msgbuff); + free(t518_testfd); + t518_testfd = NULL; free(memchunk); return -8; } /* create a bunch of file descriptors */ - for(num_open.rlim_cur = 1; - num_open.rlim_cur < num_open.rlim_max; - num_open.rlim_cur++) { + for(t518_num_open.rlim_cur = 1; + t518_num_open.rlim_cur < t518_num_open.rlim_max; + t518_num_open.rlim_cur++) { - testfd[num_open.rlim_cur] = dup(testfd[0]); + t518_testfd[t518_num_open.rlim_cur] = dup(t518_testfd[0]); - if(testfd[num_open.rlim_cur] < 0) { + if(t518_testfd[t518_num_open.rlim_cur] < 0) { - testfd[num_open.rlim_cur] = -1; + t518_testfd[t518_num_open.rlim_cur] = -1; - rlim2str(strbuff1, sizeof(strbuff1), num_open.rlim_cur); + tutil_rlim2str(strbuff1, sizeof(strbuff1), t518_num_open.rlim_cur); curl_msnprintf(strbuff, sizeof(strbuff), "dup() attempt %s failed", strbuff1); curl_mfprintf(stderr, "%s\n", strbuff); - rlim2str(strbuff1, sizeof(strbuff1), num_open.rlim_cur); + tutil_rlim2str(strbuff1, sizeof(strbuff1), t518_num_open.rlim_cur); curl_msnprintf(strbuff, sizeof(strbuff), "fds system limit seems close to %s", strbuff1); curl_mfprintf(stderr, "%s\n", strbuff); - num_open.rlim_max = NUM_NEEDED; + t518_num_open.rlim_max = NUM_NEEDED; - rlim2str(strbuff2, sizeof(strbuff2), num_open.rlim_max); - rlim2str(strbuff1, sizeof(strbuff1), num_open.rlim_cur); + tutil_rlim2str(strbuff2, sizeof(strbuff2), t518_num_open.rlim_max); + tutil_rlim2str(strbuff1, sizeof(strbuff1), t518_num_open.rlim_cur); curl_msnprintf(strbuff, sizeof(strbuff), "fds needed %s > system limit %s", strbuff2, strbuff1); - store_errmsg(strbuff, 0); - curl_mfprintf(stderr, "%s\n", msgbuff); - - for(num_open.rlim_cur = 0; - testfd[num_open.rlim_cur] >= 0; - num_open.rlim_cur++) - close(testfd[num_open.rlim_cur]); - free(testfd); - testfd = NULL; + t518_store_errmsg(strbuff, 0); + curl_mfprintf(stderr, "%s\n", t518_msgbuff); + + for(t518_num_open.rlim_cur = 0; + t518_testfd[t518_num_open.rlim_cur] >= 0; + t518_num_open.rlim_cur++) + close(t518_testfd[t518_num_open.rlim_cur]); + free(t518_testfd); + t518_testfd = NULL; free(memchunk); return -9; } } - rlim2str(strbuff, sizeof(strbuff), num_open.rlim_max); + tutil_rlim2str(strbuff, sizeof(strbuff), t518_num_open.rlim_max); curl_mfprintf(stderr, "%s file descriptors open\n", strbuff); #if !defined(HAVE_POLL) && !defined(USE_WINSOCK) @@ -383,28 +356,28 @@ static int test_rlimit(int keep_open) * with an indication that select limit would be exceeded. */ - num_open.rlim_cur = FD_SETSIZE - SAFETY_MARGIN; - if(num_open.rlim_max > num_open.rlim_cur) { + t518_num_open.rlim_cur = FD_SETSIZE - T518_SAFETY_MARGIN; + if(t518_num_open.rlim_max > t518_num_open.rlim_cur) { curl_msnprintf(strbuff, sizeof(strbuff), "select limit is FD_SETSIZE %d", - FD_SETSIZE); - store_errmsg(strbuff, 0); - curl_mfprintf(stderr, "%s\n", msgbuff); - close_file_descriptors(); + FD_SETSIZE); + t518_store_errmsg(strbuff, 0); + curl_mfprintf(stderr, "%s\n", t518_msgbuff); + t518_close_file_descriptors(); free(memchunk); return -10; } - num_open.rlim_cur = FD_SETSIZE - SAFETY_MARGIN; + t518_num_open.rlim_cur = FD_SETSIZE - T518_SAFETY_MARGIN; for(rl.rlim_cur = 0; - rl.rlim_cur < num_open.rlim_max; + rl.rlim_cur < t518_num_open.rlim_max; rl.rlim_cur++) { - if((testfd[rl.rlim_cur] > 0) && - ((unsigned int)testfd[rl.rlim_cur] > num_open.rlim_cur)) { + if((t518_testfd[rl.rlim_cur] > 0) && + ((unsigned int)t518_testfd[rl.rlim_cur] > t518_num_open.rlim_cur)) { curl_msnprintf(strbuff, sizeof(strbuff), "select limit is FD_SETSIZE %d", - FD_SETSIZE); - store_errmsg(strbuff, 0); - curl_mfprintf(stderr, "%s\n", msgbuff); - close_file_descriptors(); + FD_SETSIZE); + t518_store_errmsg(strbuff, 0); + curl_mfprintf(stderr, "%s\n", t518_msgbuff); + t518_close_file_descriptors(); free(memchunk); return -11; } @@ -421,15 +394,15 @@ static int test_rlimit(int keep_open) * if it is capable of fopen()ing some additional files. */ - if(!fopen_works()) { - rlim2str(strbuff1, sizeof(strbuff1), num_open.rlim_max); + if(!t518_fopen_works()) { + tutil_rlim2str(strbuff1, sizeof(strbuff1), t518_num_open.rlim_max); curl_msnprintf(strbuff, sizeof(strbuff), "fopen fails with %s fds open", - strbuff1); - curl_mfprintf(stderr, "%s\n", msgbuff); + strbuff1); + curl_mfprintf(stderr, "%s\n", t518_msgbuff); curl_msnprintf(strbuff, sizeof(strbuff), "fopen fails with lots of fds open"); - store_errmsg(strbuff, 0); - close_file_descriptors(); + t518_store_errmsg(strbuff, 0); + t518_close_file_descriptors(); free(memchunk); return -12; } @@ -442,27 +415,27 @@ static int test_rlimit(int keep_open) /* close file descriptors unless instructed to keep them */ if(!keep_open) { - close_file_descriptors(); + t518_close_file_descriptors(); } return 0; } -CURLcode test(char *URL) +static CURLcode test_lib518(const char *URL) { CURLcode res; CURL *curl; if(!strcmp(URL, "check")) { /* used by the test script to ask if we can run this test or not */ - if(test_rlimit(FALSE)) { - curl_mfprintf(stdout, "test_rlimit problem: %s\n", msgbuff); + if(t518_test_rlimit(FALSE)) { + curl_mfprintf(stdout, "test_rlimit problem: %s\n", t518_msgbuff); return TEST_ERR_FAILURE; } return CURLE_OK; /* sure, run this! */ } - if(test_rlimit(TRUE)) { + if(t518_test_rlimit(TRUE)) { /* failure */ return TEST_ERR_MAJOR_BAD; } @@ -472,14 +445,14 @@ CURLcode test(char *URL) if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { curl_mfprintf(stderr, "curl_global_init() failed\n"); - close_file_descriptors(); + t518_close_file_descriptors(); return TEST_ERR_MAJOR_BAD; } curl = curl_easy_init(); if(!curl) { curl_mfprintf(stderr, "curl_easy_init() failed\n"); - close_file_descriptors(); + t518_close_file_descriptors(); curl_global_cleanup(); return TEST_ERR_MAJOR_BAD; } @@ -491,20 +464,20 @@ CURLcode test(char *URL) test_cleanup: - close_file_descriptors(); + t518_close_file_descriptors(); curl_easy_cleanup(curl); curl_global_cleanup(); return res; } -#else /* defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) */ +#else /* HAVE_GETRLIMIT && HAVE_SETRLIMIT */ -CURLcode test(char *URL) +static CURLcode test_lib518(const char *URL) { (void)URL; curl_mprintf("system lacks necessary system function(s)"); - return 1; /* skip test */ + return TEST_ERR_MAJOR_BAD; /* skip test */ } -#endif /* defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) */ +#endif /* HAVE_GETRLIMIT && HAVE_SETRLIMIT */ diff --git a/vendor/curl/tests/libtest/lib519.c b/vendor/curl/tests/libtest/lib519.c index 2f92f73864f..615e8aac8a5 100644 --- a/vendor/curl/tests/libtest/lib519.c +++ b/vendor/curl/tests/libtest/lib519.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib519(const char *URL) { CURLcode res; CURL *curl; diff --git a/vendor/curl/tests/libtest/lib520.c b/vendor/curl/tests/libtest/lib520.c index 81552019676..34f7c541e22 100644 --- a/vendor/curl/tests/libtest/lib520.c +++ b/vendor/curl/tests/libtest/lib520.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib520(const char *URL) { CURLcode res; CURL *curl; diff --git a/vendor/curl/tests/libtest/lib521.c b/vendor/curl/tests/libtest/lib521.c index cc1863d148d..32bf7b3022a 100644 --- a/vendor/curl/tests/libtest/lib521.c +++ b/vendor/curl/tests/libtest/lib521.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib521(const char *URL) { CURLcode res; CURL *curl; diff --git a/vendor/curl/tests/libtest/lib523.c b/vendor/curl/tests/libtest/lib523.c index f130d7abaeb..3b56ada894e 100644 --- a/vendor/curl/tests/libtest/lib523.c +++ b/vendor/curl/tests/libtest/lib523.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib523(const char *URL) { CURLcode res; CURL *curl; diff --git a/vendor/curl/tests/libtest/lib524.c b/vendor/curl/tests/libtest/lib524.c index 830c0d7776b..e015e58637e 100644 --- a/vendor/curl/tests/libtest/lib524.c +++ b/vendor/curl/tests/libtest/lib524.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib524(const char *URL) { CURLcode res; CURL *curl; diff --git a/vendor/curl/tests/libtest/lib525.c b/vendor/curl/tests/libtest/lib525.c index e1742a4afdb..6c7d6503667 100644 --- a/vendor/curl/tests/libtest/lib525.c +++ b/vendor/curl/tests/libtest/lib525.c @@ -21,17 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include - -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -CURLcode test(char *URL) +static CURLcode test_lib525(const char *URL) { CURLcode res = CURLE_OK; CURL *curl = NULL; @@ -44,20 +38,14 @@ CURLcode test(char *URL) start_test_timing(); if(!libtest_arg2) { -#ifdef LIB529 - /* test 529 */ - curl_mfprintf(stderr, "Usage: lib529 [url] [uploadfile]\n"); -#else - /* test 525 */ - curl_mfprintf(stderr, "Usage: lib525 [url] [uploadfile]\n"); -#endif + curl_mfprintf(stderr, "Usage: test [url] [uploadfile]\n"); return TEST_ERR_USAGE; } hd_src = fopen(libtest_arg2, "rb"); if(!hd_src) { curl_mfprintf(stderr, "fopen failed with error (%d) %s\n", - errno, strerror(errno)); + errno, strerror(errno)); curl_mfprintf(stderr, "Error opening file '%s'\n", libtest_arg2); return TEST_ERR_FOPEN; } @@ -71,7 +59,7 @@ CURLcode test(char *URL) if(hd == -1) { /* can't open file, bail out */ curl_mfprintf(stderr, "fstat() failed with error (%d) %s\n", - errno, strerror(errno)); + errno, strerror(errno)); curl_mfprintf(stderr, "Error opening file '%s'\n", libtest_arg2); fclose(hd_src); return TEST_ERR_FSTAT; @@ -145,21 +133,20 @@ CURLcode test(char *URL) test_cleanup: -#ifdef LIB529 - /* test 529 */ - /* proper cleanup sequence - type PA */ - curl_multi_remove_handle(m, curl); - curl_multi_cleanup(m); - curl_easy_cleanup(curl); - curl_global_cleanup(); -#else - /* test 525 */ - /* proper cleanup sequence - type PB */ - curl_multi_remove_handle(m, curl); - curl_easy_cleanup(curl); - curl_multi_cleanup(m); - curl_global_cleanup(); -#endif + if(testnum == 529) { + /* proper cleanup sequence - type PA */ + curl_multi_remove_handle(m, curl); + curl_multi_cleanup(m); + curl_easy_cleanup(curl); + curl_global_cleanup(); + } + else { /* testnum == 525 */ + /* proper cleanup sequence - type PB */ + curl_multi_remove_handle(m, curl); + curl_easy_cleanup(curl); + curl_multi_cleanup(m); + curl_global_cleanup(); + } /* close the local file */ fclose(hd_src); diff --git a/vendor/curl/tests/libtest/lib526.c b/vendor/curl/tests/libtest/lib526.c index c38d6dfebaf..963181713b2 100644 --- a/vendor/curl/tests/libtest/lib526.c +++ b/vendor/curl/tests/libtest/lib526.c @@ -27,49 +27,41 @@ * sharing within the multi handle all transfers are performed on the same * persistent connection. * - * This source code is used for lib526, lib527 and lib532 with only #ifdefs + * This source code is used for test526, test527 and test532 with branches * controlling the small differences. * - * - lib526 closes all easy handles after + * - test526 closes all easy handles after * they all have transferred the file over the single connection - * - lib527 closes each easy handle after each single transfer. - * - lib532 uses only a single easy handle that is removed, reset and then + * - test527 closes each easy handle after each single transfer. + * - test532 uses only a single easy handle that is removed, reset and then * re-added for each transfer * * Test case 526, 527 and 532 use FTP, while test 528 uses the lib526 tool but * with HTTP. */ -#include "test.h" +#include "first.h" -#include - -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -#define NUM_HANDLES 4 - -CURLcode test(char *URL) +static CURLcode test_lib526(const char *URL) { CURLcode res = CURLE_OK; CURL *curl[NUM_HANDLES]; int running; CURLM *m = NULL; - int current = 0; - int i; + size_t current = 0; + size_t i; - for(i = 0; i < NUM_HANDLES; i++) + for(i = 0; i < CURL_ARRAYSIZE(curl); i++) curl[i] = NULL; start_test_timing(); global_init(CURL_GLOBAL_ALL); - /* get NUM_HANDLES easy handles */ - for(i = 0; i < NUM_HANDLES; i++) { + /* get each easy handle */ + for(i = 0; i < CURL_ARRAYSIZE(curl); i++) { easy_init(curl[i]); /* specify target */ easy_setopt(curl[i], CURLOPT_URL, URL); @@ -96,31 +88,32 @@ CURLcode test(char *URL) abort_on_test_timeout(); if(!running) { -#ifdef LIB527 - /* NOTE: this code does not remove the handle from the multi handle - here, which would be the nice, sane and documented way of working. - This however tests that the API survives this abuse gracefully. */ - curl_easy_cleanup(curl[current]); - curl[current] = NULL; -#endif - if(++current < NUM_HANDLES) { - curl_mfprintf(stderr, "Advancing to URL %d\n", current); -#ifdef LIB532 - /* first remove the only handle we use */ - curl_multi_remove_handle(m, curl[0]); - - /* make us reuse the same handle all the time, and try resetting - the handle first too */ - curl_easy_reset(curl[0]); - easy_setopt(curl[0], CURLOPT_URL, URL); - /* go verbose */ - easy_setopt(curl[0], CURLOPT_VERBOSE, 1L); - - /* re-add it */ - multi_add_handle(m, curl[0]); -#else - multi_add_handle(m, curl[current]); -#endif + if(testnum == 527) { + /* NOTE: this code does not remove the handle from the multi handle + here, which would be the nice, sane and documented way of working. + This however tests that the API survives this abuse gracefully. */ + curl_easy_cleanup(curl[current]); + curl[current] = NULL; + } + if(++current < CURL_ARRAYSIZE(curl)) { + curl_mfprintf(stderr, "Advancing to URL %zu\n", current); + if(testnum == 532) { + /* first remove the only handle we use */ + curl_multi_remove_handle(m, curl[0]); + + /* make us reuse the same handle all the time, and try resetting + the handle first too */ + curl_easy_reset(curl[0]); + easy_setopt(curl[0], CURLOPT_URL, URL); + /* go verbose */ + easy_setopt(curl[0], CURLOPT_VERBOSE, 1L); + + /* re-add it */ + multi_add_handle(m, curl[0]); + } + else { + multi_add_handle(m, curl[current]); + } } else { break; /* done */ @@ -142,45 +135,38 @@ CURLcode test(char *URL) test_cleanup: -#if defined(LIB526) + if((testnum == 526) || (testnum == 528)) { + /* proper cleanup sequence - type PB */ - /* test 526 and 528 */ - /* proper cleanup sequence - type PB */ - - for(i = 0; i < NUM_HANDLES; i++) { - curl_multi_remove_handle(m, curl[i]); - curl_easy_cleanup(curl[i]); + for(i = 0; i < CURL_ARRAYSIZE(curl); i++) { + curl_multi_remove_handle(m, curl[i]); + curl_easy_cleanup(curl[i]); + } + curl_multi_cleanup(m); + curl_global_cleanup(); } - curl_multi_cleanup(m); - curl_global_cleanup(); + else if(testnum == 527) { + /* Upon non-failure test flow the easy's have already been cleanup'ed. In + case there is a failure we arrive here with easy's that have not been + cleanup'ed yet, in this case we have to cleanup them or otherwise these + will be leaked, let's use undocumented cleanup sequence - type UB */ -#elif defined(LIB527) + if(res != CURLE_OK) + for(i = 0; i < CURL_ARRAYSIZE(curl); i++) + curl_easy_cleanup(curl[i]); - /* test 527 */ + curl_multi_cleanup(m); + curl_global_cleanup(); - /* Upon non-failure test flow the easy's have already been cleanup'ed. In - case there is a failure we arrive here with easy's that have not been - cleanup'ed yet, in this case we have to cleanup them or otherwise these - will be leaked, let's use undocumented cleanup sequence - type UB */ + } + else if(testnum == 532) { + /* undocumented cleanup sequence - type UB */ - if(res != CURLE_OK) - for(i = 0; i < NUM_HANDLES; i++) + for(i = 0; i < CURL_ARRAYSIZE(curl); i++) curl_easy_cleanup(curl[i]); - - curl_multi_cleanup(m); - curl_global_cleanup(); - -#elif defined(LIB532) - - /* test 532 */ - /* undocumented cleanup sequence - type UB */ - - for(i = 0; i < NUM_HANDLES; i++) - curl_easy_cleanup(curl[i]); - curl_multi_cleanup(m); - curl_global_cleanup(); - -#endif + curl_multi_cleanup(m); + curl_global_cleanup(); + } return res; } diff --git a/vendor/curl/tests/libtest/lib530.c b/vendor/curl/tests/libtest/lib530.c index f577c82ad57..e6fe6ceff0b 100644 --- a/vendor/curl/tests/libtest/lib530.c +++ b/vendor/curl/tests/libtest/lib530.c @@ -28,41 +28,61 @@ * aborted correctly. */ -#include "test.h" +#include "first.h" -#include - -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 -struct Sockets { +static struct t530_ctx { + int socket_calls; + int max_socket_calls; + int timer_calls; + int max_timer_calls; + char buf[1024]; +} t530_ctx; + +static const char *t530_tag(void) +{ + curl_msnprintf(t530_ctx.buf, sizeof(t530_ctx.buf), + "[T530-%d-%d] [%d/%d]", + t530_ctx.max_socket_calls, t530_ctx.max_timer_calls, + t530_ctx.socket_calls, t530_ctx.timer_calls); + return t530_ctx.buf; +} + +static void t530_msg(const char *msg) +{ + curl_mfprintf(stderr, "%s %s\n", t530_tag(), msg); +} + + +struct t530_Sockets { curl_socket_t *sockets; int count; /* number of sockets actually stored in array */ int max_count; /* max number of sockets that fit in allocated array */ }; -struct ReadWriteSockets { - struct Sockets read, write; +struct t530_ReadWriteSockets { + struct t530_Sockets read, write; }; /** * Remove a file descriptor from a sockets array. */ -static void removeFd(struct Sockets *sockets, curl_socket_t fd, int mention) +static void t530_removeFd(struct t530_Sockets *sockets, curl_socket_t fd, + int mention) { int i; if(mention) - curl_mfprintf(stderr, "Remove socket fd %d\n", (int) fd); + curl_mfprintf(stderr, "%s remove socket fd %" FMT_SOCKET_T "\n", + t530_tag(), fd); for(i = 0; i < sockets->count; ++i) { if(sockets->sockets[i] == fd) { if(i < sockets->count - 1) memmove(&sockets->sockets[i], &sockets->sockets[i + 1], - sizeof(curl_socket_t) * (sockets->count - (i + 1))); + sizeof(curl_socket_t) * (sockets->count - (i + 1))); --sockets->count; } } @@ -72,14 +92,16 @@ static void removeFd(struct Sockets *sockets, curl_socket_t fd, int mention) * Add a file descriptor to a sockets array. * Return 0 on success, 1 on error. */ -static int addFd(struct Sockets *sockets, curl_socket_t fd, const char *what) +static int t530_addFd(struct t530_Sockets *sockets, curl_socket_t fd, + const char *what) { /** * To ensure we only have each file descriptor once, we remove it then add * it again. */ - curl_mfprintf(stderr, "Add socket fd %d for %s\n", (int) fd, what); - removeFd(sockets, fd, 0); + curl_mfprintf(stderr, "%s add socket fd %" FMT_SOCKET_T " for %s\n", + t530_tag(), fd, what); + t530_removeFd(sockets, fd, 0); /* * Allocate array storage when required. */ @@ -106,61 +128,56 @@ static int addFd(struct Sockets *sockets, curl_socket_t fd, const char *what) return 0; } -static int max_socket_calls; -static int socket_calls = 0; - /** * Callback invoked by curl to poll reading / writing of a socket. */ -static int curlSocketCallback(CURL *easy, curl_socket_t s, int action, - void *userp, void *socketp) +static int t530_curlSocketCallback(CURL *easy, curl_socket_t s, int action, + void *userp, void *socketp) { - struct ReadWriteSockets *sockets = userp; + struct t530_ReadWriteSockets *sockets = userp; (void)easy; /* unused */ (void)socketp; /* unused */ - curl_mfprintf(stderr, "CURLMOPT_SOCKETFUNCTION called: %u\n", - socket_calls++); - if(socket_calls == max_socket_calls) { - curl_mfprintf(stderr, "curlSocketCallback returns error\n"); + t530_ctx.socket_calls++; + t530_msg("-> CURLMOPT_SOCKETFUNCTION"); + if(t530_ctx.socket_calls == t530_ctx.max_socket_calls) { + t530_msg("<- CURLMOPT_SOCKETFUNCTION returns error"); return -1; } if(action == CURL_POLL_IN || action == CURL_POLL_INOUT) - if(addFd(&sockets->read, s, "read")) + if(t530_addFd(&sockets->read, s, "read")) return -1; /* bail out */ if(action == CURL_POLL_OUT || action == CURL_POLL_INOUT) - if(addFd(&sockets->write, s, "write")) + if(t530_addFd(&sockets->write, s, "write")) return -1; if(action == CURL_POLL_REMOVE) { - removeFd(&sockets->read, s, 1); - removeFd(&sockets->write, s, 0); + t530_removeFd(&sockets->read, s, 1); + t530_removeFd(&sockets->write, s, 0); } return 0; } -static int max_timer_calls; -static int timer_calls = 0; - /** * Callback invoked by curl to set a timeout. */ -static int curlTimerCallback(CURLM *multi, long timeout_ms, void *userp) +static int t530_curlTimerCallback(CURLM *multi, long timeout_ms, void *userp) { - struct timeval *timeout = userp; + struct curltime *timeout = userp; (void)multi; /* unused */ - curl_mfprintf(stderr, "CURLMOPT_TIMERFUNCTION called: %u\n", timer_calls++); - if(timer_calls == max_timer_calls) { - curl_mfprintf(stderr, "curlTimerCallback returns error\n"); + t530_ctx.timer_calls++; + t530_msg("-> CURLMOPT_TIMERFUNCTION"); + if(t530_ctx.timer_calls == t530_ctx.max_timer_calls) { + t530_msg("<- CURLMOPT_TIMERFUNCTION returns error"); return -1; } if(timeout_ms != -1) { - *timeout = tutil_tvnow(); + *timeout = curlx_now(); timeout->tv_usec += (int)timeout_ms * 1000; } else { @@ -172,7 +189,7 @@ static int curlTimerCallback(CURLM *multi, long timeout_ms, void *userp) /** * Check for curl completion. */ -static int checkForCompletion(CURLM *curl, int *success) +static int t530_checkForCompletion(CURLM *curl, int *success) { int result = 0; *success = 0; @@ -189,8 +206,8 @@ static int checkForCompletion(CURLM *curl, int *success) *success = 0; } else { - curl_mfprintf(stderr, "Got an unexpected message from curl: %i\n", - message->msg); + curl_mfprintf(stderr, "%s got an unexpected message from curl: %i\n", + t530_tag(), message->msg); result = 1; *success = 0; } @@ -198,33 +215,33 @@ static int checkForCompletion(CURLM *curl, int *success) return result; } -static int getMicroSecondTimeout(struct timeval *timeout) +static ssize_t t530_getMicroSecondTimeout(struct curltime *timeout) { - struct timeval now; + struct curltime now; ssize_t result; - now = tutil_tvnow(); + now = curlx_now(); result = (ssize_t)((timeout->tv_sec - now.tv_sec) * 1000000 + timeout->tv_usec - now.tv_usec); if(result < 0) result = 0; - return curlx_sztosi(result); + return result; } /** * Update a fd_set with all of the sockets in use. */ -static void updateFdSet(struct Sockets *sockets, fd_set* fdset, - curl_socket_t *maxFd) +static void t530_updateFdSet(struct t530_Sockets *sockets, fd_set* fdset, + curl_socket_t *maxFd) { int i; for(i = 0; i < sockets->count; ++i) { -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif FD_SET(sockets->sockets[i], fdset); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif if(*maxFd < sockets->sockets[i] + 1) { @@ -233,27 +250,27 @@ static void updateFdSet(struct Sockets *sockets, fd_set* fdset, } } -static int socket_action(CURLM *curl, curl_socket_t s, int evBitmask, - const char *info) +static CURLMcode socket_action(CURLM *curl, curl_socket_t s, int evBitmask, + const char *info) { int numhandles = 0; CURLMcode result = curl_multi_socket_action(curl, s, evBitmask, &numhandles); if(result != CURLM_OK) { - curl_mfprintf(stderr, "Curl error on %s (%i) %s\n", - info, result, curl_multi_strerror(result)); + curl_mfprintf(stderr, "%s Curl error on %s (%i) %s\n", + t530_tag(), info, result, curl_multi_strerror(result)); } - return (int)result; + return result; } /** * Invoke curl when a file descriptor is set. */ -static int checkFdSet(CURLM *curl, - struct Sockets *sockets, fd_set *fdset, - int evBitmask, const char *name) +static CURLMcode t530_checkFdSet(CURLM *curl, struct t530_Sockets *sockets, + fd_set *fdset, int evBitmask, + const char *name) { int i; - int result = 0; + CURLMcode result = CURLM_OK; for(i = 0; i < sockets->count; ++i) { if(FD_ISSET(sockets->sockets[i], fdset)) { result = socket_action(curl, sockets->sockets[i], evBitmask, name); @@ -264,22 +281,21 @@ static int checkFdSet(CURLM *curl, return result; } -static CURLcode testone(char *URL, int timercb, int socketcb) +static CURLcode testone(const char *URL, int timer_fail_at, int socket_fail_at) { CURLcode res = CURLE_OK; CURL *curl = NULL; CURLM *m = NULL; - struct ReadWriteSockets sockets = {{NULL, 0, 0}, {NULL, 0, 0}}; + struct t530_ReadWriteSockets sockets = {{NULL, 0, 0}, {NULL, 0, 0}}; int success = 0; - struct timeval timeout = {0}; + struct curltime timeout = {0}; timeout.tv_sec = (time_t)-1; /* set the limits */ - max_timer_calls = timercb; - max_socket_calls = socketcb; - timer_calls = 0; /* reset the globals */ - socket_calls = 0; + memset(&t530_ctx, 0, sizeof(t530_ctx)); + t530_ctx.max_timer_calls = timer_fail_at; + t530_ctx.max_socket_calls = socket_fail_at; - curl_mfprintf(stderr, "start test: %d %d\n", timercb, socketcb); + t530_msg("start"); start_test_timing(); res_global_init(CURL_GLOBAL_ALL); @@ -296,10 +312,10 @@ static CURLcode testone(char *URL, int timercb, int socketcb) multi_init(m); - multi_setopt(m, CURLMOPT_SOCKETFUNCTION, curlSocketCallback); + multi_setopt(m, CURLMOPT_SOCKETFUNCTION, t530_curlSocketCallback); multi_setopt(m, CURLMOPT_SOCKETDATA, &sockets); - multi_setopt(m, CURLMOPT_TIMERFUNCTION, curlTimerCallback); + multi_setopt(m, CURLMOPT_TIMERFUNCTION, t530_curlTimerCallback); multi_setopt(m, CURLMOPT_TIMERDATA, &timeout); multi_add_handle(m, curl); @@ -309,7 +325,7 @@ static CURLcode testone(char *URL, int timercb, int socketcb) goto test_cleanup; } - while(!checkForCompletion(m, &success)) { + while(!t530_checkForCompletion(m, &success)) { fd_set readSet, writeSet; curl_socket_t maxFd = 0; struct timeval tv = {0}; @@ -317,11 +333,11 @@ static CURLcode testone(char *URL, int timercb, int socketcb) FD_ZERO(&readSet); FD_ZERO(&writeSet); - updateFdSet(&sockets.read, &readSet, &maxFd); - updateFdSet(&sockets.write, &writeSet, &maxFd); + t530_updateFdSet(&sockets.read, &readSet, &maxFd); + t530_updateFdSet(&sockets.write, &writeSet, &maxFd); if(timeout.tv_sec != (time_t)-1) { - int usTimeout = getMicroSecondTimeout(&timeout); + int usTimeout = curlx_sztosi(t530_getMicroSecondTimeout(&timeout)); tv.tv_sec = usTimeout / 1000000; tv.tv_usec = usTimeout % 1000000; } @@ -334,16 +350,19 @@ static CURLcode testone(char *URL, int timercb, int socketcb) select_test((int)maxFd, &readSet, &writeSet, NULL, &tv); /* Check the sockets for reading / writing */ - if(checkFdSet(m, &sockets.read, &readSet, CURL_CSELECT_IN, "read")) { + if(t530_checkFdSet(m, &sockets.read, &readSet, CURL_CSELECT_IN, + "read")) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; } - if(checkFdSet(m, &sockets.write, &writeSet, CURL_CSELECT_OUT, "write")) { + if(t530_checkFdSet(m, &sockets.write, &writeSet, CURL_CSELECT_OUT, + "write")) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; } - if(timeout.tv_sec != (time_t)-1 && getMicroSecondTimeout(&timeout) == 0) { + if(timeout.tv_sec != (time_t)-1 && + t530_getMicroSecondTimeout(&timeout) == 0) { /* Curl's timer has elapsed. */ if(socket_action(m, CURL_SOCKET_TIMEOUT, 0, "timeout")) { res = TEST_ERR_BAD_TIMEOUT; @@ -355,14 +374,14 @@ static CURLcode testone(char *URL, int timercb, int socketcb) } if(!success) { - curl_mfprintf(stderr, "Error getting file.\n"); + t530_msg("Error getting file."); res = TEST_ERR_MAJOR_BAD; } test_cleanup: /* proper cleanup sequence */ - curl_mfprintf(stderr, "cleanup: %d %d\n", timercb, socketcb); + t530_msg("cleanup"); curl_multi_remove_handle(m, curl); curl_easy_cleanup(curl); curl_multi_cleanup(m); @@ -371,33 +390,35 @@ static CURLcode testone(char *URL, int timercb, int socketcb) /* free local memory */ free(sockets.read.sockets); free(sockets.write.sockets); + t530_msg("done"); + return res; } -CURLcode test(char *URL) +static CURLcode test_lib530(const char *URL) { CURLcode rc; /* rerun the same transfer multiple times and make it fail in different callback calls */ - rc = testone(URL, 0, 0); + rc = testone(URL, 0, 0); /* no callback fails */ if(rc) - curl_mfprintf(stderr, "test 0/0 failed: %d\n", rc); + curl_mfprintf(stderr, "%s FAILED: %d\n", t530_tag(), rc); - rc = testone(URL, 1, 0); + rc = testone(URL, 1, 0); /* fail 1st call to timer callback */ if(!rc) - curl_mfprintf(stderr, "test 1/0 failed: %d\n", rc); + curl_mfprintf(stderr, "%s FAILED: %d\n", t530_tag(), rc); - rc = testone(URL, 2, 0); + rc = testone(URL, 2, 0); /* fail 2nd call to timer callback */ if(!rc) - curl_mfprintf(stderr, "test 2/0 failed: %d\n", rc); + curl_mfprintf(stderr, "%s FAILED: %d\n", t530_tag(), rc); - rc = testone(URL, 0, 1); + rc = testone(URL, 0, 1); /* fail 1st call to socket callback */ if(!rc) - curl_mfprintf(stderr, "test 0/1 failed: %d\n", rc); + curl_mfprintf(stderr, "%s FAILED: %d\n", t530_tag(), rc); - rc = testone(URL, 0, 2); + rc = testone(URL, 0, 2); /* fail 2nd call to socket callback */ if(!rc) - curl_mfprintf(stderr, "test 0/2 failed: %d\n", rc); + curl_mfprintf(stderr, "%s FAILED: %d\n", t530_tag(), rc); return CURLE_OK; } diff --git a/vendor/curl/tests/libtest/lib533.c b/vendor/curl/tests/libtest/lib533.c index be121058966..adba324f669 100644 --- a/vendor/curl/tests/libtest/lib533.c +++ b/vendor/curl/tests/libtest/lib533.c @@ -23,17 +23,11 @@ ***************************************************************************/ /* used for test case 533, 534, 535 and 546 */ -#include "test.h" +#include "first.h" -#include - -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -CURLcode test(char *URL) +static CURLcode test_lib533(const char *URL) { CURLcode res = CURLE_OK; CURL *curl = NULL; diff --git a/vendor/curl/tests/libtest/lib536.c b/vendor/curl/tests/libtest/lib536.c index ce1df9c0dc5..c0107ed9cbd 100644 --- a/vendor/curl/tests/libtest/lib536.c +++ b/vendor/curl/tests/libtest/lib536.c @@ -21,28 +21,28 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -#define WITH_PROXY "http://usingproxy.com/" -#define WITHOUT_PROXY libtest_arg2 - static void proxystat(CURL *curl) { long wasproxy; if(!curl_easy_getinfo(curl, CURLINFO_USED_PROXY, &wasproxy)) { curl_mprintf("This %sthe proxy\n", wasproxy ? "used ": - "DID NOT use "); + "DID NOT use "); } } -CURLcode test(char *URL) +static CURLcode test_lib536(const char *URL) { CURLcode res = CURLE_OK; CURL *curl; struct curl_slist *host = NULL; + static const char *url_with_proxy = "http://usingproxy.com/"; + const char *url_without_proxy = libtest_arg2; + if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { curl_mfprintf(stderr, "curl_global_init() failed\n"); return TEST_ERR_MAJOR_BAD; @@ -61,14 +61,14 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_RESOLVE, host); test_setopt(curl, CURLOPT_PROXY, URL); - test_setopt(curl, CURLOPT_URL, WITH_PROXY); + test_setopt(curl, CURLOPT_URL, url_with_proxy); test_setopt(curl, CURLOPT_NOPROXY, "goingdirect.com"); test_setopt(curl, CURLOPT_VERBOSE, 1L); res = curl_easy_perform(curl); if(!res) { proxystat(curl); - test_setopt(curl, CURLOPT_URL, WITHOUT_PROXY); + test_setopt(curl, CURLOPT_URL, url_without_proxy); res = curl_easy_perform(curl); if(!res) proxystat(curl); diff --git a/vendor/curl/tests/libtest/lib537.c b/vendor/curl/tests/libtest/lib537.c index 1e4d3839aea..fa03c3b9833 100644 --- a/vendor/curl/tests/libtest/lib537.c +++ b/vendor/curl/tests/libtest/lib537.c @@ -21,24 +21,16 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#ifdef HAVE_SYS_RESOURCE_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#include - -#include "warnless.h" +#include "testutil.h" #include "memdebug.h" #if !defined(HAVE_POLL) && !defined(USE_WINSOCK) && !defined(FD_SETSIZE) #error "this test requires FD_SETSIZE" #endif -#define SAFETY_MARGIN (11) +#define T537_SAFETY_MARGIN (11) #if defined(_WIN32) || defined(MSDOS) #define DEV_NULL "NUL" @@ -48,31 +40,31 @@ #if defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) -static int *testfd = NULL; -static struct rlimit num_open; -static char msgbuff[256]; +static int *t537_testfd = NULL; +static struct rlimit t537_num_open; +static char t537_msgbuff[256]; -static void store_errmsg(const char *msg, int err) +static void t537_store_errmsg(const char *msg, int err) { if(!err) - curl_msnprintf(msgbuff, sizeof(msgbuff), "%s", msg); + curl_msnprintf(t537_msgbuff, sizeof(t537_msgbuff), "%s", msg); else - curl_msnprintf(msgbuff, sizeof(msgbuff), "%s, errno %d, %s", msg, - err, strerror(err)); + curl_msnprintf(t537_msgbuff, sizeof(t537_msgbuff), "%s, errno %d, %s", msg, + err, strerror(err)); } -static void close_file_descriptors(void) +static void t537_close_file_descriptors(void) { - for(num_open.rlim_cur = 0; - num_open.rlim_cur < num_open.rlim_max; - num_open.rlim_cur++) - if(testfd[num_open.rlim_cur] > 0) - close(testfd[num_open.rlim_cur]); - free(testfd); - testfd = NULL; + for(t537_num_open.rlim_cur = 0; + t537_num_open.rlim_cur < t537_num_open.rlim_max; + t537_num_open.rlim_cur++) + if(t537_testfd[t537_num_open.rlim_cur] > 0) + close(t537_testfd[t537_num_open.rlim_cur]); + free(t537_testfd); + t537_testfd = NULL; } -static int fopen_works(void) +static int t537_fopen_works(void) { FILE *fpa[3]; int i; @@ -84,8 +76,8 @@ static int fopen_works(void) for(i = 0; i < 3; i++) { fpa[i] = fopen(DEV_NULL, FOPEN_READTEXT); if(!fpa[i]) { - store_errmsg("fopen failed", errno); - curl_mfprintf(stderr, "%s\n", msgbuff); + t537_store_errmsg("fopen failed", errno); + curl_mfprintf(stderr, "%s\n", t537_msgbuff); ret = 0; break; } @@ -97,28 +89,7 @@ static int fopen_works(void) return ret; } -static void rlim2str(char *buf, size_t len, rlim_t val) -{ -#ifdef RLIM_INFINITY - if(val == RLIM_INFINITY) { - curl_msnprintf(buf, len, "INFINITY"); - return; - } -#endif -#ifdef HAVE_LONGLONG - if(sizeof(rlim_t) > sizeof(long)) - curl_msnprintf(buf, len, "%llu", (unsigned long long)val); - else -#endif - { - if(sizeof(rlim_t) < sizeof(long)) - curl_msnprintf(buf, len, "%u", (unsigned int)val); - else - curl_msnprintf(buf, len, "%lu", (unsigned long)val); - } -} - -static int test_rlimit(int keep_open) +static int t537_test_rlimit(int keep_open) { int *tmpfd; rlim_t nitems, i; @@ -130,17 +101,17 @@ static int test_rlimit(int keep_open) /* get initial open file limits */ if(getrlimit(RLIMIT_NOFILE, &rl) != 0) { - store_errmsg("getrlimit() failed", errno); - curl_mfprintf(stderr, "%s\n", msgbuff); + t537_store_errmsg("getrlimit() failed", errno); + curl_mfprintf(stderr, "%s\n", t537_msgbuff); return -1; } /* show initial open file limits */ - rlim2str(strbuff, sizeof(strbuff), rl.rlim_cur); + tutil_rlim2str(strbuff, sizeof(strbuff), rl.rlim_cur); curl_mfprintf(stderr, "initial soft limit: %s\n", strbuff); - rlim2str(strbuff, sizeof(strbuff), rl.rlim_max); + tutil_rlim2str(strbuff, sizeof(strbuff), rl.rlim_max); curl_mfprintf(stderr, "initial hard limit: %s\n", strbuff); /* If the OS allows a HUGE number of open files, we do not run. @@ -171,9 +142,9 @@ static int test_rlimit(int keep_open) rl.rlim_cur = OPEN_MAX; if(setrlimit(RLIMIT_NOFILE, &rl) != 0) { /* on failure don't abort just issue a warning */ - store_errmsg("setrlimit() failed", errno); - curl_mfprintf(stderr, "%s\n", msgbuff); - msgbuff[0] = '\0'; + t537_store_errmsg("setrlimit() failed", errno); + curl_mfprintf(stderr, "%s\n", t537_msgbuff); + t537_msgbuff[0] = '\0'; } } #endif @@ -182,25 +153,25 @@ static int test_rlimit(int keep_open) rl.rlim_cur = rl.rlim_max; if(setrlimit(RLIMIT_NOFILE, &rl) != 0) { /* on failure don't abort just issue a warning */ - store_errmsg("setrlimit() failed", errno); - curl_mfprintf(stderr, "%s\n", msgbuff); - msgbuff[0] = '\0'; + t537_store_errmsg("setrlimit() failed", errno); + curl_mfprintf(stderr, "%s\n", t537_msgbuff); + t537_msgbuff[0] = '\0'; } /* get current open file limits */ if(getrlimit(RLIMIT_NOFILE, &rl) != 0) { - store_errmsg("getrlimit() failed", errno); - curl_mfprintf(stderr, "%s\n", msgbuff); + t537_store_errmsg("getrlimit() failed", errno); + curl_mfprintf(stderr, "%s\n", t537_msgbuff); return -3; } /* show current open file limits */ - rlim2str(strbuff, sizeof(strbuff), rl.rlim_cur); + tutil_rlim2str(strbuff, sizeof(strbuff), rl.rlim_cur); curl_mfprintf(stderr, "current soft limit: %s\n", strbuff); - rlim2str(strbuff, sizeof(strbuff), rl.rlim_max); + tutil_rlim2str(strbuff, sizeof(strbuff), rl.rlim_max); curl_mfprintf(stderr, "current hard limit: %s\n", strbuff); } /* (rl.rlim_cur != rl.rlim_max) */ @@ -220,7 +191,7 @@ static int test_rlimit(int keep_open) * avoid a low memory condition once the file descriptors are * open. System conditions that could make the test fail should * be addressed in the precheck phase. This chunk of memory shall - * be always free()ed before exiting the test_rlimit() function so + * be always free()ed before exiting the t537_test_rlimit() function so * that it becomes available to the test. */ @@ -229,8 +200,8 @@ static int test_rlimit(int keep_open) if(nitems > 0x7fff) nitems = 0x40000; do { - num_open.rlim_max = sizeof(*memchunk) * nitems; - rlim2str(strbuff, sizeof(strbuff), num_open.rlim_max); + t537_num_open.rlim_max = sizeof(*memchunk) * nitems; + tutil_rlim2str(strbuff, sizeof(strbuff), t537_num_open.rlim_max); curl_mfprintf(stderr, "allocating memchunk %s byte array\n", strbuff); memchunk = malloc(sizeof(*memchunk) * (size_t)nitems); if(!memchunk) { @@ -239,8 +210,8 @@ static int test_rlimit(int keep_open) } } while(nitems && !memchunk); if(!memchunk) { - store_errmsg("memchunk, malloc() failed", errno); - curl_mfprintf(stderr, "%s\n", msgbuff); + t537_store_errmsg("memchunk, malloc() failed", errno); + curl_mfprintf(stderr, "%s\n", t537_msgbuff); return -4; } @@ -258,8 +229,8 @@ static int test_rlimit(int keep_open) #else if(rl.rlim_cur > 0) { #endif - /* soft limit minus SAFETY_MARGIN */ - num_open.rlim_max = rl.rlim_cur - SAFETY_MARGIN; + /* soft limit minus T537_SAFETY_MARGIN */ + t537_num_open.rlim_max = rl.rlim_cur - T537_SAFETY_MARGIN; } else { /* a huge number of file descriptors */ @@ -267,18 +238,18 @@ static int test_rlimit(int keep_open) nitems = i; if(nitems > 0x7fff) nitems = 0x40000; - num_open.rlim_max = nitems; + t537_num_open.rlim_max = nitems; } /* verify that we won't overflow size_t in malloc() */ - if((size_t)(num_open.rlim_max) > ((size_t)-1) / sizeof(*testfd)) { - rlim2str(strbuff1, sizeof(strbuff1), num_open.rlim_max); + if((size_t)(t537_num_open.rlim_max) > ((size_t)-1) / sizeof(*t537_testfd)) { + tutil_rlim2str(strbuff1, sizeof(strbuff1), t537_num_open.rlim_max); curl_msnprintf(strbuff, sizeof(strbuff), "unable to allocate an array for %s " "file descriptors, would overflow size_t", strbuff1); - store_errmsg(strbuff, 0); - curl_mfprintf(stderr, "%s\n", msgbuff); + t537_store_errmsg(strbuff, 0); + curl_mfprintf(stderr, "%s\n", t537_msgbuff); free(memchunk); return -5; } @@ -286,19 +257,20 @@ static int test_rlimit(int keep_open) /* allocate array for file descriptors */ do { - rlim2str(strbuff, sizeof(strbuff), num_open.rlim_max); + tutil_rlim2str(strbuff, sizeof(strbuff), t537_num_open.rlim_max); curl_mfprintf(stderr, "allocating array for %s file descriptors\n", strbuff); - testfd = malloc(sizeof(*testfd) * (size_t)(num_open.rlim_max)); - if(!testfd) { + t537_testfd = malloc(sizeof(*t537_testfd) * + (size_t)(t537_num_open.rlim_max)); + if(!t537_testfd) { curl_mfprintf(stderr, "testfd, malloc() failed\n"); - num_open.rlim_max /= 2; + t537_num_open.rlim_max /= 2; } - } while(num_open.rlim_max && !testfd); - if(!testfd) { - store_errmsg("testfd, malloc() failed", errno); - curl_mfprintf(stderr, "%s\n", msgbuff); + } while(t537_num_open.rlim_max && !t537_testfd); + if(!t537_testfd) { + t537_store_errmsg("testfd, malloc() failed", errno); + curl_mfprintf(stderr, "%s\n", t537_msgbuff); free(memchunk); return -6; } @@ -307,73 +279,74 @@ static int test_rlimit(int keep_open) curl_mfprintf(stderr, "initializing testfd array\n"); - for(num_open.rlim_cur = 0; - num_open.rlim_cur < num_open.rlim_max; - num_open.rlim_cur++) - testfd[num_open.rlim_cur] = -1; + for(t537_num_open.rlim_cur = 0; + t537_num_open.rlim_cur < t537_num_open.rlim_max; + t537_num_open.rlim_cur++) + t537_testfd[t537_num_open.rlim_cur] = -1; - rlim2str(strbuff, sizeof(strbuff), num_open.rlim_max); + tutil_rlim2str(strbuff, sizeof(strbuff), t537_num_open.rlim_max); curl_mfprintf(stderr, "trying to open %s file descriptors\n", strbuff); /* open a dummy descriptor */ - testfd[0] = open(DEV_NULL, O_RDONLY); - if(testfd[0] < 0) { + t537_testfd[0] = open(DEV_NULL, O_RDONLY); + if(t537_testfd[0] < 0) { curl_msnprintf(strbuff, sizeof(strbuff), "opening of %s failed", DEV_NULL); - store_errmsg(strbuff, errno); - curl_mfprintf(stderr, "%s\n", msgbuff); - free(testfd); - testfd = NULL; + t537_store_errmsg(strbuff, errno); + curl_mfprintf(stderr, "%s\n", t537_msgbuff); + free(t537_testfd); + t537_testfd = NULL; free(memchunk); return -7; } /* create a bunch of file descriptors */ - for(num_open.rlim_cur = 1; - num_open.rlim_cur < num_open.rlim_max; - num_open.rlim_cur++) { + for(t537_num_open.rlim_cur = 1; + t537_num_open.rlim_cur < t537_num_open.rlim_max; + t537_num_open.rlim_cur++) { - testfd[num_open.rlim_cur] = dup(testfd[0]); + t537_testfd[t537_num_open.rlim_cur] = dup(t537_testfd[0]); - if(testfd[num_open.rlim_cur] < 0) { + if(t537_testfd[t537_num_open.rlim_cur] < 0) { - testfd[num_open.rlim_cur] = -1; + t537_testfd[t537_num_open.rlim_cur] = -1; - rlim2str(strbuff1, sizeof(strbuff1), num_open.rlim_cur); + tutil_rlim2str(strbuff1, sizeof(strbuff1), t537_num_open.rlim_cur); curl_msnprintf(strbuff, sizeof(strbuff), "dup() attempt %s failed", strbuff1); curl_mfprintf(stderr, "%s\n", strbuff); - rlim2str(strbuff1, sizeof(strbuff1), num_open.rlim_cur); + tutil_rlim2str(strbuff1, sizeof(strbuff1), t537_num_open.rlim_cur); curl_msnprintf(strbuff, sizeof(strbuff), "fds system limit seems close to %s", strbuff1); curl_mfprintf(stderr, "%s\n", strbuff); - num_open.rlim_max = num_open.rlim_cur - SAFETY_MARGIN; + t537_num_open.rlim_max = t537_num_open.rlim_cur - T537_SAFETY_MARGIN; - num_open.rlim_cur -= num_open.rlim_max; - rlim2str(strbuff1, sizeof(strbuff1), num_open.rlim_cur); + t537_num_open.rlim_cur -= t537_num_open.rlim_max; + tutil_rlim2str(strbuff1, sizeof(strbuff1), t537_num_open.rlim_cur); curl_msnprintf(strbuff, sizeof(strbuff), "closing %s file descriptors", strbuff1); curl_mfprintf(stderr, "%s\n", strbuff); - for(num_open.rlim_cur = num_open.rlim_max; - testfd[num_open.rlim_cur] >= 0; - num_open.rlim_cur++) { - close(testfd[num_open.rlim_cur]); - testfd[num_open.rlim_cur] = -1; + for(t537_num_open.rlim_cur = t537_num_open.rlim_max; + t537_testfd[t537_num_open.rlim_cur] >= 0; + t537_num_open.rlim_cur++) { + close(t537_testfd[t537_num_open.rlim_cur]); + t537_testfd[t537_num_open.rlim_cur] = -1; } - rlim2str(strbuff, sizeof(strbuff), num_open.rlim_max); + tutil_rlim2str(strbuff, sizeof(strbuff), t537_num_open.rlim_max); curl_mfprintf(stderr, "shrinking array for %s file descriptors\n", strbuff); /* we don't care if we can't shrink it */ - tmpfd = realloc(testfd, sizeof(*testfd) * (size_t)(num_open.rlim_max)); + tmpfd = realloc(t537_testfd, + sizeof(*t537_testfd) * (size_t)(t537_num_open.rlim_max)); if(tmpfd) { - testfd = tmpfd; + t537_testfd = tmpfd; tmpfd = NULL; } @@ -381,7 +354,7 @@ static int test_rlimit(int keep_open) } } - rlim2str(strbuff, sizeof(strbuff), num_open.rlim_max); + tutil_rlim2str(strbuff, sizeof(strbuff), t537_num_open.rlim_max); curl_mfprintf(stderr, "%s file descriptors open\n", strbuff); #if !defined(HAVE_POLL) && !defined(USE_WINSOCK) @@ -397,28 +370,28 @@ static int test_rlimit(int keep_open) * with an indication that select limit would be exceeded. */ - num_open.rlim_cur = FD_SETSIZE - SAFETY_MARGIN; - if(num_open.rlim_max > num_open.rlim_cur) { + t537_num_open.rlim_cur = FD_SETSIZE - T537_SAFETY_MARGIN; + if(t537_num_open.rlim_max > t537_num_open.rlim_cur) { curl_msnprintf(strbuff, sizeof(strbuff), "select limit is FD_SETSIZE %d", - FD_SETSIZE); - store_errmsg(strbuff, 0); - curl_mfprintf(stderr, "%s\n", msgbuff); - close_file_descriptors(); + FD_SETSIZE); + t537_store_errmsg(strbuff, 0); + curl_mfprintf(stderr, "%s\n", t537_msgbuff); + t537_close_file_descriptors(); free(memchunk); return -8; } - num_open.rlim_cur = FD_SETSIZE - SAFETY_MARGIN; + t537_num_open.rlim_cur = FD_SETSIZE - T537_SAFETY_MARGIN; for(rl.rlim_cur = 0; - rl.rlim_cur < num_open.rlim_max; + rl.rlim_cur < t537_num_open.rlim_max; rl.rlim_cur++) { - if((testfd[rl.rlim_cur] > 0) && - ((unsigned int)testfd[rl.rlim_cur] > num_open.rlim_cur)) { + if((t537_testfd[rl.rlim_cur] > 0) && + ((unsigned int)t537_testfd[rl.rlim_cur] > t537_num_open.rlim_cur)) { curl_msnprintf(strbuff, sizeof(strbuff), "select limit is FD_SETSIZE %d", - FD_SETSIZE); - store_errmsg(strbuff, 0); - curl_mfprintf(stderr, "%s\n", msgbuff); - close_file_descriptors(); + FD_SETSIZE); + t537_store_errmsg(strbuff, 0); + curl_mfprintf(stderr, "%s\n", t537_msgbuff); + t537_close_file_descriptors(); free(memchunk); return -9; } @@ -435,15 +408,15 @@ static int test_rlimit(int keep_open) * if it is capable of fopen()ing some additional files. */ - if(!fopen_works()) { - rlim2str(strbuff1, sizeof(strbuff1), num_open.rlim_max); + if(!t537_fopen_works()) { + tutil_rlim2str(strbuff1, sizeof(strbuff1), t537_num_open.rlim_max); curl_msnprintf(strbuff, sizeof(strbuff), "fopen fails with %s fds open", strbuff1); - curl_mfprintf(stderr, "%s\n", msgbuff); + curl_mfprintf(stderr, "%s\n", t537_msgbuff); curl_msnprintf(strbuff, sizeof(strbuff), "fopen fails with lots of fds open"); - store_errmsg(strbuff, 0); - close_file_descriptors(); + t537_store_errmsg(strbuff, 0); + t537_close_file_descriptors(); free(memchunk); return -10; } @@ -456,27 +429,27 @@ static int test_rlimit(int keep_open) /* close file descriptors unless instructed to keep them */ if(!keep_open) { - close_file_descriptors(); + t537_close_file_descriptors(); } return 0; } -CURLcode test(char *URL) +static CURLcode test_lib537(const char *URL) { CURLcode res; CURL *curl; if(!strcmp(URL, "check")) { /* used by the test script to ask if we can run this test or not */ - if(test_rlimit(FALSE)) { - curl_mfprintf(stdout, "test_rlimit problem: %s\n", msgbuff); + if(t537_test_rlimit(FALSE)) { + curl_mfprintf(stdout, "test_rlimit problem: %s\n", t537_msgbuff); return TEST_ERR_FAILURE; } return CURLE_OK; /* sure, run this! */ } - if(test_rlimit(TRUE)) { + if(t537_test_rlimit(TRUE)) { /* failure */ return TEST_ERR_MAJOR_BAD; } @@ -486,14 +459,14 @@ CURLcode test(char *URL) if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { curl_mfprintf(stderr, "curl_global_init() failed\n"); - close_file_descriptors(); + t537_close_file_descriptors(); return TEST_ERR_MAJOR_BAD; } curl = curl_easy_init(); if(!curl) { curl_mfprintf(stderr, "curl_easy_init() failed\n"); - close_file_descriptors(); + t537_close_file_descriptors(); curl_global_cleanup(); return TEST_ERR_MAJOR_BAD; } @@ -505,20 +478,20 @@ CURLcode test(char *URL) test_cleanup: - close_file_descriptors(); + t537_close_file_descriptors(); curl_easy_cleanup(curl); curl_global_cleanup(); return res; } -#else /* defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) */ +#else /* HAVE_GETRLIMIT && HAVE_SETRLIMIT */ -CURLcode test(char *URL) +static CURLcode test_lib537(const char *URL) { (void)URL; curl_mprintf("system lacks necessary system function(s)"); return TEST_ERR_MAJOR_BAD; /* skip test */ } -#endif /* defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) */ +#endif /* HAVE_GETRLIMIT && HAVE_SETRLIMIT */ diff --git a/vendor/curl/tests/libtest/lib539.c b/vendor/curl/tests/libtest/lib539.c index ace839d03ca..e4e26c204a1 100644 --- a/vendor/curl/tests/libtest/lib539.c +++ b/vendor/curl/tests/libtest/lib539.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib539(const char *URL) { CURLcode res; CURL *curl; @@ -49,7 +49,7 @@ CURLcode test(char *URL) */ test_setopt(curl, CURLOPT_URL, URL); test_setopt(curl, CURLOPT_VERBOSE, 1L); - test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_SINGLECWD); + test_setopt(curl, CURLOPT_FTP_FILEMETHOD, CURLFTPMETHOD_SINGLECWD); res = curl_easy_perform(curl); if(res == CURLE_OK) { @@ -70,7 +70,7 @@ CURLcode test(char *URL) } test_setopt(curl, CURLOPT_URL, libtest_arg2); - test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_NOCWD); + test_setopt(curl, CURLOPT_FTP_FILEMETHOD, CURLFTPMETHOD_NOCWD); test_setopt(curl, CURLOPT_QUOTE, slist); res = curl_easy_perform(curl); diff --git a/vendor/curl/tests/libtest/lib540.c b/vendor/curl/tests/libtest/lib540.c index 42020849874..f544dec48d3 100644 --- a/vendor/curl/tests/libtest/lib540.c +++ b/vendor/curl/tests/libtest/lib540.c @@ -30,29 +30,19 @@ * argv4 = host name to use for the custom Host: header */ -#include "test.h" +#include "first.h" -#include - -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -#define PROXY libtest_arg2 -#define PROXYUSERPWD libtest_arg3 -#define HOST test_argv[4] - -#define NUM_HANDLES 2 - -static CURL *testeh[NUM_HANDLES]; +static CURL *testeh[2]; static CURLcode init(int num, CURLM *cm, const char *url, const char *userpwd, struct curl_slist *headers) { CURLcode res = CURLE_OK; + const char *proxy = libtest_arg2; + res_easy_init(testeh[num]); if(res) goto init_failed; @@ -61,7 +51,7 @@ static CURLcode init(int num, CURLM *cm, const char *url, const char *userpwd, if(res) goto init_failed; - res_easy_setopt(testeh[num], CURLOPT_PROXY, PROXY); + res_easy_setopt(testeh[num], CURLOPT_PROXY, proxy); if(res) goto init_failed; @@ -69,7 +59,7 @@ static CURLcode init(int num, CURLM *cm, const char *url, const char *userpwd, if(res) goto init_failed; - res_easy_setopt(testeh[num], CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY); + res_easy_setopt(testeh[num], CURLOPT_PROXYAUTH, CURLAUTH_ANY); if(res) goto init_failed; @@ -167,13 +157,13 @@ static CURLcode loop(int num, CURLM *cm, const char *url, const char *userpwd, if(!msg) break; if(msg->msg == CURLMSG_DONE) { - int i; + size_t i; CURL *e = msg->easy_handle; - curl_mfprintf(stderr, "R: %d - %s\n", (int)msg->data.result, - curl_easy_strerror(msg->data.result)); + curl_mfprintf(stderr, "R: %d - %s\n", msg->data.result, + curl_easy_strerror(msg->data.result)); curl_multi_remove_handle(cm, e); curl_easy_cleanup(e); - for(i = 0; i < NUM_HANDLES; i++) { + for(i = 0; i < CURL_ARRAYSIZE(testeh); i++) { if(testeh[i] == e) { testeh[i] = NULL; break; @@ -181,7 +171,7 @@ static CURLcode loop(int num, CURLM *cm, const char *url, const char *userpwd, } } else - curl_mfprintf(stderr, "E: CURLMsg (%d)\n", (int)msg->msg); + curl_mfprintf(stderr, "E: CURLMsg (%d)\n", msg->msg); } res_test_timedout(); @@ -192,15 +182,18 @@ static CURLcode loop(int num, CURLM *cm, const char *url, const char *userpwd, return CURLE_OK; } -CURLcode test(char *URL) +static CURLcode test_lib540(const char *URL) { CURLM *cm = NULL; struct curl_slist *headers = NULL; char buffer[246]; /* naively fixed-size */ CURLcode res = CURLE_OK; - int i; + size_t i; + + const char *proxyuserpws = libtest_arg3; + const char *host; - for(i = 0; i < NUM_HANDLES; i++) + for(i = 0; i < CURL_ARRAYSIZE(testeh); i++) testeh[i] = NULL; start_test_timing(); @@ -208,7 +201,8 @@ CURLcode test(char *URL) if(test_argc < 4) return TEST_ERR_MAJOR_BAD; - curl_msnprintf(buffer, sizeof(buffer), "Host: %s", HOST); + host = test_argv[4]; + curl_msnprintf(buffer, sizeof(buffer), "Host: %s", host); /* now add a custom Host: header */ headers = curl_slist_append(headers, buffer); @@ -230,19 +224,19 @@ CURLcode test(char *URL) return res; } - res = loop(0, cm, URL, PROXYUSERPWD, headers); + res = loop(0, cm, URL, proxyuserpws, headers); if(res) goto test_cleanup; curl_mfprintf(stderr, "lib540: now we do the request again\n"); - res = loop(1, cm, URL, PROXYUSERPWD, headers); + res = loop(1, cm, URL, proxyuserpws, headers); test_cleanup: /* proper cleanup sequence - type PB */ - for(i = 0; i < NUM_HANDLES; i++) { + for(i = 0; i < CURL_ARRAYSIZE(testeh); i++) { curl_multi_remove_handle(cm, testeh[i]); curl_easy_cleanup(testeh[i]); } diff --git a/vendor/curl/tests/libtest/lib541.c b/vendor/curl/tests/libtest/lib541.c index 1215206634c..9868474d01b 100644 --- a/vendor/curl/tests/libtest/lib541.c +++ b/vendor/curl/tests/libtest/lib541.c @@ -21,11 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" - -#ifdef HAVE_FCNTL_H -#include -#endif +#include "first.h" #include "memdebug.h" @@ -33,7 +29,7 @@ * Two FTP uploads, the second with no content sent. */ -CURLcode test(char *URL) +static CURLcode test_lib541(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; @@ -49,7 +45,7 @@ CURLcode test(char *URL) hd_src = fopen(libtest_arg2, "rb"); if(!hd_src) { curl_mfprintf(stderr, "fopen failed with error (%d) %s\n", - errno, strerror(errno)); + errno, strerror(errno)); curl_mfprintf(stderr, "Error opening file '%s'\n", libtest_arg2); return TEST_ERR_MAJOR_BAD; /* if this happens things are major weird */ } @@ -63,7 +59,7 @@ CURLcode test(char *URL) if(hd == -1) { /* can't open file, bail out */ curl_mfprintf(stderr, "fstat() failed with error (%d) %s\n", - errno, strerror(errno)); + errno, strerror(errno)); curl_mfprintf(stderr, "Error opening file '%s'\n", libtest_arg2); fclose(hd_src); return TEST_ERR_MAJOR_BAD; diff --git a/vendor/curl/tests/libtest/lib542.c b/vendor/curl/tests/libtest/lib542.c index f48c26995ee..e6e73131fd6 100644 --- a/vendor/curl/tests/libtest/lib542.c +++ b/vendor/curl/tests/libtest/lib542.c @@ -21,11 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" - -#ifdef HAVE_FCNTL_H -#include -#endif +#include "first.h" #include "memdebug.h" @@ -33,7 +29,7 @@ * FTP get with NOBODY but no HEADER */ -CURLcode test(char *URL) +static CURLcode test_lib542(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; diff --git a/vendor/curl/tests/libtest/lib543.c b/vendor/curl/tests/libtest/lib543.c index 8f8d4fd32a6..d3653dbccd2 100644 --- a/vendor/curl/tests/libtest/lib543.c +++ b/vendor/curl/tests/libtest/lib543.c @@ -23,11 +23,11 @@ ***************************************************************************/ /* Based on Alex Fishman's bug report on September 30, 2007 */ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib543(const char *URL) { static const unsigned char a[] = { 0x9c, 0x26, 0x4b, 0x3d, 0x49, 0x4, 0xa1, 0x1, diff --git a/vendor/curl/tests/libtest/lib544.c b/vendor/curl/tests/libtest/lib544.c index 9b6874ca372..c49a8e54b8f 100644 --- a/vendor/curl/tests/libtest/lib544.c +++ b/vendor/curl/tests/libtest/lib544.c @@ -21,20 +21,24 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -static char teststring[] = -{ 'T', 'h', 'i', 's', '\0', ' ', 'i', 's', ' ', 't', 'e', 's', 't', ' ', +static CURLcode test_lib544(const char *URL) +{ + CURL *curl; + CURLcode res = CURLE_OK; + + static const char teststring_init[] = { + 'T', 'h', 'i', 's', '\0', ' ', 'i', 's', ' ', 't', 'e', 's', 't', ' ', 'b', 'i', 'n', 'a', 'r', 'y', ' ', 'd', 'a', 't', 'a', ' ', 'w', 'i', 't', 'h', ' ', 'a', 'n', ' ', 'e', 'm', 'b', 'e', 'd', 'd', 'e', 'd', ' ', 'N', 'U', 'L'}; -CURLcode test(char *URL) -{ - CURL *curl; - CURLcode res = CURLE_OK; + char teststring[sizeof(teststring_init)]; + + memcpy(teststring, teststring_init, sizeof(teststring_init)); if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { curl_mfprintf(stderr, "curl_global_init() failed\n"); @@ -51,9 +55,8 @@ CURLcode test(char *URL) /* First set the URL that is about to receive our POST. */ test_setopt(curl, CURLOPT_URL, URL); -#ifdef LIB545 - test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) sizeof(teststring)); -#endif + if(testnum == 545) + test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)sizeof(teststring)); test_setopt(curl, CURLOPT_COPYPOSTFIELDS, teststring); diff --git a/vendor/curl/tests/libtest/lib547.c b/vendor/curl/tests/libtest/lib547.c index ce64ae41da8..e3597d6d3e9 100644 --- a/vendor/curl/tests/libtest/lib547.c +++ b/vendor/curl/tests/libtest/lib547.c @@ -26,17 +26,14 @@ * argv3 = proxyuser:password */ -#include "test.h" +#include "first.h" #include "memdebug.h" -#define UPLOADTHIS "this is the blurb we want to upload\n" +static const char t547_uploadthis[] = "this is the blurb we want to upload\n"; +#define T547_DATALEN (sizeof(t547_uploadthis)-1) -#ifndef LIB548 -static size_t readcallback(char *ptr, - size_t size, - size_t nmemb, - void *clientp) +static size_t t547_read_cb(char *ptr, size_t size, size_t nmemb, void *clientp) { int *counter = (int *)clientp; @@ -47,17 +44,16 @@ static size_t readcallback(char *ptr, } (*counter)++; /* bump */ - if(size * nmemb >= strlen(UPLOADTHIS)) { + if(size * nmemb >= T547_DATALEN) { curl_mfprintf(stderr, "READ!\n"); - strcpy(ptr, UPLOADTHIS); - return strlen(UPLOADTHIS); + strcpy(ptr, t547_uploadthis); + return T547_DATALEN; } curl_mfprintf(stderr, "READ NOT FINE!\n"); return 0; } -static curlioerr ioctlcallback(CURL *handle, - int cmd, - void *clientp) + +static curlioerr t547_ioctl_callback(CURL *handle, int cmd, void *clientp) { int *counter = (int *)clientp; (void)handle; /* unused */ @@ -68,17 +64,11 @@ static curlioerr ioctlcallback(CURL *handle, return CURLIOE_OK; } - - -#endif - -CURLcode test(char *URL) +static CURLcode test_lib547(const char *URL) { CURLcode res; CURL *curl; -#ifndef LIB548 int counter = 0; -#endif if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { curl_mfprintf(stderr, "curl_global_init() failed\n"); @@ -95,25 +85,26 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_URL, URL); test_setopt(curl, CURLOPT_VERBOSE, 1L); test_setopt(curl, CURLOPT_HEADER, 1L); -#ifdef LIB548 - /* set the data to POST with a mere pointer to a null-terminated string */ - test_setopt(curl, CURLOPT_POSTFIELDS, UPLOADTHIS); -#else - /* 547 style, which means reading the POST data from a callback */ - test_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctlcallback); - test_setopt(curl, CURLOPT_IOCTLDATA, &counter); - - test_setopt(curl, CURLOPT_READFUNCTION, readcallback); - test_setopt(curl, CURLOPT_READDATA, &counter); - /* We CANNOT do the POST fine without setting the size (or choose - chunked)! */ - test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(UPLOADTHIS)); -#endif + if(testnum == 548) { + /* set the data to POST with a mere pointer to a null-terminated string */ + test_setopt(curl, CURLOPT_POSTFIELDS, t547_uploadthis); + } + else { + /* 547 style, which means reading the POST data from a callback */ + test_setopt(curl, CURLOPT_IOCTLFUNCTION, t547_ioctl_callback); + test_setopt(curl, CURLOPT_IOCTLDATA, &counter); + + test_setopt(curl, CURLOPT_READFUNCTION, t547_read_cb); + test_setopt(curl, CURLOPT_READDATA, &counter); + /* We CANNOT do the POST fine without setting the size (or choose + chunked)! */ + test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)T547_DATALEN); + } test_setopt(curl, CURLOPT_POST, 1L); test_setopt(curl, CURLOPT_PROXY, libtest_arg2); test_setopt(curl, CURLOPT_PROXYUSERPWD, libtest_arg3); test_setopt(curl, CURLOPT_PROXYAUTH, - (long) (CURLAUTH_NTLM | CURLAUTH_DIGEST | CURLAUTH_BASIC) ); + CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_NTLM); res = curl_easy_perform(curl); diff --git a/vendor/curl/tests/libtest/lib549.c b/vendor/curl/tests/libtest/lib549.c index eb5f4e313d4..4eaacf5868a 100644 --- a/vendor/curl/tests/libtest/lib549.c +++ b/vendor/curl/tests/libtest/lib549.c @@ -26,11 +26,11 @@ * argv3 = non-zero means ASCII transfer */ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib549(const char *URL) { CURLcode res; CURL *curl; diff --git a/vendor/curl/tests/libtest/lib552.c b/vendor/curl/tests/libtest/lib552.c index f4fde2ff831..198ba6aa886 100644 --- a/vendor/curl/tests/libtest/lib552.c +++ b/vendor/curl/tests/libtest/lib552.c @@ -25,110 +25,16 @@ * argv2 = proxy with embedded user+password */ -#include "test.h" +#include "first.h" -#include "warnless.h" +#include "testtrace.h" #include "memdebug.h" -struct testdata { - char trace_ascii; /* 1 or 0 */ -}; - -static -void dump(const char *text, - FILE *stream, unsigned char *ptr, size_t size, - char nohex) -{ - size_t i; - size_t c; - - unsigned int width = 0x10; - - if(nohex) - /* without the hex output, we can fit more on screen */ - width = 0x40; - - curl_mfprintf(stream, "%s, %zu bytes (0x%zx)\n", text, size, size); - - for(i = 0; i < size; i += width) { - - curl_mfprintf(stream, "%04zx: ", i); - - if(!nohex) { - /* hex not disabled, show it */ - for(c = 0; c < width; c++) - if(i + c < size) - curl_mfprintf(stream, "%02x ", ptr[i + c]); - else - fputs(" ", stream); - } - - for(c = 0; (c < width) && (i + c < size); c++) { - /* check for 0D0A; if found, skip past and start a new line of output */ - if(nohex && (i + c + 1 < size) && ptr[i + c] == 0x0D && - ptr[i + c + 1] == 0x0A) { - i += (c + 2 - width); - break; - } - curl_mfprintf(stream, "%c", - (ptr[i + c] >= 0x20) && (ptr[i + c] < 0x80) ? ptr[i + c] : '.'); - /* check again for 0D0A, to avoid an extra \n if it's at width */ - if(nohex && (i + c + 2 < size) && ptr[i + c + 1] == 0x0D && - ptr[i + c + 2] == 0x0A) { - i += (c + 3 - width); - break; - } - } - fputc('\n', stream); /* newline */ - } - fflush(stream); -} - -static -int my_trace(CURL *handle, curl_infotype type, - char *data, size_t size, - void *userp) -{ - struct testdata *config = (struct testdata *)userp; - const char *text; - (void)handle; /* prevent compiler warning */ - - switch(type) { - case CURLINFO_TEXT: - curl_mfprintf(stderr, "== Info: %s", (char *)data); - return 0; - case CURLINFO_HEADER_OUT: - text = "=> Send header"; - break; - case CURLINFO_DATA_OUT: - text = "=> Send data"; - break; - case CURLINFO_SSL_DATA_OUT: - text = "=> Send SSL data"; - break; - case CURLINFO_HEADER_IN: - text = "<= Recv header"; - break; - case CURLINFO_DATA_IN: - text = "<= Recv data"; - break; - case CURLINFO_SSL_DATA_IN: - text = "<= Recv SSL data"; - break; - default: /* in case a new one is introduced to shock us */ - return 0; - } - - dump(text, stderr, (unsigned char *)data, size, config->trace_ascii); - return 0; -} - - static size_t current_offset = 0; static char databuf[70000]; /* MUST be more than 64k OR MAX_INITIAL_POST_SIZE */ -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *stream) +static size_t t552_read_cb(char *ptr, size_t size, size_t nmemb, void *stream) { size_t amount = nmemb * size; /* Total bytes curl wants */ size_t available = sizeof(databuf) - current_offset; /* What we have to @@ -140,17 +46,14 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *stream) return given; } - -static size_t write_callback(char *ptr, size_t size, size_t nmemb, - void *stream) +static size_t t552_write_cb(char *ptr, size_t size, size_t nmemb, void *stream) { - int amount = curlx_uztosi(size * nmemb); - curl_mprintf("%.*s", amount, (char *)ptr); + size_t amount = size * nmemb; + curl_mprintf("%.*s", (int)amount, ptr); (void)stream; - return size * nmemb; + return amount; } - static curlioerr ioctl_callback(CURL *handle, int cmd, void *clientp) { (void)clientp; @@ -164,23 +67,21 @@ static curlioerr ioctl_callback(CURL *handle, int cmd, void *clientp) return CURLIOE_UNKNOWNCMD; } - - -CURLcode test(char *URL) +static CURLcode test_lib552(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; - struct testdata config; size_t i; static const char fill[] = "test data"; - config.trace_ascii = 1; /* enable ASCII tracing */ + debug_config.nohex = TRUE; + debug_config.tracetime = FALSE; global_init(CURL_GLOBAL_ALL); easy_init(curl); - test_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace); - test_setopt(curl, CURLOPT_DEBUGDATA, &config); + test_setopt(curl, CURLOPT_DEBUGFUNCTION, libtest_debug_cb); + test_setopt(curl, CURLOPT_DEBUGDATA, &debug_config); /* the DEBUGFUNCTION has no effect until we enable VERBOSE */ test_setopt(curl, CURLOPT_VERBOSE, 1L); @@ -192,11 +93,11 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_POST, 1L); /* Setup read callback */ - test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) sizeof(databuf)); - test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)sizeof(databuf)); + test_setopt(curl, CURLOPT_READFUNCTION, t552_read_cb); /* Write callback */ - test_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + test_setopt(curl, CURLOPT_WRITEFUNCTION, t552_write_cb); /* Ioctl function */ test_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_callback); @@ -207,7 +108,7 @@ CURLcode test(char *URL) /* Accept any auth. But for this bug configure proxy with DIGEST, basic might work too, not NTLM */ - test_setopt(curl, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY); + test_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY); res = curl_easy_perform(curl); diff --git a/vendor/curl/tests/libtest/lib553.c b/vendor/curl/tests/libtest/lib553.c index d6d7f7cdbba..0d44573131e 100644 --- a/vendor/curl/tests/libtest/lib553.c +++ b/vendor/curl/tests/libtest/lib553.c @@ -26,7 +26,7 @@ * bug report #1871269, fixed on Jan 14 2008 before the 7.18.0 release. */ -#include "test.h" +#include "first.h" #include "memdebug.h" @@ -55,10 +55,10 @@ static size_t myreadfunc(char *ptr, size_t size, size_t nmemb, void *stream) #define NUM_HEADERS 8 #define SIZE_HEADERS 5000 -static char testbuf[SIZE_HEADERS + 100]; - -CURLcode test(char *URL) +static CURLcode test_lib553(const char *URL) { + static char testbuf[SIZE_HEADERS + 100]; + CURL *curl; CURLcode res = CURLE_FAILED_INIT; int i; diff --git a/vendor/curl/tests/libtest/lib554.c b/vendor/curl/tests/libtest/lib554.c index 94e6ad79366..23cb5a7046a 100644 --- a/vendor/curl/tests/libtest/lib554.c +++ b/vendor/curl/tests/libtest/lib554.c @@ -21,54 +21,54 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -static char testdata[]= - "this is what we post to the silly web server\n"; - -struct WriteThis { - char *readptr; +struct t554_WriteThis { + const char *readptr; size_t sizeleft; }; -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) +static size_t t554_read_cb(char *ptr, size_t size, size_t nmemb, void *userp) { -#ifdef LIB587 - (void)ptr; - (void)size; - (void)nmemb; - (void)userp; - return CURL_READFUNC_ABORT; -#else - - struct WriteThis *pooh = (struct WriteThis *)userp; + struct t554_WriteThis *pooh = (struct t554_WriteThis *)userp; if(size*nmemb < 1) return 0; if(pooh->sizeleft) { - *ptr = pooh->readptr[0]; /* copy one single byte */ - pooh->readptr++; /* advance pointer */ - pooh->sizeleft--; /* less data left */ - return 1; /* we return 1 byte at a time! */ + *ptr = pooh->readptr[0]; /* copy one single byte */ + pooh->readptr++; /* advance pointer */ + pooh->sizeleft--; /* less data left */ + return 1; /* we return 1 byte at a time! */ } - return 0; /* no more data left to deliver */ -#endif + return 0; /* no more data left to deliver */ } -static CURLcode test_once(char *URL, bool oldstyle) +static size_t t587_read_cb(char *ptr, size_t size, size_t nmemb, void *userp) { + (void)ptr; + (void)size; + (void)nmemb; + (void)userp; + return CURL_READFUNC_ABORT; +} + +static CURLcode t554_test_once(const char *URL, bool oldstyle) +{ + static const char testdata[] = + "this is what we post to the silly web server\n"; + CURL *curl; CURLcode res = CURLE_OK; CURLFORMcode formrc; struct curl_httppost *formpost = NULL; struct curl_httppost *lastptr = NULL; - struct WriteThis pooh; - struct WriteThis pooh2; + struct t554_WriteThis pooh; + struct t554_WriteThis pooh2; pooh.readptr = testdata; pooh.sizeleft = strlen(testdata); @@ -95,7 +95,7 @@ static CURLcode test_once(char *URL, bool oldstyle) } if(formrc) - curl_mprintf("curl_formadd(1) = %d\n", (int)formrc); + curl_mprintf("curl_formadd(1) = %d\n", formrc); /* Now add the same data with another name and make it not look like a file upload but still using the callback */ @@ -112,7 +112,7 @@ static CURLcode test_once(char *URL, bool oldstyle) CURLFORM_END); if(formrc) - curl_mprintf("curl_formadd(2) = %d\n", (int)formrc); + curl_mprintf("curl_formadd(2) = %d\n", formrc); /* Fill in the filename field */ formrc = curl_formadd(&formpost, @@ -121,7 +121,7 @@ static CURLcode test_once(char *URL, bool oldstyle) CURLFORM_COPYCONTENTS, "postit2.c", CURLFORM_END); if(formrc) - curl_mprintf("curl_formadd(3) = %d\n", (int)formrc); + curl_mprintf("curl_formadd(3) = %d\n", formrc); /* Fill in a submit field too */ formrc = curl_formadd(&formpost, @@ -132,17 +132,17 @@ static CURLcode test_once(char *URL, bool oldstyle) CURLFORM_END); if(formrc) - curl_mprintf("curl_formadd(4) = %d\n", (int)formrc); + curl_mprintf("curl_formadd(4) = %d\n", formrc); formrc = curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "somename", CURLFORM_BUFFER, "somefile.txt", CURLFORM_BUFFERPTR, "blah blah", - CURLFORM_BUFFERLENGTH, (long)9, + CURLFORM_BUFFERLENGTH, 9L, CURLFORM_END); if(formrc) - curl_mprintf("curl_formadd(5) = %d\n", (int)formrc); + curl_mprintf("curl_formadd(5) = %d\n", formrc); curl = curl_easy_init(); if(!curl) { @@ -162,7 +162,12 @@ static CURLcode test_once(char *URL, bool oldstyle) test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)pooh.sizeleft); /* we want to use our own read function */ - test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + if(testnum == 587) { + test_setopt(curl, CURLOPT_READFUNCTION, t587_read_cb); + } + else { + test_setopt(curl, CURLOPT_READFUNCTION, t554_read_cb); + } /* send a multi-part formpost */ test_setopt(curl, CURLOPT_HTTPPOST, formpost); @@ -187,7 +192,7 @@ static CURLcode test_once(char *URL, bool oldstyle) return res; } -CURLcode test(char *URL) +static CURLcode test_lib554(const char *URL) { CURLcode res; @@ -196,9 +201,9 @@ CURLcode test(char *URL) return TEST_ERR_MAJOR_BAD; } - res = test_once(URL, TRUE); /* old */ + res = t554_test_once(URL, TRUE); /* old */ if(!res) - res = test_once(URL, FALSE); /* new */ + res = t554_test_once(URL, FALSE); /* new */ curl_global_cleanup(); diff --git a/vendor/curl/tests/libtest/lib555.c b/vendor/curl/tests/libtest/lib555.c index a63fc217848..30438bafa9d 100644 --- a/vendor/curl/tests/libtest/lib555.c +++ b/vendor/curl/tests/libtest/lib555.c @@ -30,20 +30,14 @@ * argv3 = proxyuser:password */ -#include "test.h" -#include "testutil.h" -#include "warnless.h" -#include "memdebug.h" +#include "first.h" -#define TEST_HANG_TIMEOUT 60 * 1000 +#include "memdebug.h" -static const char uploadthis[] = - "this is the blurb we want to upload\n"; +static const char t555_uploadthis[] = "this is the blurb we want to upload\n"; +#define T555_DATALEN (sizeof(t555_uploadthis)-1) -static size_t readcallback(char *ptr, - size_t size, - size_t nmemb, - void *clientp) +static size_t t555_read_cb(char *ptr, size_t size, size_t nmemb, void *clientp) { int *counter = (int *)clientp; @@ -54,17 +48,16 @@ static size_t readcallback(char *ptr, } (*counter)++; /* bump */ - if(size * nmemb >= strlen(uploadthis)) { + if(size * nmemb >= T555_DATALEN) { curl_mfprintf(stderr, "READ!\n"); - strcpy(ptr, uploadthis); - return strlen(uploadthis); + strcpy(ptr, t555_uploadthis); + return T555_DATALEN; } curl_mfprintf(stderr, "READ NOT FINE!\n"); return 0; } -static curlioerr ioctlcallback(CURL *handle, - int cmd, - void *clientp) + +static curlioerr t555_ioctl_callback(CURL *handle, int cmd, void *clientp) { int *counter = (int *)clientp; (void)handle; /* unused */ @@ -75,8 +68,7 @@ static curlioerr ioctlcallback(CURL *handle, return CURLIOE_OK; } - -CURLcode test(char *URL) +static CURLcode test_lib555(const char *URL) { CURLcode res = CURLE_OK; CURL *curl = NULL; @@ -95,20 +87,20 @@ CURLcode test(char *URL) easy_setopt(curl, CURLOPT_HEADER, 1L); /* read the POST data from a callback */ - easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctlcallback); + easy_setopt(curl, CURLOPT_IOCTLFUNCTION, t555_ioctl_callback); easy_setopt(curl, CURLOPT_IOCTLDATA, &counter); - easy_setopt(curl, CURLOPT_READFUNCTION, readcallback); + easy_setopt(curl, CURLOPT_READFUNCTION, t555_read_cb); easy_setopt(curl, CURLOPT_READDATA, &counter); /* We CANNOT do the POST fine without setting the size (or choose chunked)! */ - easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(uploadthis)); + easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)T555_DATALEN); easy_setopt(curl, CURLOPT_POST, 1L); easy_setopt(curl, CURLOPT_PROXY, libtest_arg2); easy_setopt(curl, CURLOPT_PROXYUSERPWD, libtest_arg3); easy_setopt(curl, CURLOPT_PROXYAUTH, - (long) (CURLAUTH_NTLM | CURLAUTH_DIGEST | CURLAUTH_BASIC) ); + CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_NTLM); multi_init(m); diff --git a/vendor/curl/tests/libtest/lib556.c b/vendor/curl/tests/libtest/lib556.c index c3eeea18148..7b155a25283 100644 --- a/vendor/curl/tests/libtest/lib556.c +++ b/vendor/curl/tests/libtest/lib556.c @@ -21,18 +21,15 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "warnless.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib556(const char *URL) { CURLcode res; CURL *curl; -#ifdef LIB696 int transfers = 0; -#endif if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { curl_mfprintf(stderr, "curl_global_init() failed\n"); @@ -50,15 +47,13 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_CONNECT_ONLY, 1L); test_setopt(curl, CURLOPT_VERBOSE, 1L); -#ifdef LIB696 again: -#endif res = curl_easy_perform(curl); if(!res) { /* we are connected, now get an HTTP document the raw way */ - const char *request = + static const char *request = "GET /556 HTTP/1.1\r\n" "Host: ninja\r\n\r\n"; const char *sbuf = request; @@ -89,7 +84,7 @@ CURLcode test(char *URL) if((size_t)write(STDOUT_FILENO, buf, nread) != nread) { #endif curl_mfprintf(stderr, "write() failed: errno %d (%s)\n", - errno, strerror(errno)); + errno, strerror(errno)); res = TEST_ERR_FAILURE; break; } @@ -101,12 +96,12 @@ CURLcode test(char *URL) res = TEST_ERR_FAILURE; } -#ifdef LIB696 - ++transfers; - /* perform the transfer a second time */ - if(!res && transfers == 1) - goto again; -#endif + if(testnum == 696) { + ++transfers; + /* perform the transfer a second time */ + if(!res && transfers == 1) + goto again; + } test_cleanup: diff --git a/vendor/curl/tests/libtest/lib557.c b/vendor/curl/tests/libtest/lib557.c index 8092d3967ff..61b051a43c5 100644 --- a/vendor/curl/tests/libtest/lib557.c +++ b/vendor/curl/tests/libtest/lib557.c @@ -27,9 +27,7 @@ * curl_m*printf formatting capabilities and handling of some data types. */ -#include "test.h" - -#include +#include "first.h" #ifdef HAVE_LOCALE_H # include /* for setlocale() */ @@ -46,30 +44,7 @@ #endif #endif -#if (SIZEOF_CURL_OFF_T > SIZEOF_LONG) -# define MPRNT_SUFFIX_CURL_OFF_T LL -#else -# define MPRNT_SUFFIX_CURL_OFF_T L -#endif - - -#ifdef CURL_ISOCPP -# define MPRNT_OFF_T_C_HELPER2(Val,Suffix) Val ## Suffix -#else -# define MPRNT_OFF_T_C_HELPER2(Val,Suffix) Val/**/Suffix -#endif -#define MPRNT_OFF_T_C_HELPER1(Val,Suffix) MPRNT_OFF_T_C_HELPER2(Val,Suffix) -#define MPRNT_OFF_T_C(Val) MPRNT_OFF_T_C_HELPER1(Val,MPRNT_SUFFIX_CURL_OFF_T) - - #define BUFSZ 256 -#define USHORT_TESTS_ARRSZ 1 + 100 -#define SSHORT_TESTS_ARRSZ 1 + 100 -#define UINT_TESTS_ARRSZ 1 + 100 -#define SINT_TESTS_ARRSZ 1 + 100 -#define ULONG_TESTS_ARRSZ 1 + 100 -#define SLONG_TESTS_ARRSZ 1 + 100 -#define COFFT_TESTS_ARRSZ 1 + 100 struct unsshort_st { @@ -121,13 +96,13 @@ struct curloff_st { }; -static struct unsshort_st us_test[USHORT_TESTS_ARRSZ]; -static struct sigshort_st ss_test[SSHORT_TESTS_ARRSZ]; -static struct unsint_st ui_test[UINT_TESTS_ARRSZ]; -static struct sigint_st si_test[SINT_TESTS_ARRSZ]; -static struct unslong_st ul_test[ULONG_TESTS_ARRSZ]; -static struct siglong_st sl_test[SLONG_TESTS_ARRSZ]; -static struct curloff_st co_test[COFFT_TESTS_ARRSZ]; +static struct unsshort_st us_test[1 + 100]; +static struct sigshort_st ss_test[1 + 100]; +static struct unsint_st ui_test[1 + 100]; +static struct sigint_st si_test[1 + 100]; +static struct unslong_st ul_test[1 + 100]; +static struct siglong_st sl_test[1 + 100]; +static struct curloff_st co_test[1 + 100]; static int test_unsigned_short_formatting(void) @@ -164,8 +139,8 @@ static int test_unsigned_short_formatting(void) (void)curl_msprintf(us_test[i].result, "%hu", us_test[i].num); if(memcmp(us_test[i].result, - us_test[i].expected, - strlen(us_test[i].expected))) { + us_test[i].expected, + strlen(us_test[i].expected))) { curl_mprintf("unsigned short test #%.2d: Failed " "(Expected: %s Got: %s)\n", i, us_test[i].expected, us_test[i].result); @@ -242,7 +217,7 @@ static int test_signed_short_formatting(void) ss_test[i].expected, strlen(ss_test[i].expected))) { curl_mprintf("signed short test #%.2d: Failed (Expected: %s Got: %s)\n", - i, ss_test[i].expected, ss_test[i].result); + i, ss_test[i].expected, ss_test[i].result); failed++; } @@ -389,10 +364,10 @@ static int test_unsigned_int_formatting(void) (void)curl_msprintf(ui_test[i].result, "%u", ui_test[i].num); if(memcmp(ui_test[i].result, - ui_test[i].expected, - strlen(ui_test[i].expected))) { + ui_test[i].expected, + strlen(ui_test[i].expected))) { curl_mprintf("unsigned int test #%.2d: Failed (Expected: %s Got: %s)\n", - i, ui_test[i].expected, ui_test[i].result); + i, ui_test[i].expected, ui_test[i].result); failed++; } @@ -620,7 +595,7 @@ static int test_signed_int_formatting(void) si_test[i].expected, strlen(si_test[i].expected))) { curl_mprintf("signed int test #%.2d: Failed (Expected: %s Got: %s)\n", - i, si_test[i].expected, si_test[i].result); + i, si_test[i].expected, si_test[i].result); failed++; } @@ -766,10 +741,10 @@ static int test_unsigned_long_formatting(void) (void)curl_msprintf(ul_test[i].result, "%lu", ul_test[i].num); if(memcmp(ul_test[i].result, - ul_test[i].expected, - strlen(ul_test[i].expected))) { + ul_test[i].expected, + strlen(ul_test[i].expected))) { curl_mprintf("unsigned long test #%.2d: Failed (Expected: %s Got: %s)\n", - i, ul_test[i].expected, ul_test[i].result); + i, ul_test[i].expected, ul_test[i].result); failed++; } @@ -997,7 +972,7 @@ static int test_signed_long_formatting(void) sl_test[i].expected, strlen(sl_test[i].expected))) { curl_mprintf("signed long test #%.2d: Failed (Expected: %s Got: %s)\n", - i, sl_test[i].expected, sl_test[i].result); + i, sl_test[i].expected, sl_test[i].result); failed++; } @@ -1018,84 +993,84 @@ static int test_curl_off_t_formatting(void) int num_cofft_tests = 0; int failed = 0; - i = 1; co_test[i].num = MPRNT_OFF_T_C(0x7FFFFFFFFFFFFFFF); co_test[i].expected = "9223372036854775807"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFFFFFFFFFFFFFE); co_test[i].expected = "9223372036854775806"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFFFFFFFFFFFFFD); co_test[i].expected = "9223372036854775805"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFFFFFF00000000); co_test[i].expected = "9223372032559808512"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x000000007FFFFFFF); co_test[i].expected = "2147483647"; - - i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFF000000000000); co_test[i].expected = "9223090561878065152"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x00007FFF00000000); co_test[i].expected = "140733193388032"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x000000007FFF0000); co_test[i].expected = "2147418112"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000007FFF); co_test[i].expected = "32767"; - - i++; co_test[i].num = MPRNT_OFF_T_C(0x7F00000000000000); co_test[i].expected = "9151314442816847872"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x007F000000000000); co_test[i].expected = "35747322042253312"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x00007F0000000000); co_test[i].expected = "139637976727552"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x0000007F00000000); co_test[i].expected = "545460846592"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x000000007F000000); co_test[i].expected = "2130706432"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x00000000007F0000); co_test[i].expected = "8323072"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000007F00); co_test[i].expected = "32512"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x000000000000007F); co_test[i].expected = "127"; - - i++; co_test[i].num = MPRNT_OFF_T_C(0x7000000000000000); co_test[i].expected = "8070450532247928832"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x0700000000000000); co_test[i].expected = "504403158265495552"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x0070000000000000); co_test[i].expected = "31525197391593472"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x0007000000000000); co_test[i].expected = "1970324836974592"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x0000700000000000); co_test[i].expected = "123145302310912"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x0000070000000000); co_test[i].expected = "7696581394432"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x0000007000000000); co_test[i].expected = "481036337152"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000700000000); co_test[i].expected = "30064771072"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000070000000); co_test[i].expected = "1879048192"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000007000000); co_test[i].expected = "117440512"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000700000); co_test[i].expected = "7340032"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000070000); co_test[i].expected = "458752"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000007000); co_test[i].expected = "28672"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000000700); co_test[i].expected = "1792"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000000070); co_test[i].expected = "112"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000000007); co_test[i].expected = "7"; - - i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000000001); co_test[i].expected = "1"; - i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000000000); co_test[i].expected = "0"; - - i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFFFFFFFFFFFFFF) -MPRNT_OFF_T_C(1); co_test[i].expected = "-9223372036854775808"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFFFFFFFFFFFFFE) -MPRNT_OFF_T_C(1); co_test[i].expected = "-9223372036854775807"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFFFFFFFFFFFFFD) -MPRNT_OFF_T_C(1); co_test[i].expected = "-9223372036854775806"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFFFFFF00000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-9223372032559808513"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x000000007FFFFFFF) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2147483648"; - - i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFF000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-9223090561878065153"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x00007FFF00000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-140733193388033"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x000000007FFF0000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2147418113"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000007FFF) -MPRNT_OFF_T_C(1); co_test[i].expected = "-32768"; - - i++; co_test[i].num = -MPRNT_OFF_T_C(0x7F00000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-9151314442816847873"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x007F000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-35747322042253313"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x00007F0000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-139637976727553"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000007F00000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-545460846593"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x000000007F000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2130706433"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x00000000007F0000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-8323073"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000007F00) -MPRNT_OFF_T_C(1); co_test[i].expected = "-32513"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x000000000000007F) -MPRNT_OFF_T_C(1); co_test[i].expected = "-128"; - - i++; co_test[i].num = -MPRNT_OFF_T_C(0x7000000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-8070450532247928833"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x0700000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-504403158265495553"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x0070000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-31525197391593473"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x0007000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1970324836974593"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000700000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-123145302310913"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000070000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-7696581394433"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000007000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-481036337153"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000700000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-30064771073"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000070000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1879048193"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000007000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-117440513"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000700000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-7340033"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000070000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-458753"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000007000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-28673"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000000700) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1793"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000000070) -MPRNT_OFF_T_C(1); co_test[i].expected = "-113"; - i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000000007) -MPRNT_OFF_T_C(1); co_test[i].expected = "-8"; - - i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1"; + i = 1; co_test[i].num = 0x7FFFFFFFFFFFFFFFLL; co_test[i].expected = "9223372036854775807"; + i++; co_test[i].num = 0x7FFFFFFFFFFFFFFE; co_test[i].expected = "9223372036854775806"; + i++; co_test[i].num = 0x7FFFFFFFFFFFFFFD; co_test[i].expected = "9223372036854775805"; + i++; co_test[i].num = 0x7FFFFFFF00000000; co_test[i].expected = "9223372032559808512"; + i++; co_test[i].num = 0x000000007FFFFFFF; co_test[i].expected = "2147483647"; + + i++; co_test[i].num = 0x7FFF000000000000; co_test[i].expected = "9223090561878065152"; + i++; co_test[i].num = 0x00007FFF00000000; co_test[i].expected = "140733193388032"; + i++; co_test[i].num = 0x000000007FFF0000; co_test[i].expected = "2147418112"; + i++; co_test[i].num = 0x0000000000007FFF; co_test[i].expected = "32767"; + + i++; co_test[i].num = 0x7F00000000000000; co_test[i].expected = "9151314442816847872"; + i++; co_test[i].num = 0x007F000000000000; co_test[i].expected = "35747322042253312"; + i++; co_test[i].num = 0x00007F0000000000; co_test[i].expected = "139637976727552"; + i++; co_test[i].num = 0x0000007F00000000; co_test[i].expected = "545460846592"; + i++; co_test[i].num = 0x000000007F000000; co_test[i].expected = "2130706432"; + i++; co_test[i].num = 0x00000000007F0000; co_test[i].expected = "8323072"; + i++; co_test[i].num = 0x0000000000007F00; co_test[i].expected = "32512"; + i++; co_test[i].num = 0x000000000000007F; co_test[i].expected = "127"; + + i++; co_test[i].num = 0x7000000000000000; co_test[i].expected = "8070450532247928832"; + i++; co_test[i].num = 0x0700000000000000; co_test[i].expected = "504403158265495552"; + i++; co_test[i].num = 0x0070000000000000; co_test[i].expected = "31525197391593472"; + i++; co_test[i].num = 0x0007000000000000; co_test[i].expected = "1970324836974592"; + i++; co_test[i].num = 0x0000700000000000; co_test[i].expected = "123145302310912"; + i++; co_test[i].num = 0x0000070000000000; co_test[i].expected = "7696581394432"; + i++; co_test[i].num = 0x0000007000000000; co_test[i].expected = "481036337152"; + i++; co_test[i].num = 0x0000000700000000; co_test[i].expected = "30064771072"; + i++; co_test[i].num = 0x0000000070000000; co_test[i].expected = "1879048192"; + i++; co_test[i].num = 0x0000000007000000; co_test[i].expected = "117440512"; + i++; co_test[i].num = 0x0000000000700000; co_test[i].expected = "7340032"; + i++; co_test[i].num = 0x0000000000070000; co_test[i].expected = "458752"; + i++; co_test[i].num = 0x0000000000007000; co_test[i].expected = "28672"; + i++; co_test[i].num = 0x0000000000000700; co_test[i].expected = "1792"; + i++; co_test[i].num = 0x0000000000000070; co_test[i].expected = "112"; + i++; co_test[i].num = 0x0000000000000007; co_test[i].expected = "7"; + + i++; co_test[i].num = 0x0000000000000001; co_test[i].expected = "1"; + i++; co_test[i].num = 0x0000000000000000; co_test[i].expected = "0"; + + i++; co_test[i].num = -0x7FFFFFFFFFFFFFFFLL - 1; co_test[i].expected = "-9223372036854775808"; + i++; co_test[i].num = -0x7FFFFFFFFFFFFFFE -1; co_test[i].expected = "-9223372036854775807"; + i++; co_test[i].num = -0x7FFFFFFFFFFFFFFD -1; co_test[i].expected = "-9223372036854775806"; + i++; co_test[i].num = -0x7FFFFFFF00000000 -1; co_test[i].expected = "-9223372032559808513"; + i++; co_test[i].num = -0x000000007FFFFFFF -1; co_test[i].expected = "-2147483648"; + + i++; co_test[i].num = -0x7FFF000000000000 -1; co_test[i].expected = "-9223090561878065153"; + i++; co_test[i].num = -0x00007FFF00000000 -1; co_test[i].expected = "-140733193388033"; + i++; co_test[i].num = -0x000000007FFF0000 -1; co_test[i].expected = "-2147418113"; + i++; co_test[i].num = -0x0000000000007FFF -1; co_test[i].expected = "-32768"; + + i++; co_test[i].num = -0x7F00000000000000 -1; co_test[i].expected = "-9151314442816847873"; + i++; co_test[i].num = -0x007F000000000000 -1; co_test[i].expected = "-35747322042253313"; + i++; co_test[i].num = -0x00007F0000000000 -1; co_test[i].expected = "-139637976727553"; + i++; co_test[i].num = -0x0000007F00000000 -1; co_test[i].expected = "-545460846593"; + i++; co_test[i].num = -0x000000007F000000 -1; co_test[i].expected = "-2130706433"; + i++; co_test[i].num = -0x00000000007F0000 -1; co_test[i].expected = "-8323073"; + i++; co_test[i].num = -0x0000000000007F00 -1; co_test[i].expected = "-32513"; + i++; co_test[i].num = -0x000000000000007F -1; co_test[i].expected = "-128"; + + i++; co_test[i].num = -0x7000000000000000 -1; co_test[i].expected = "-8070450532247928833"; + i++; co_test[i].num = -0x0700000000000000 -1; co_test[i].expected = "-504403158265495553"; + i++; co_test[i].num = -0x0070000000000000 -1; co_test[i].expected = "-31525197391593473"; + i++; co_test[i].num = -0x0007000000000000 -1; co_test[i].expected = "-1970324836974593"; + i++; co_test[i].num = -0x0000700000000000 -1; co_test[i].expected = "-123145302310913"; + i++; co_test[i].num = -0x0000070000000000 -1; co_test[i].expected = "-7696581394433"; + i++; co_test[i].num = -0x0000007000000000 -1; co_test[i].expected = "-481036337153"; + i++; co_test[i].num = -0x0000000700000000 -1; co_test[i].expected = "-30064771073"; + i++; co_test[i].num = -0x0000000070000000 -1; co_test[i].expected = "-1879048193"; + i++; co_test[i].num = -0x0000000007000000 -1; co_test[i].expected = "-117440513"; + i++; co_test[i].num = -0x0000000000700000 -1; co_test[i].expected = "-7340033"; + i++; co_test[i].num = -0x0000000000070000 -1; co_test[i].expected = "-458753"; + i++; co_test[i].num = -0x0000000000007000 -1; co_test[i].expected = "-28673"; + i++; co_test[i].num = -0x0000000000000700 -1; co_test[i].expected = "-1793"; + i++; co_test[i].num = -0x0000000000000070 -1; co_test[i].expected = "-113"; + i++; co_test[i].num = -0x0000000000000007 -1; co_test[i].expected = "-8"; + + i++; co_test[i].num = 0x0000000000000000 -1; co_test[i].expected = "-1"; num_cofft_tests = i; @@ -1112,7 +1087,7 @@ static int test_curl_off_t_formatting(void) co_test[i].expected, strlen(co_test[i].expected))) { curl_mprintf("curl_off_t test #%.2d: Failed (Expected: %s Got: %s)\n", - i, co_test[i].expected, co_test[i].result); + i, co_test[i].expected, co_test[i].result); failed++; } @@ -1131,7 +1106,7 @@ static int _string_check(int linenumber, char *buf, const char *buf2) if(strcmp(buf, buf2)) { /* they shouldn't differ */ curl_mprintf("sprintf line %d failed:\nwe '%s'\nsystem: '%s'\n", - linenumber, buf, buf2); + linenumber, buf, buf2); return 1; } return 0; @@ -1144,7 +1119,7 @@ static int _strlen_check(int linenumber, char *buf, size_t len) if(len != buflen) { /* they shouldn't differ */ curl_mprintf("sprintf strlen:%d failed:\nwe '%zu'\nsystem: '%zu'\n", - linenumber, buflen, len); + linenumber, buflen, len); return 1; } return 0; @@ -1164,7 +1139,7 @@ static int test_string_formatting(void) errors += string_check(buf, "09foo"); curl_msnprintf(buf, sizeof(buf), "%*.*s", 5, 2, "foo"); - errors += string_check(buf, " fo"); + errors += string_check(buf, " fo"); /* spellchecker:disable-line */ curl_msnprintf(buf, sizeof(buf), "%*.*s", 2, 5, "foo"); errors += string_check(buf, "foo"); @@ -1557,7 +1532,7 @@ static int test_return_codes(void) return 0; } -CURLcode test(char *URL) +static CURLcode test_lib557(const char *URL) { int errors = 0; (void)URL; /* not used */ @@ -1571,29 +1546,17 @@ CURLcode test(char *URL) #endif errors += test_pos_arguments(); - errors += test_weird_arguments(); - errors += test_unsigned_short_formatting(); - errors += test_signed_short_formatting(); - errors += test_unsigned_int_formatting(); - errors += test_signed_int_formatting(); - errors += test_unsigned_long_formatting(); - errors += test_signed_long_formatting(); - errors += test_curl_off_t_formatting(); - errors += test_string_formatting(); - errors += test_float_formatting(); - errors += test_oct_hex_formatting(); - errors += test_return_codes(); if(errors) diff --git a/vendor/curl/tests/libtest/lib558.c b/vendor/curl/tests/libtest/lib558.c index 3f1724a1e33..795a0b74b37 100644 --- a/vendor/curl/tests/libtest/lib558.c +++ b/vendor/curl/tests/libtest/lib558.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib558(const char *URL) { unsigned char a[] = {0x2f, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x91, 0xa2, 0xb3, 0xc4, 0xd5, 0xe6, 0xf7}; diff --git a/vendor/curl/tests/libtest/lib559.c b/vendor/curl/tests/libtest/lib559.c index 621b90e6111..36a55751265 100644 --- a/vendor/curl/tests/libtest/lib559.c +++ b/vendor/curl/tests/libtest/lib559.c @@ -21,12 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testtrace.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib559(const char *URL) { CURLcode res; CURL *curl; diff --git a/vendor/curl/tests/libtest/lib560.c b/vendor/curl/tests/libtest/lib560.c index 95b62ce784b..060e27eea05 100644 --- a/vendor/curl/tests/libtest/lib560.c +++ b/vendor/curl/tests/libtest/lib560.c @@ -21,14 +21,10 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - /* * Simply download an HTTPS file! * @@ -39,7 +35,7 @@ * fast/different compared to the real/distant servers we saw the bug happen * with. */ -CURLcode test(char *URL) +static CURLcode test_lib560(const char *URL) { CURL *http_handle = NULL; CURLM *multi_handle = NULL; diff --git a/vendor/curl/tests/libtest/lib562.c b/vendor/curl/tests/libtest/lib562.c index fa9c75bac64..016dffe1bda 100644 --- a/vendor/curl/tests/libtest/lib562.c +++ b/vendor/curl/tests/libtest/lib562.c @@ -21,11 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" - -#ifdef HAVE_FCNTL_H -#include -#endif +#include "first.h" #include "memdebug.h" @@ -37,7 +33,7 @@ */ -CURLcode test(char *URL) +static CURLcode test_lib562(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; diff --git a/vendor/curl/tests/libtest/lib564.c b/vendor/curl/tests/libtest/lib564.c index 11c9ab6e7b1..86e4f9ed06c 100644 --- a/vendor/curl/tests/libtest/lib564.c +++ b/vendor/curl/tests/libtest/lib564.c @@ -21,17 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include - -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -CURLcode test(char *URL) +static CURLcode test_lib564(const char *URL) { CURLcode res = CURLE_OK; CURL *curl = NULL; @@ -47,7 +41,7 @@ CURLcode test(char *URL) easy_setopt(curl, CURLOPT_URL, URL); easy_setopt(curl, CURLOPT_VERBOSE, 1L); easy_setopt(curl, CURLOPT_PROXY, libtest_arg2); - easy_setopt(curl, CURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS4); + easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4); multi_init(m); diff --git a/vendor/curl/tests/libtest/lib566.c b/vendor/curl/tests/libtest/lib566.c index 3ed609f67f1..15221cd0ccd 100644 --- a/vendor/curl/tests/libtest/lib566.c +++ b/vendor/curl/tests/libtest/lib566.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib566(const char *URL) { CURLcode res; CURL *curl; diff --git a/vendor/curl/tests/libtest/lib567.c b/vendor/curl/tests/libtest/lib567.c index 9c36cfa420f..a11a6c31f01 100644 --- a/vendor/curl/tests/libtest/lib567.c +++ b/vendor/curl/tests/libtest/lib567.c @@ -21,14 +21,14 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" /* * Test a simple OPTIONS request with a custom header */ -CURLcode test(char *URL) +static CURLcode test_lib567(const char *URL) { CURLcode res; CURL *curl; diff --git a/vendor/curl/tests/libtest/lib568.c b/vendor/curl/tests/libtest/lib568.c index f3e68c2da3c..8e34194ef5e 100644 --- a/vendor/curl/tests/libtest/lib568.c +++ b/vendor/curl/tests/libtest/lib568.c @@ -21,27 +21,15 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" - -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif +#include "first.h" +#include "testutil.h" #include "memdebug.h" -/* build request url */ -static char *suburl(const char *base, int i) -{ - return curl_maprintf("%s%.4d", base, i); -} - /* * Test the Client->Server ANNOUNCE functionality (PUT style) */ -CURLcode test(char *URL) +static CURLcode test_lib568(const char *URL) { CURLcode res; CURL *curl; @@ -69,7 +57,7 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_URL, URL); - stream_uri = suburl(URL, request++); + stream_uri = tutil_suburl(URL, request++); if(!stream_uri) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; @@ -110,7 +98,7 @@ CURLcode test(char *URL) sdpf = NULL; /* Make sure we can do a normal request now */ - stream_uri = suburl(URL, request++); + stream_uri = tutil_suburl(URL, request++); if(!stream_uri) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; @@ -126,7 +114,7 @@ CURLcode test(char *URL) /* Now do a POST style one */ - stream_uri = suburl(URL, request++); + stream_uri = tutil_suburl(URL, request++); if(!stream_uri) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; @@ -156,7 +144,7 @@ CURLcode test(char *URL) custom_headers = NULL; /* Make sure we can do a normal request now */ - stream_uri = suburl(URL, request++); + stream_uri = tutil_suburl(URL, request++); if(!stream_uri) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; diff --git a/vendor/curl/tests/libtest/lib569.c b/vendor/curl/tests/libtest/lib569.c index f5d124f4d98..8f340b489d5 100644 --- a/vendor/curl/tests/libtest/lib569.c +++ b/vendor/curl/tests/libtest/lib569.c @@ -21,19 +21,15 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" -#include "memdebug.h" +#include "first.h" -/* build request url */ -static char *suburl(const char *base, int i) -{ - return curl_maprintf("%s%.4d", base, i); -} +#include "testutil.h" +#include "memdebug.h" /* * Test Session ID capture */ -CURLcode test(char *URL) +static CURLcode test_lib569(const char *URL) { CURLcode res; CURL *curl; @@ -70,16 +66,16 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP); res = curl_easy_perform(curl); - if(res != (int)CURLE_BAD_FUNCTION_ARGUMENT) { + if(res != CURLE_BAD_FUNCTION_ARGUMENT) { curl_mfprintf(stderr, "This should have failed. " - "Cannot setup without a Transport: header"); + "Cannot setup without a Transport: header"); res = TEST_ERR_MAJOR_BAD; goto test_cleanup; } /* Go through the various Session IDs */ for(i = 0; i < 3; i++) { - stream_uri = suburl(URL, request++); + stream_uri = tutil_suburl(URL, request++); if(!stream_uri) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; @@ -99,7 +95,7 @@ CURLcode test(char *URL) curl_mfprintf(idfile, "Got Session ID: [%s]\n", rtsp_session_id); rtsp_session_id = NULL; - stream_uri = suburl(URL, request++); + stream_uri = tutil_suburl(URL, request++); if(!stream_uri) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; diff --git a/vendor/curl/tests/libtest/lib570.c b/vendor/curl/tests/libtest/lib570.c index 8f803b656ad..300881efa7b 100644 --- a/vendor/curl/tests/libtest/lib570.c +++ b/vendor/curl/tests/libtest/lib570.c @@ -21,16 +21,12 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" -#include "memdebug.h" +#include "first.h" -/* build request url */ -static char *suburl(const char *base, int i) -{ - return curl_maprintf("%s%.4d", base, i); -} +#include "testutil.h" +#include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib570(const char *URL) { CURLcode res; CURL *curl; @@ -57,7 +53,7 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_OPTIONS); - stream_uri = suburl(URL, request++); + stream_uri = tutil_suburl(URL, request++); if(!stream_uri) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; @@ -67,7 +63,7 @@ CURLcode test(char *URL) stream_uri = NULL; res = curl_easy_perform(curl); - if(res != (int)CURLE_RTSP_CSEQ_ERROR) { + if(res != CURLE_RTSP_CSEQ_ERROR) { curl_mfprintf(stderr, "Failed to detect CSeq mismatch"); res = TEST_ERR_MAJOR_BAD; goto test_cleanup; @@ -78,7 +74,7 @@ CURLcode test(char *URL) "RAW/RAW/UDP;unicast;client_port=3056-3057"); test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP); - stream_uri = suburl(URL, request++); + stream_uri = tutil_suburl(URL, request++); if(!stream_uri) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; @@ -93,7 +89,7 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_PLAY); - stream_uri = suburl(URL, request++); + stream_uri = tutil_suburl(URL, request++); if(!stream_uri) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; diff --git a/vendor/curl/tests/libtest/lib571.c b/vendor/curl/tests/libtest/lib571.c index fe0f7e05efc..2cf4128e7ab 100644 --- a/vendor/curl/tests/libtest/lib571.c +++ b/vendor/curl/tests/libtest/lib571.c @@ -21,25 +21,19 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #ifdef HAVE_NETINET_IN_H -# include +#include #endif #ifdef HAVE_NETDB_H -# include +#include #endif #ifdef HAVE_ARPA_INET_H -# include -#endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef HAVE_FCNTL_H -# include +#include #endif -#include "warnless.h" +#include "testutil.h" #include "memdebug.h" #define RTP_PKT_CHANNEL(p) ((int)((unsigned char)((p)[1]))) @@ -48,13 +42,13 @@ ((int)((unsigned char)((p)[3])))) #define RTP_DATA_SIZE 12 -static const char *RTP_DATA = "$_1234\n\0Rsdf"; static int rtp_packet_count = 0; -static size_t rtp_write(char *ptr, size_t size, size_t nmemb, void *stream) +static size_t rtp_write(char *data, size_t size, size_t nmemb, void *stream) { - char *data = (char *)ptr; + static const char *RTP_DATA = "$_1234\n\0Rsdf"; + int channel = RTP_PKT_CHANNEL(data); int message_size; int coded_size = RTP_PKT_LENGTH(data); @@ -67,8 +61,7 @@ static size_t rtp_write(char *ptr, size_t size, size_t nmemb, void *stream) curl_mprintf("RTP: message size %d, channel %d\n", message_size, channel); if(message_size != coded_size) { curl_mprintf("RTP embedded size (%d) does not match " - "the write size (%d).\n", - coded_size, message_size); + "the write size (%d).\n", coded_size, message_size); return failure; } @@ -83,7 +76,7 @@ static size_t rtp_write(char *ptr, size_t size, size_t nmemb, void *stream) else { if(memcmp(RTP_DATA, data + i, message_size - i) != 0) { curl_mprintf("RTP PAYLOAD END CORRUPTED (%d), [%s]\n", - message_size - i, data + i); + message_size - i, data + i); /* return failure; */ } } @@ -95,13 +88,7 @@ static size_t rtp_write(char *ptr, size_t size, size_t nmemb, void *stream) return size * nmemb; } -/* build request url */ -static char *suburl(const char *base, int i) -{ - return curl_maprintf("%s%.4d", base, i); -} - -CURLcode test(char *URL) +static CURLcode test_lib571(const char *URL) { CURLcode res; CURL *curl; @@ -129,7 +116,7 @@ CURLcode test(char *URL) } test_setopt(curl, CURLOPT_URL, URL); - stream_uri = suburl(URL, request++); + stream_uri = tutil_suburl(URL, request++); if(!stream_uri) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; @@ -151,7 +138,7 @@ CURLcode test(char *URL) goto test_cleanup; /* This PLAY starts the interleave */ - stream_uri = suburl(URL, request++); + stream_uri = tutil_suburl(URL, request++); if(!stream_uri) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; @@ -166,7 +153,7 @@ CURLcode test(char *URL) goto test_cleanup; /* The DESCRIBE request will try to consume data after the Content */ - stream_uri = suburl(URL, request++); + stream_uri = tutil_suburl(URL, request++); if(!stream_uri) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; @@ -180,7 +167,7 @@ CURLcode test(char *URL) if(res) goto test_cleanup; - stream_uri = suburl(URL, request++); + stream_uri = tutil_suburl(URL, request++); if(!stream_uri) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; diff --git a/vendor/curl/tests/libtest/lib572.c b/vendor/curl/tests/libtest/lib572.c index 5f572211345..ea9e34e0685 100644 --- a/vendor/curl/tests/libtest/lib572.c +++ b/vendor/curl/tests/libtest/lib572.c @@ -21,27 +21,15 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" - -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif +#include "first.h" +#include "testutil.h" #include "memdebug.h" -/* build request url */ -static char *suburl(const char *base, int i) -{ - return curl_maprintf("%s%.4d", base, i); -} - /* * Test GET_PARAMETER: PUT, HEARTBEAT, and POST */ -CURLcode test(char *URL) +static CURLcode test_lib572(const char *URL) { CURLcode res; CURL *curl; @@ -64,7 +52,6 @@ CURLcode test(char *URL) return TEST_ERR_MAJOR_BAD; } - test_setopt(curl, CURLOPT_HEADERDATA, stdout); test_setopt(curl, CURLOPT_WRITEDATA, stdout); test_setopt(curl, CURLOPT_VERBOSE, 1L); @@ -72,7 +59,7 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_URL, URL); /* SETUP */ - stream_uri = suburl(URL, request++); + stream_uri = tutil_suburl(URL, request++); if(!stream_uri) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; @@ -87,7 +74,7 @@ CURLcode test(char *URL) if(res) goto test_cleanup; - stream_uri = suburl(URL, request++); + stream_uri = tutil_suburl(URL, request++); if(!stream_uri) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; @@ -127,7 +114,7 @@ CURLcode test(char *URL) paramsf = NULL; /* Heartbeat GET_PARAMETERS */ - stream_uri = suburl(URL, request++); + stream_uri = tutil_suburl(URL, request++); if(!stream_uri) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; @@ -142,7 +129,7 @@ CURLcode test(char *URL) /* POST GET_PARAMETERS */ - stream_uri = suburl(URL, request++); + stream_uri = tutil_suburl(URL, request++); if(!stream_uri) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; @@ -161,7 +148,7 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_POSTFIELDS, NULL); /* Make sure we can do a normal request now */ - stream_uri = suburl(URL, request++); + stream_uri = tutil_suburl(URL, request++); if(!stream_uri) { res = TEST_ERR_MAJOR_BAD; goto test_cleanup; diff --git a/vendor/curl/tests/libtest/lib573.c b/vendor/curl/tests/libtest/lib573.c index 40af2212c9d..572bfa0cd12 100644 --- a/vendor/curl/tests/libtest/lib573.c +++ b/vendor/curl/tests/libtest/lib573.c @@ -21,20 +21,16 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "testtrace.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - /* * Get a single URL without select(). */ -CURLcode test(char *URL) +static CURLcode test_lib573(const char *URL) { CURL *c = NULL; CURLM *m = NULL; @@ -57,9 +53,9 @@ CURLcode test(char *URL) easy_setopt(c, CURLOPT_HEADER, 1L); easy_setopt(c, CURLOPT_URL, URL); - libtest_debug_config.nohex = 1; - libtest_debug_config.tracetime = 1; - easy_setopt(c, CURLOPT_DEBUGDATA, &libtest_debug_config); + debug_config.nohex = TRUE; + debug_config.tracetime = TRUE; + easy_setopt(c, CURLOPT_DEBUGDATA, &debug_config); easy_setopt(c, CURLOPT_DEBUGFUNCTION, libtest_debug_cb); easy_setopt(c, CURLOPT_VERBOSE, 1L); @@ -98,7 +94,7 @@ CURLcode test(char *URL) curl_easy_getinfo(c, CURLINFO_CONNECT_TIME, &connect_time); if(connect_time < dbl_epsilon) { curl_mfprintf(stderr, "connect time %e is < epsilon %e\n", - connect_time, dbl_epsilon); + connect_time, dbl_epsilon); res = TEST_ERR_MAJOR_BAD; } diff --git a/vendor/curl/tests/libtest/lib574.c b/vendor/curl/tests/libtest/lib574.c index 4675f2d60fb..e82be6c0d66 100644 --- a/vendor/curl/tests/libtest/lib574.c +++ b/vendor/curl/tests/libtest/lib574.c @@ -21,22 +21,20 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT (60 * 1000) - static int new_fnmatch(void *ptr, const char *pattern, const char *string) { (void)ptr; curl_mfprintf(stderr, "lib574: match string '%s' against pattern '%s'\n", - string, pattern); + string, pattern); return CURL_FNMATCHFUNC_MATCH; } -CURLcode test(char *URL) +static CURLcode test_lib574(const char *URL) { CURLcode res; CURL *curl; @@ -56,7 +54,7 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_URL, URL); test_setopt(curl, CURLOPT_WILDCARDMATCH, 1L); test_setopt(curl, CURLOPT_FNMATCH_FUNCTION, new_fnmatch); - test_setopt(curl, CURLOPT_TIMEOUT_MS, (long) TEST_HANG_TIMEOUT); + test_setopt(curl, CURLOPT_TIMEOUT_MS, (long)TEST_HANG_TIMEOUT); res = curl_easy_perform(curl); if(res) { diff --git a/vendor/curl/tests/libtest/lib575.c b/vendor/curl/tests/libtest/lib575.c index d64f70d737d..a0ac02f8521 100644 --- a/vendor/curl/tests/libtest/lib575.c +++ b/vendor/curl/tests/libtest/lib575.c @@ -21,23 +21,17 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include - -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - /* 3x download! * 1. normal * 2. dup handle * 3. with multi interface */ -CURLcode test(char *URL) +static CURLcode test_lib575(const char *URL) { CURL *handle = NULL; CURL *duphandle = NULL; diff --git a/vendor/curl/tests/libtest/lib576.c b/vendor/curl/tests/libtest/lib576.c index 014fd896ac7..a054dba3fa9 100644 --- a/vendor/curl/tests/libtest/lib576.c +++ b/vendor/curl/tests/libtest/lib576.c @@ -21,9 +21,8 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" #include "memdebug.h" struct chunk_data { @@ -31,8 +30,7 @@ struct chunk_data { int print_content; }; -static -long chunk_bgn(const void *f, void *ptr, int remains) +static long chunk_bgn(const void *f, void *ptr, int remains) { const struct curl_fileinfo *finfo = f; struct chunk_data *ch_d = ptr; @@ -48,7 +46,7 @@ long chunk_bgn(const void *f, void *ptr, int remains) curl_mprintf(" (parsed => %o)", finfo->perm); curl_mprintf("\n"); } - curl_mprintf("Size: %ldB\n", (long)finfo->size); + curl_mprintf("Size: %" CURL_FORMAT_CURL_OFF_T "B\n", finfo->size); if(finfo->strings.user) curl_mprintf("User: %s\n", finfo->strings.user); if(finfo->strings.group) @@ -74,7 +72,8 @@ long chunk_bgn(const void *f, void *ptr, int remains) if(finfo->filetype == CURLFILETYPE_FILE) { ch_d->print_content = 1; curl_mprintf("Content:\n" - "-------------------------------------------------------------\n"); + "-------------------------------------------" + "------------------\n"); } if(strcmp(finfo->filename, "someothertext.txt") == 0) { curl_mprintf("# THIS CONTENT WAS SKIPPED IN CHUNK_BGN CALLBACK #\n"); @@ -83,8 +82,7 @@ long chunk_bgn(const void *f, void *ptr, int remains) return CURL_CHUNK_BGN_FUNC_OK; } -static -long chunk_end(void *ptr) +static long chunk_end(void *ptr) { struct chunk_data *ch_d = ptr; if(ch_d->print_content) { @@ -98,7 +96,7 @@ long chunk_end(void *ptr) return CURL_CHUNK_END_FUNC_OK; } -CURLcode test(char *URL) +static CURLcode test_lib576(const char *URL) { CURL *handle = NULL; CURLcode res = CURLE_OK; diff --git a/vendor/curl/tests/libtest/lib578.c b/vendor/curl/tests/libtest/lib578.c index 33b807afb0e..5b46c8e622b 100644 --- a/vendor/curl/tests/libtest/lib578.c +++ b/vendor/curl/tests/libtest/lib578.c @@ -21,17 +21,17 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" /* The size of data should be kept below MAX_INITIAL_POST_SIZE! */ -static char testdata[]="this is a short string.\n"; +static char t578_testdata[] = "this is a short string.\n"; -static size_t data_size = CURL_ARRAYSIZE(testdata); +static size_t data_size = CURL_ARRAYSIZE(t578_testdata); -static int progress_callback(void *clientp, double dltotal, double dlnow, - double ultotal, double ulnow) +static int t578_progress_callback(void *clientp, double dltotal, double dlnow, + double ultotal, double ulnow) { FILE *moo = fopen(libtest_arg2, "wb"); @@ -44,13 +44,13 @@ static int progress_callback(void *clientp, double dltotal, double dlnow, curl_mfprintf(moo, "PASSED, UL data matched data size\n"); else curl_mfprintf(moo, "Progress callback called with UL %f out of %f\n", - ulnow, ultotal); + ulnow, ultotal); fclose(moo); } return 0; } -CURLcode test(char *URL) +static CURLcode test_lib578(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; @@ -75,11 +75,11 @@ CURLcode test(char *URL) /* Set the expected POST size */ test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)data_size); - test_setopt(curl, CURLOPT_POSTFIELDS, testdata); + test_setopt(curl, CURLOPT_POSTFIELDS, t578_testdata); /* we want to use our own progress function */ test_setopt(curl, CURLOPT_NOPROGRESS, 0L); - test_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback); + test_setopt(curl, CURLOPT_PROGRESSFUNCTION, t578_progress_callback); /* get verbose debug output please */ test_setopt(curl, CURLOPT_VERBOSE, 1L); diff --git a/vendor/curl/tests/libtest/lib579.c b/vendor/curl/tests/libtest/lib579.c index 8bc9e2a7cd2..4f6b67e5400 100644 --- a/vendor/curl/tests/libtest/lib579.c +++ b/vendor/curl/tests/libtest/lib579.c @@ -21,20 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -static const char * const testpost[]={ - "one", - "two", - "three", - "and a final longer crap: four", - NULL -}; - - -struct WriteThis { +struct t579_WriteThis { int counter; }; @@ -46,7 +37,7 @@ static void progress_final_report(void) { FILE *moo = fopen(libtest_arg2, "ab"); curl_mfprintf(moo ? moo : stderr, "Progress: end UL %zu/%zu\n", - last_ul, last_ul_total); + last_ul, last_ul_total); if(moo) fclose(moo); else @@ -54,8 +45,8 @@ static void progress_final_report(void) started = FALSE; } -static int progress_callback(void *clientp, double dltotal, double dlnow, - double ultotal, double ulnow) +static int t579_progress_callback(void *clientp, double dltotal, double dlnow, + double ultotal, double ulnow) { (void)clientp; /* UNUSED */ (void)dltotal; /* UNUSED */ @@ -70,7 +61,7 @@ static int progress_callback(void *clientp, double dltotal, double dlnow, if(!started) { FILE *moo = fopen(libtest_arg2, "ab"); curl_mfprintf(moo ? moo : stderr, "Progress: start UL %zu/%zu\n", - last_ul, last_ul_total); + last_ul, last_ul_total); if(moo) fclose(moo); else @@ -82,9 +73,17 @@ static int progress_callback(void *clientp, double dltotal, double dlnow, return 0; } -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) +static size_t t579_read_cb(char *ptr, size_t size, size_t nmemb, void *userp) { - struct WriteThis *pooh = (struct WriteThis *)userp; + static const char * const testpost[] = { + "one", + "two", + "three", + "and a final longer crap: four", + NULL + }; + + struct t579_WriteThis *pooh = (struct t579_WriteThis *)userp; const char *data; if(size*nmemb < 1) @@ -101,12 +100,12 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) return 0; /* no more data left to deliver */ } -CURLcode test(char *URL) +static CURLcode test_lib579(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; struct curl_slist *slist = NULL; - struct WriteThis pooh; + struct t579_WriteThis pooh; pooh.counter = 0; if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { @@ -136,7 +135,7 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_POST, 1L); /* we want to use our own read function */ - test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + test_setopt(curl, CURLOPT_READFUNCTION, t579_read_cb); /* pointer to pass to our read function */ test_setopt(curl, CURLOPT_READDATA, &pooh); @@ -150,12 +149,12 @@ CURLcode test(char *URL) /* enforce chunked transfer by setting the header */ test_setopt(curl, CURLOPT_HTTPHEADER, slist); - test_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_DIGEST); + test_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); test_setopt(curl, CURLOPT_USERPWD, "foo:bar"); /* we want to use our own progress function */ test_setopt(curl, CURLOPT_NOPROGRESS, 0L); - test_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback); + test_setopt(curl, CURLOPT_PROGRESSFUNCTION, t579_progress_callback); /* Perform the request, res will get the return code */ res = curl_easy_perform(curl); diff --git a/vendor/curl/tests/libtest/lib582.c b/vendor/curl/tests/libtest/lib582.c index 2d2f2bcb7a2..8ca87d459d2 100644 --- a/vendor/curl/tests/libtest/lib582.c +++ b/vendor/curl/tests/libtest/lib582.c @@ -21,41 +21,36 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include - -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -struct Sockets { +struct t582_Sockets { curl_socket_t *sockets; int count; /* number of sockets actually stored in array */ int max_count; /* max number of sockets that fit in allocated array */ }; -struct ReadWriteSockets { - struct Sockets read, write; +struct t582_ReadWriteSockets { + struct t582_Sockets read, write; }; /** * Remove a file descriptor from a sockets array. */ -static void removeFd(struct Sockets *sockets, curl_socket_t fd, int mention) +static void t582_removeFd(struct t582_Sockets *sockets, curl_socket_t fd, + int mention) { int i; if(mention) - curl_mfprintf(stderr, "Remove socket fd %d\n", (int) fd); + curl_mfprintf(stderr, "Remove socket fd %" FMT_SOCKET_T "\n", fd); for(i = 0; i < sockets->count; ++i) { if(sockets->sockets[i] == fd) { if(i < sockets->count - 1) memmove(&sockets->sockets[i], &sockets->sockets[i + 1], - sizeof(curl_socket_t) * (sockets->count - (i + 1))); + sizeof(curl_socket_t) * (sockets->count - (i + 1))); --sockets->count; } } @@ -64,14 +59,15 @@ static void removeFd(struct Sockets *sockets, curl_socket_t fd, int mention) /** * Add a file descriptor to a sockets array. */ -static void addFd(struct Sockets *sockets, curl_socket_t fd, const char *what) +static void t582_addFd(struct t582_Sockets *sockets, curl_socket_t fd, + const char *what) { /** * To ensure we only have each file descriptor once, we remove it then add * it again. */ - curl_mfprintf(stderr, "Add socket fd %d for %s\n", (int) fd, what); - removeFd(sockets, fd, 0); + curl_mfprintf(stderr, "Add socket fd %" FMT_SOCKET_T " for %s\n", fd, what); + t582_removeFd(sockets, fd, 0); /* * Allocate array storage when required. */ @@ -96,23 +92,23 @@ static void addFd(struct Sockets *sockets, curl_socket_t fd, const char *what) /** * Callback invoked by curl to poll reading / writing of a socket. */ -static int curlSocketCallback(CURL *easy, curl_socket_t s, int action, - void *userp, void *socketp) +static int t582_curlSocketCallback(CURL *easy, curl_socket_t s, int action, + void *userp, void *socketp) { - struct ReadWriteSockets *sockets = userp; + struct t582_ReadWriteSockets *sockets = userp; (void)easy; /* unused */ (void)socketp; /* unused */ if(action == CURL_POLL_IN || action == CURL_POLL_INOUT) - addFd(&sockets->read, s, "read"); + t582_addFd(&sockets->read, s, "read"); if(action == CURL_POLL_OUT || action == CURL_POLL_INOUT) - addFd(&sockets->write, s, "write"); + t582_addFd(&sockets->write, s, "write"); if(action == CURL_POLL_REMOVE) { - removeFd(&sockets->read, s, 1); - removeFd(&sockets->write, s, 0); + t582_removeFd(&sockets->read, s, 1); + t582_removeFd(&sockets->write, s, 0); } return 0; @@ -121,13 +117,13 @@ static int curlSocketCallback(CURL *easy, curl_socket_t s, int action, /** * Callback invoked by curl to set a timeout. */ -static int curlTimerCallback(CURLM *multi, long timeout_ms, void *userp) +static int t582_curlTimerCallback(CURLM *multi, long timeout_ms, void *userp) { - struct timeval *timeout = userp; + struct curltime *timeout = userp; (void)multi; /* unused */ if(timeout_ms != -1) { - *timeout = tutil_tvnow(); + *timeout = curlx_now(); timeout->tv_usec += (int)timeout_ms * 1000; } else { @@ -139,7 +135,7 @@ static int curlTimerCallback(CURLM *multi, long timeout_ms, void *userp) /** * Check for curl completion. */ -static int checkForCompletion(CURLM *curl, int *success) +static int t582_checkForCompletion(CURLM *curl, int *success) { int result = 0; *success = 0; @@ -157,7 +153,7 @@ static int checkForCompletion(CURLM *curl, int *success) } else { curl_mfprintf(stderr, "Got an unexpected message from curl: %i\n", - (int)message->msg); + message->msg); result = 1; *success = 0; } @@ -165,33 +161,33 @@ static int checkForCompletion(CURLM *curl, int *success) return result; } -static int getMicroSecondTimeout(struct timeval *timeout) +static ssize_t t582_getMicroSecondTimeout(struct curltime *timeout) { - struct timeval now; + struct curltime now; ssize_t result; - now = tutil_tvnow(); + now = curlx_now(); result = (ssize_t)((timeout->tv_sec - now.tv_sec) * 1000000 + timeout->tv_usec - now.tv_usec); if(result < 0) result = 0; - return curlx_sztosi(result); + return result; } /** * Update a fd_set with all of the sockets in use. */ -static void updateFdSet(struct Sockets *sockets, fd_set* fdset, - curl_socket_t *maxFd) +static void t582_updateFdSet(struct t582_Sockets *sockets, fd_set* fdset, + curl_socket_t *maxFd) { int i; for(i = 0; i < sockets->count; ++i) { -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif FD_SET(sockets->sockets[i], fdset); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif if(*maxFd < sockets->sockets[i] + 1) { @@ -207,15 +203,15 @@ static void notifyCurl(CURLM *curl, curl_socket_t s, int evBitmask, CURLMcode result = curl_multi_socket_action(curl, s, evBitmask, &numhandles); if(result != CURLM_OK) { curl_mfprintf(stderr, "Curl error on %s (%i) %s\n", - info, result, curl_multi_strerror(result)); + info, result, curl_multi_strerror(result)); } } /** * Invoke curl when a file descriptor is set. */ -static void checkFdSet(CURLM *curl, struct Sockets *sockets, fd_set *fdset, - int evBitmask, const char *name) +static void t582_checkFdSet(CURLM *curl, struct t582_Sockets *sockets, + fd_set *fdset, int evBitmask, const char *name) { int i; for(i = 0; i < sockets->count; ++i) { @@ -225,7 +221,7 @@ static void checkFdSet(CURLM *curl, struct Sockets *sockets, fd_set *fdset, } } -CURLcode test(char *URL) +static CURLcode test_lib582(const char *URL) { CURLcode res = CURLE_OK; CURL *curl = NULL; @@ -233,9 +229,9 @@ CURLcode test(char *URL) int hd; struct_stat file_info; CURLM *m = NULL; - struct ReadWriteSockets sockets = {{NULL, 0, 0}, {NULL, 0, 0}}; + struct t582_ReadWriteSockets sockets = {{NULL, 0, 0}, {NULL, 0, 0}}; int success = 0; - struct timeval timeout = {0}; + struct curltime timeout = {0}; timeout.tv_sec = (time_t)-1; assert(test_argc >= 5); @@ -250,7 +246,7 @@ CURLcode test(char *URL) hd_src = fopen(libtest_arg2, "rb"); if(!hd_src) { curl_mfprintf(stderr, "fopen() failed with error (%d) %s\n", - errno, strerror(errno)); + errno, strerror(errno)); curl_mfprintf(stderr, "Error opening file '%s'\n", libtest_arg2); return TEST_ERR_FOPEN; } @@ -264,15 +260,16 @@ CURLcode test(char *URL) if(hd == -1) { /* can't open file, bail out */ curl_mfprintf(stderr, "fstat() failed with error (%d) %s\n", - errno, strerror(errno)); + errno, strerror(errno)); curl_mfprintf(stderr, "Error opening file '%s'\n", libtest_arg2); fclose(hd_src); return TEST_ERR_FSTAT; } - curl_mfprintf(stderr, "Set to upload %d bytes\n", (int)file_info.st_size); + curl_mfprintf(stderr, "Set to upload %" CURL_FORMAT_CURL_OFF_T " bytes\n", + (curl_off_t)file_info.st_size); res_global_init(CURL_GLOBAL_ALL); - if(res) { + if(res != CURLE_OK) { fclose(hd_src); return res; } @@ -300,15 +297,15 @@ CURLcode test(char *URL) multi_init(m); - multi_setopt(m, CURLMOPT_SOCKETFUNCTION, curlSocketCallback); + multi_setopt(m, CURLMOPT_SOCKETFUNCTION, t582_curlSocketCallback); multi_setopt(m, CURLMOPT_SOCKETDATA, &sockets); - multi_setopt(m, CURLMOPT_TIMERFUNCTION, curlTimerCallback); + multi_setopt(m, CURLMOPT_TIMERFUNCTION, t582_curlTimerCallback); multi_setopt(m, CURLMOPT_TIMERDATA, &timeout); multi_add_handle(m, curl); - while(!checkForCompletion(m, &success)) { + while(!t582_checkForCompletion(m, &success)) { fd_set readSet, writeSet; curl_socket_t maxFd = 0; struct timeval tv = {0}; @@ -316,11 +313,11 @@ CURLcode test(char *URL) FD_ZERO(&readSet); FD_ZERO(&writeSet); - updateFdSet(&sockets.read, &readSet, &maxFd); - updateFdSet(&sockets.write, &writeSet, &maxFd); + t582_updateFdSet(&sockets.read, &readSet, &maxFd); + t582_updateFdSet(&sockets.write, &writeSet, &maxFd); if(timeout.tv_sec != (time_t)-1) { - int usTimeout = getMicroSecondTimeout(&timeout); + int usTimeout = curlx_sztosi(t582_getMicroSecondTimeout(&timeout)); tv.tv_sec = usTimeout / 1000000; tv.tv_usec = usTimeout % 1000000; } @@ -332,10 +329,11 @@ CURLcode test(char *URL) select_test((int)maxFd, &readSet, &writeSet, NULL, &tv); /* Check the sockets for reading / writing */ - checkFdSet(m, &sockets.read, &readSet, CURL_CSELECT_IN, "read"); - checkFdSet(m, &sockets.write, &writeSet, CURL_CSELECT_OUT, "write"); + t582_checkFdSet(m, &sockets.read, &readSet, CURL_CSELECT_IN, "read"); + t582_checkFdSet(m, &sockets.write, &writeSet, CURL_CSELECT_OUT, "write"); - if(timeout.tv_sec != (time_t)-1 && getMicroSecondTimeout(&timeout) == 0) { + if(timeout.tv_sec != (time_t)-1 && + t582_getMicroSecondTimeout(&timeout) == 0) { /* Curl's timer has elapsed. */ notifyCurl(m, CURL_SOCKET_TIMEOUT, 0, "timeout"); } diff --git a/vendor/curl/tests/libtest/lib583.c b/vendor/curl/tests/libtest/lib583.c index 8ddcaa31721..9950e8b402b 100644 --- a/vendor/curl/tests/libtest/lib583.c +++ b/vendor/curl/tests/libtest/lib583.c @@ -26,13 +26,11 @@ * https://curl.se/mail/lib-2011-03/0066.html */ -#include "test.h" - -#include +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib583(const char *URL) { int stillRunning; CURLM *multiHandle = NULL; @@ -56,7 +54,7 @@ CURLcode test(char *URL) easy_setopt(curl, CURLOPT_VERBOSE, 1L); easy_setopt(curl, CURLOPT_URL, URL); - easy_setopt(curl, CURLOPT_INFILESIZE, (long)5); + easy_setopt(curl, CURLOPT_INFILESIZE, 5L); multi_add_handle(multiHandle, curl); @@ -72,8 +70,8 @@ CURLcode test(char *URL) curl_mfprintf(stderr, "curl_multi_remove_handle()...\n"); mres = curl_multi_remove_handle(multiHandle, curl); if(mres) { - curl_mfprintf(stderr, "curl_multi_remove_handle() failed, " - "with code %d\n", (int)mres); + curl_mfprintf(stderr, "curl_multi_remove_handle() failed, with code %d\n", + mres); res = TEST_ERR_MULTI; } else diff --git a/vendor/curl/tests/libtest/lib586.c b/vendor/curl/tests/libtest/lib586.c index 2712df74f7f..439c92bf352 100644 --- a/vendor/curl/tests/libtest/lib586.c +++ b/vendor/curl/tests/libtest/lib586.c @@ -21,28 +21,29 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" + #include "memdebug.h" #define THREADS 2 /* struct containing data of a thread */ -struct Tdata { +struct t586_Tdata { CURLSH *share; - char *url; + const char *url; }; -struct userdata { +struct t586_userdata { const char *text; int counter; }; /* lock callback */ -static void test_lock(CURL *handle, curl_lock_data data, - curl_lock_access laccess, void *useptr) +static void t586_test_lock(CURL *handle, curl_lock_data data, + curl_lock_access laccess, void *useptr) { const char *what; - struct userdata *user = (struct userdata *)useptr; + struct t586_userdata *user = (struct t586_userdata *)useptr; (void)handle; (void)laccess; @@ -61,7 +62,7 @@ static void test_lock(CURL *handle, curl_lock_data data, what = "ssl_session"; break; default: - curl_mfprintf(stderr, "lock: no such data: %d\n", (int)data); + curl_mfprintf(stderr, "lock: no such data: %d\n", data); return; } curl_mprintf("lock: %-6s [%s]: %d\n", what, user->text, user->counter); @@ -69,10 +70,10 @@ static void test_lock(CURL *handle, curl_lock_data data, } /* unlock callback */ -static void test_unlock(CURL *handle, curl_lock_data data, void *useptr) +static void t586_test_unlock(CURL *handle, curl_lock_data data, void *useptr) { const char *what; - struct userdata *user = (struct userdata *)useptr; + struct t586_userdata *user = (struct t586_userdata *)useptr; (void)handle; switch(data) { case CURL_LOCK_DATA_SHARE: @@ -88,7 +89,7 @@ static void test_unlock(CURL *handle, curl_lock_data data, void *useptr) what = "ssl_session"; break; default: - curl_mfprintf(stderr, "unlock: no such data: %d\n", (int)data); + curl_mfprintf(stderr, "unlock: no such data: %d\n", data); return; } curl_mprintf("unlock: %-6s [%s]: %d\n", what, user->text, user->counter); @@ -96,10 +97,10 @@ static void test_unlock(CURL *handle, curl_lock_data data, void *useptr) } /* the dummy thread function */ -static void *test_fire(void *ptr) +static void *t586_test_fire(void *ptr) { CURLcode code; - struct Tdata *tdata = (struct Tdata*)ptr; + struct t586_Tdata *tdata = (struct t586_Tdata*)ptr; CURL *curl; curl = curl_easy_init(); @@ -119,7 +120,7 @@ static void *test_fire(void *ptr) if(code != CURLE_OK) { int i = 0; curl_mfprintf(stderr, "perform url '%s' repeat %d failed, curlcode %d\n", - tdata->url, i, (int)code); + tdata->url, i, code); } curl_mprintf("CLEANUP\n"); @@ -129,16 +130,15 @@ static void *test_fire(void *ptr) } /* test function */ -CURLcode test(char *URL) +static CURLcode test_lib586(const char *URL) { CURLcode res = CURLE_OK; CURLSHcode scode = CURLSHE_OK; - char *url; - struct Tdata tdata; + struct t586_Tdata tdata; CURL *curl; CURLSH *share; int i; - struct userdata user; + struct t586_userdata user; user.text = "Pigs in space"; user.counter = 0; @@ -160,11 +160,11 @@ CURLcode test(char *URL) if(CURLSHE_OK == scode) { curl_mprintf("CURLSHOPT_LOCKFUNC\n"); - scode = curl_share_setopt(share, CURLSHOPT_LOCKFUNC, test_lock); + scode = curl_share_setopt(share, CURLSHOPT_LOCKFUNC, t586_test_lock); } if(CURLSHE_OK == scode) { curl_mprintf("CURLSHOPT_UNLOCKFUNC\n"); - scode = curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, test_unlock); + scode = curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, t586_test_unlock); } if(CURLSHE_OK == scode) { curl_mprintf("CURLSHOPT_USERDATA\n"); @@ -193,7 +193,7 @@ CURLcode test(char *URL) /* simulate thread, direct call of "thread" function */ curl_mprintf("*** run %d\n",i); - test_fire(&tdata); + t586_test_fire(&tdata); } @@ -207,8 +207,7 @@ CURLcode test(char *URL) return TEST_ERR_MAJOR_BAD; } - url = URL; - test_setopt(curl, CURLOPT_URL, url); + test_setopt(curl, CURLOPT_URL, URL); curl_mprintf("CURLOPT_SHARE\n"); test_setopt(curl, CURLOPT_SHARE, share); @@ -237,7 +236,7 @@ CURLcode test(char *URL) scode = curl_share_cleanup(share); if(scode != CURLSHE_OK) curl_mfprintf(stderr, "curl_share_cleanup failed, code errno %d\n", - (int)scode); + scode); curl_mprintf("GLOBAL_CLEANUP\n"); curl_global_cleanup(); diff --git a/vendor/curl/tests/libtest/lib589.c b/vendor/curl/tests/libtest/lib589.c index d2faa5f00df..9b912ab037d 100644 --- a/vendor/curl/tests/libtest/lib589.c +++ b/vendor/curl/tests/libtest/lib589.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib589(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; @@ -47,8 +47,7 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_VERBOSE, 1L); /* show verbose for debug */ test_setopt(curl, CURLOPT_HEADER, 1L); /* include header */ -#ifdef LIB584 - { + if(testnum == 584) { curl_mime *mime = curl_mime_init(curl); curl_mimepart *part = curl_mime_addpart(mime); curl_mime_name(part, "fake"); @@ -59,7 +58,6 @@ CURLcode test(char *URL) if(res) goto test_cleanup; } -#endif test_setopt(curl, CURLOPT_MIMEPOST, NULL); diff --git a/vendor/curl/tests/libtest/lib590.c b/vendor/curl/tests/libtest/lib590.c index caa50ffce3f..c804f995dee 100644 --- a/vendor/curl/tests/libtest/lib590.c +++ b/vendor/curl/tests/libtest/lib590.c @@ -21,7 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" /* Based on a bug report recipe by Rene Bernhardt in @@ -29,16 +29,17 @@ It is reproducible by the following steps: - - Use a proxy that offers NTLM and Negotiate ( CURLOPT_PROXY and - CURLOPT_PROXYPORT) - - Tell libcurl NOT to use Negotiate CURL_EASY_SETOPT(CURLOPT_PROXYAUTH, - CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_NTLM) + - Use a proxy that offers NTLM and Negotiate + (CURLOPT_PROXY and CURLOPT_PROXYPORT) + - Tell libcurl NOT to use Negotiate + curl_easy_setopt(CURLOPT_PROXYAUTH, + CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_NTLM) - Start the request */ #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib590(const char *URL) { CURLcode res; CURL *curl; @@ -59,7 +60,7 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_URL, URL); test_setopt(curl, CURLOPT_HEADER, 1L); test_setopt(curl, CURLOPT_PROXYAUTH, - (long) (CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_NTLM)); + CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_NTLM); test_setopt(curl, CURLOPT_PROXY, libtest_arg2); /* set in first.c */ /* set the name + password twice to test that the API is fine with it */ diff --git a/vendor/curl/tests/libtest/lib591.c b/vendor/curl/tests/libtest/lib591.c index ce2b855a412..1f09fbdc4d1 100644 --- a/vendor/curl/tests/libtest/lib591.c +++ b/vendor/curl/tests/libtest/lib591.c @@ -21,21 +21,13 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" - /* lib591 is used for test cases 591, 592, 593 and 594 */ -#include - -#include +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - -CURLcode test(char *URL) +static CURLcode test_lib591(const char *URL) { CURL *easy = NULL; CURLM *multi = NULL; @@ -50,7 +42,7 @@ CURLcode test(char *URL) upload = fopen(libtest_arg3, "rb"); if(!upload) { curl_mfprintf(stderr, "fopen() failed with error (%d) %s\n", - errno, strerror(errno)); + errno, strerror(errno)); curl_mfprintf(stderr, "Error opening file '%s'\n", libtest_arg3); return TEST_ERR_FOPEN; } diff --git a/vendor/curl/tests/libtest/lib597.c b/vendor/curl/tests/libtest/lib597.c index 71535b041d3..126ce74f385 100644 --- a/vendor/curl/tests/libtest/lib597.c +++ b/vendor/curl/tests/libtest/lib597.c @@ -21,16 +21,10 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include - -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - /* * Test case for below scenario: * - Connect to an FTP server using CONNECT_ONLY option @@ -40,7 +34,7 @@ * with function curl_multi_info_read(). */ -CURLcode test(char *URL) +static CURLcode test_lib597(const char *URL) { CURL *easy = NULL; CURLM *multi = NULL; diff --git a/vendor/curl/tests/libtest/lib598.c b/vendor/curl/tests/libtest/lib598.c index 96d6662769c..56330c4a244 100644 --- a/vendor/curl/tests/libtest/lib598.c +++ b/vendor/curl/tests/libtest/lib598.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib598(const char *URL) { CURLcode res; CURL *curl; diff --git a/vendor/curl/tests/libtest/lib599.c b/vendor/curl/tests/libtest/lib599.c index d9ee121daf1..5b52698a29f 100644 --- a/vendor/curl/tests/libtest/lib599.c +++ b/vendor/curl/tests/libtest/lib599.c @@ -21,12 +21,12 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -static int progress_callback(void *clientp, double dltotal, - double dlnow, double ultotal, double ulnow) +static int t599_progress_callback(void *clientp, double dltotal, + double dlnow, double ultotal, double ulnow) { (void)clientp; (void)ulnow; @@ -41,7 +41,7 @@ static int progress_callback(void *clientp, double dltotal, return 0; } -CURLcode test(char *URL) +static CURLcode test_lib599(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; @@ -64,7 +64,7 @@ CURLcode test(char *URL) /* we want to use our own progress function */ test_setopt(curl, CURLOPT_NOPROGRESS, 0L); - test_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback); + test_setopt(curl, CURLOPT_PROGRESSFUNCTION, t599_progress_callback); /* get verbose debug output please */ test_setopt(curl, CURLOPT_VERBOSE, 1L); diff --git a/vendor/curl/tests/libtest/lib643.c b/vendor/curl/tests/libtest/lib643.c index 49ab41bb12d..612f0b566c8 100644 --- a/vendor/curl/tests/libtest/lib643.c +++ b/vendor/curl/tests/libtest/lib643.c @@ -21,33 +21,31 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -static char testdata[]= - "dummy\n"; - -struct WriteThis { - char *readptr; +struct t643_WriteThis { + const char *readptr; curl_off_t sizeleft; }; -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) +static size_t t643_read_cb(char *ptr, size_t size, size_t nmemb, void *userp) { - struct WriteThis *pooh = (struct WriteThis *)userp; + struct t643_WriteThis *pooh = (struct t643_WriteThis *)userp; int eof; if(size*nmemb < 1) return 0; -#ifdef LIB645 - eof = !*pooh->readptr; -#else - eof = pooh->sizeleft <= 0; - if(!eof) - pooh->sizeleft--; -#endif + if(testnum == 643) { + eof = pooh->sizeleft <= 0; + if(!eof) + pooh->sizeleft--; + } + else { + eof = !*pooh->readptr; + } if(!eof) { *ptr = *pooh->readptr; /* copy one single byte */ @@ -55,24 +53,25 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) return 1; /* we return 1 byte at a time! */ } - return 0; /* no more data left to deliver */ + return 0; /* no more data left to deliver */ } -static CURLcode test_once(char *URL, bool oldstyle) +static CURLcode t643_test_once(const char *URL, bool oldstyle) { + static const char testdata[] = "dummy\n"; + CURL *curl; CURLcode res = CURLE_OK; curl_mime *mime = NULL; curl_mimepart *part = NULL; - struct WriteThis pooh; - struct WriteThis pooh2; + struct t643_WriteThis pooh; + struct t643_WriteThis pooh2; curl_off_t datasize = -1; pooh.readptr = testdata; -#ifndef LIB645 - datasize = (curl_off_t)strlen(testdata); -#endif + if(testnum == 643) + datasize = (curl_off_t)strlen(testdata); pooh.sizeleft = datasize; curl = curl_easy_init(); @@ -103,7 +102,7 @@ static CURLcode test_once(char *URL, bool oldstyle) if(oldstyle) { res = curl_mime_name(part, "sendfile"); if(!res) - res = curl_mime_data_cb(part, datasize, read_callback, + res = curl_mime_data_cb(part, datasize, t643_read_cb, NULL, NULL, &pooh); if(!res) res = curl_mime_filename(part, "postit2.c"); @@ -112,7 +111,7 @@ static CURLcode test_once(char *URL, bool oldstyle) /* new style */ res = curl_mime_name(part, "sendfile alternative"); if(!res) - res = curl_mime_data_cb(part, datasize, read_callback, + res = curl_mime_data_cb(part, datasize, t643_read_cb, NULL, NULL, &pooh); if(!res) res = curl_mime_filename(part, "file name 2"); @@ -125,9 +124,8 @@ static CURLcode test_once(char *URL, bool oldstyle) a file upload but still using the callback */ pooh2.readptr = testdata; -#ifndef LIB645 - datasize = (curl_off_t)strlen(testdata); -#endif + if(testnum == 643) + datasize = (curl_off_t)strlen(testdata); pooh2.sizeleft = datasize; part = curl_mime_addpart(mime); @@ -141,7 +139,7 @@ static CURLcode test_once(char *URL, bool oldstyle) /* Fill in the file upload part */ res = curl_mime_name(part, "callbackdata"); if(!res) - res = curl_mime_data_cb(part, datasize, read_callback, + res = curl_mime_data_cb(part, datasize, t643_read_cb, NULL, NULL, &pooh2); if(res) @@ -225,7 +223,7 @@ static CURLcode test_once(char *URL, bool oldstyle) return res; } -static CURLcode cyclic_add(void) +static CURLcode t643_cyclic_add(void) { CURL *easy = curl_easy_init(); curl_mime *mime = curl_mime_init(easy); @@ -249,7 +247,7 @@ static CURLcode cyclic_add(void) return CURLE_OK; } -CURLcode test(char *URL) +static CURLcode test_lib643(const char *URL) { CURLcode res; @@ -258,12 +256,12 @@ CURLcode test(char *URL) return TEST_ERR_MAJOR_BAD; } - res = test_once(URL, TRUE); /* old */ + res = t643_test_once(URL, TRUE); /* old */ if(!res) - res = test_once(URL, FALSE); /* new */ + res = t643_test_once(URL, FALSE); /* new */ if(!res) - res = cyclic_add(); + res = t643_cyclic_add(); curl_global_cleanup(); diff --git a/vendor/curl/tests/libtest/lib650.c b/vendor/curl/tests/libtest/lib650.c index 59f5ba925e8..069e94f8e5c 100644 --- a/vendor/curl/tests/libtest/lib650.c +++ b/vendor/curl/tests/libtest/lib650.c @@ -21,17 +21,10 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" - -static char testdata[] = - "this is what we post to the silly web server"; - -static const char testname[] = "fieldname"; - - /* This test attempts to use all form API features that are not * used elsewhere. */ @@ -41,13 +34,12 @@ static size_t count_chars(void *userp, const char *buf, size_t len) { size_t *pcounter = (size_t *) userp; - (void) buf; + (void)buf; *pcounter += len; return len; } - -CURLcode test(char *URL) +static CURLcode test_lib650(const char *URL) { CURL *curl = NULL; CURLcode res = TEST_ERR_MAJOR_BAD; @@ -60,6 +52,10 @@ CURLcode test(char *URL) char flbuf[32]; long contentlength = 0; + static const char testname[] = "fieldname"; + static char testdata[] = + "this is what we post to the silly web server"; + if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { curl_mfprintf(stderr, "curl_global_init() failed\n"); return TEST_ERR_MAJOR_BAD; @@ -86,7 +82,7 @@ CURLcode test(char *URL) CURLFORM_CONTENTHEADER, headers, CURLFORM_END); if(formrc) { - curl_mprintf("curl_formadd(1) = %d\n", (int) formrc); + curl_mprintf("curl_formadd(1) = %d\n", formrc); goto test_cleanup; } @@ -108,7 +104,7 @@ CURLcode test(char *URL) CURLFORM_END); if(formrc) { - curl_mprintf("curl_formadd(2) = %d\n", (int) formrc); + curl_mprintf("curl_formadd(2) = %d\n", formrc); goto test_cleanup; } @@ -128,7 +124,7 @@ CURLcode test(char *URL) CURLFORM_END); if(formrc) { - curl_mprintf("curl_formadd(3) = %d\n", (int) formrc); + curl_mprintf("curl_formadd(3) = %d\n", formrc); goto test_cleanup; } @@ -139,7 +135,7 @@ CURLcode test(char *URL) CURLFORM_FILECONTENT, libtest_arg2, CURLFORM_END); if(formrc) { - curl_mprintf("curl_formadd(4) = %d\n", (int) formrc); + curl_mprintf("curl_formadd(4) = %d\n", formrc); goto test_cleanup; } @@ -150,7 +146,7 @@ CURLcode test(char *URL) curl_formget(formpost, (void *) &formlength, count_chars); /* Include length in data for external check. */ - curl_msnprintf(flbuf, sizeof(flbuf), "%lu", (unsigned long) formlength); + curl_msnprintf(flbuf, sizeof(flbuf), "%zu", formlength); formrc = curl_formadd(&formpost, &lastptr, @@ -159,7 +155,7 @@ CURLcode test(char *URL) CURLFORM_END); if(formrc) { - curl_mprintf("curl_formadd(5) = %d\n", (int) formrc); + curl_mprintf("curl_formadd(5) = %d\n", formrc); goto test_cleanup; } @@ -171,7 +167,7 @@ CURLcode test(char *URL) CURLFORM_END); if(formrc) { - curl_mprintf("curl_formadd(6) = %d\n", (int) formrc); + curl_mprintf("curl_formadd(6) = %d\n", formrc); goto test_cleanup; } @@ -191,7 +187,7 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_VERBOSE, 1L); test_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - test_setopt(curl, CURLOPT_POSTREDIR, (long)CURL_REDIR_POST_301); + test_setopt(curl, CURLOPT_POSTREDIR, CURL_REDIR_POST_301); /* include headers in the output */ test_setopt(curl, CURLOPT_HEADER, 1L); diff --git a/vendor/curl/tests/libtest/lib651.c b/vendor/curl/tests/libtest/lib651.c index 856ccd123dd..05e9e381da9 100644 --- a/vendor/curl/tests/libtest/lib651.c +++ b/vendor/curl/tests/libtest/lib651.c @@ -21,14 +21,14 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -static char testbuf[17000]; /* more than 16K */ - -CURLcode test(char *URL) +static CURLcode test_lib651(const char *URL) { + static char testbuf[17000]; /* more than 16K */ + CURL *curl; CURLcode res = CURLE_OK; CURLFORMcode formrc; @@ -55,7 +55,7 @@ CURLcode test(char *URL) CURLFORM_COPYCONTENTS, testbuf, CURLFORM_END); if(formrc) - curl_mprintf("curl_formadd(1) = %d\n", (int) formrc); + curl_mprintf("curl_formadd(1) = %d\n", formrc); curl = curl_easy_init(); diff --git a/vendor/curl/tests/libtest/lib652.c b/vendor/curl/tests/libtest/lib652.c index d6be151b184..dcbc5a3ab3f 100644 --- a/vendor/curl/tests/libtest/lib652.c +++ b/vendor/curl/tests/libtest/lib652.c @@ -21,14 +21,14 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -static char testbuf[17000]; /* more than 16K */ - -CURLcode test(char *URL) +static CURLcode test_lib652(const char *URL) { + static char testbuf[17000]; /* more than 16K */ + CURL *curl = NULL; CURLcode res = CURLE_OK; curl_mime *mime = NULL; diff --git a/vendor/curl/tests/libtest/lib653.c b/vendor/curl/tests/libtest/lib653.c index a1be0df1606..4f20865e269 100644 --- a/vendor/curl/tests/libtest/lib653.c +++ b/vendor/curl/tests/libtest/lib653.c @@ -21,14 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" - -CURLcode test(char *URL) +static CURLcode test_lib653(const char *URL) { CURL *curls = NULL; CURLcode res = CURLE_OK; diff --git a/vendor/curl/tests/libtest/lib654.c b/vendor/curl/tests/libtest/lib654.c index 6a2daee3d9b..a808e24a0ac 100644 --- a/vendor/curl/tests/libtest/lib654.c +++ b/vendor/curl/tests/libtest/lib654.c @@ -21,29 +21,26 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -static char testdata[]= - "dummy\n"; - -struct WriteThis { - char *readptr; +struct t654_WriteThis { + const char *readptr; curl_off_t sizeleft; int freecount; }; static void free_callback(void *userp) { - struct WriteThis *pooh = (struct WriteThis *) userp; + struct t654_WriteThis *pooh = (struct t654_WriteThis *) userp; pooh->freecount++; } -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) +static size_t t654_read_cb(char *ptr, size_t size, size_t nmemb, void *userp) { - struct WriteThis *pooh = (struct WriteThis *)userp; + struct t654_WriteThis *pooh = (struct t654_WriteThis *)userp; int eof; if(size*nmemb < 1) @@ -62,15 +59,17 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) return 0; /* no more data left to deliver */ } -CURLcode test(char *URL) +static CURLcode test_lib654(const char *URL) { + static const char testdata[] = "dummy\n"; + CURL *easy = NULL; CURL *easy2 = NULL; curl_mime *mime = NULL; curl_mimepart *part; struct curl_slist *hdrs = NULL; CURLcode res = TEST_ERR_FAILURE; - struct WriteThis pooh; + struct t654_WriteThis pooh; /* * Check proper copy/release of mime post data bound to a duplicated @@ -110,8 +109,8 @@ CURLcode test(char *URL) part = curl_mime_addpart(mime); curl_mime_filedata(part, libtest_arg2); part = curl_mime_addpart(mime); - curl_mime_data_cb(part, (curl_off_t) -1, read_callback, NULL, free_callback, - &pooh); + curl_mime_data_cb(part, (curl_off_t) -1, t654_read_cb, NULL, + free_callback, &pooh); /* Bind mime data to its easy handle. */ test_setopt(easy, CURLOPT_MIMEPOST, mime); @@ -152,7 +151,7 @@ CURLcode test(char *URL) if(pooh.freecount != 2) { curl_mfprintf(stderr, "free_callback() called %d times instead of 2\n", - pooh.freecount); + pooh.freecount); res = TEST_ERR_FAILURE; goto test_cleanup; } diff --git a/vendor/curl/tests/libtest/lib655.c b/vendor/curl/tests/libtest/lib655.c index adb3313c948..07392cbd86b 100644 --- a/vendor/curl/tests/libtest/lib655.c +++ b/vendor/curl/tests/libtest/lib655.c @@ -21,15 +21,15 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" static const char *TEST_DATA_STRING = "Test data"; static int cb_count = 0; -static int -resolver_alloc_cb_fail(void *resolver_state, void *reserved, void *userdata) +static int resolver_alloc_cb_fail(void *resolver_state, void *reserved, + void *userdata) { (void)resolver_state; (void)reserved; @@ -43,8 +43,8 @@ resolver_alloc_cb_fail(void *resolver_state, void *reserved, void *userdata) return 1; } -static int -resolver_alloc_cb_pass(void *resolver_state, void *reserved, void *userdata) +static int resolver_alloc_cb_pass(void *resolver_state, void *reserved, + void *userdata) { (void)resolver_state; (void)reserved; @@ -58,7 +58,7 @@ resolver_alloc_cb_pass(void *resolver_state, void *reserved, void *userdata) return 0; } -CURLcode test(char *URL) +static CURLcode test_lib655(const char *URL) { CURL *curl; CURLcode res = CURLE_OK; @@ -74,7 +74,7 @@ CURLcode test(char *URL) goto test_cleanup; } - /* First set the URL that is about to receive our request. */ + /* Set the URL that is about to receive our first request. */ test_setopt(curl, CURLOPT_URL, URL); test_setopt(curl, CURLOPT_RESOLVER_START_DATA, TEST_DATA_STRING); @@ -84,12 +84,16 @@ CURLcode test(char *URL) res = curl_easy_perform(curl); if(res != CURLE_COULDNT_RESOLVE_HOST) { curl_mfprintf(stderr, "curl_easy_perform should have returned " - "CURLE_COULDNT_RESOLVE_HOST but instead returned error %d\n", res); + "CURLE_COULDNT_RESOLVE_HOST but instead returned error %d\n", + res); if(res == CURLE_OK) res = TEST_ERR_FAILURE; goto test_cleanup; } + /* Set the URL that receives our second request. */ + test_setopt(curl, CURLOPT_URL, libtest_arg2); + test_setopt(curl, CURLOPT_RESOLVER_START_FUNCTION, resolver_alloc_cb_pass); /* this should succeed */ diff --git a/vendor/curl/tests/libtest/lib658.c b/vendor/curl/tests/libtest/lib658.c index 6254d528c51..00a2a35906b 100644 --- a/vendor/curl/tests/libtest/lib658.c +++ b/vendor/curl/tests/libtest/lib658.c @@ -21,17 +21,15 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" /* * Get a single URL without select(). */ -CURLcode test(char *URL) +static CURLcode test_lib658(const char *URL) { CURL *handle = NULL; CURLcode res = CURLE_OK; @@ -51,7 +49,7 @@ CURLcode test(char *URL) uc = curl_url_set(urlp, CURLUPART_URL, URL, 0); if(uc) { curl_mfprintf(stderr, "problem setting CURLUPART_URL: %s.", - curl_url_strerror(uc)); + curl_url_strerror(uc)); goto test_cleanup; } diff --git a/vendor/curl/tests/libtest/lib659.c b/vendor/curl/tests/libtest/lib659.c index c14173db43f..70a630758c1 100644 --- a/vendor/curl/tests/libtest/lib659.c +++ b/vendor/curl/tests/libtest/lib659.c @@ -21,17 +21,15 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" /* * Get a single URL without select(). */ -CURLcode test(char *URL) +static CURLcode test_lib659(const char *URL) { CURL *handle = NULL; CURLcode res = CURLE_OK; diff --git a/vendor/curl/tests/libtest/lib661.c b/vendor/curl/tests/libtest/lib661.c index 170237671a8..10a4ab99cee 100644 --- a/vendor/curl/tests/libtest/lib661.c +++ b/vendor/curl/tests/libtest/lib661.c @@ -21,148 +21,148 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" + #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib661(const char *URL) { - CURLcode res; - CURL *curl = NULL; - char *newURL = NULL; - struct curl_slist *slist = NULL; - - if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { - curl_mfprintf(stderr, "curl_global_init() failed\n"); - return TEST_ERR_MAJOR_BAD; - } - - curl = curl_easy_init(); - if(!curl) { - curl_mfprintf(stderr, "curl_easy_init() failed\n"); - res = TEST_ERR_MAJOR_BAD; - goto test_cleanup; - } - - /* test: CURLFTPMETHOD_SINGLECWD with absolute path should - skip CWD to entry path */ - newURL = curl_maprintf("%s/folderA/661", URL); - test_setopt(curl, CURLOPT_URL, newURL); - test_setopt(curl, CURLOPT_VERBOSE, 1L); - test_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, 1L); - test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_SINGLECWD); - res = curl_easy_perform(curl); - if(res != CURLE_REMOTE_FILE_NOT_FOUND) - goto test_cleanup; - - curl_free(newURL); - newURL = curl_maprintf("%s/folderB/661", URL); - test_setopt(curl, CURLOPT_URL, newURL); - res = curl_easy_perform(curl); - if(res != CURLE_REMOTE_FILE_NOT_FOUND) - goto test_cleanup; - - /* test: CURLFTPMETHOD_NOCWD with absolute path should - never emit CWD (for both new and reused easy handle) */ - curl_easy_cleanup(curl); - curl = curl_easy_init(); - if(!curl) { - curl_mfprintf(stderr, "curl_easy_init() failed\n"); - res = TEST_ERR_MAJOR_BAD; - goto test_cleanup; - } - - curl_free(newURL); - newURL = curl_maprintf("%s/folderA/661", URL); - test_setopt(curl, CURLOPT_URL, newURL); - test_setopt(curl, CURLOPT_VERBOSE, 1L); - test_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, 1L); - test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_NOCWD); - res = curl_easy_perform(curl); - if(res != CURLE_REMOTE_FILE_NOT_FOUND) - goto test_cleanup; - - /* curve ball: CWD /folderB before reusing connection with _NOCWD */ - curl_free(newURL); - newURL = curl_maprintf("%s/folderB/661", URL); - test_setopt(curl, CURLOPT_URL, newURL); - test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_SINGLECWD); - res = curl_easy_perform(curl); - if(res != CURLE_REMOTE_FILE_NOT_FOUND) - goto test_cleanup; - - curl_free(newURL); - newURL = curl_maprintf("%s/folderA/661", URL); - test_setopt(curl, CURLOPT_URL, newURL); - test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_NOCWD); - res = curl_easy_perform(curl); - if(res != CURLE_REMOTE_FILE_NOT_FOUND) - goto test_cleanup; - - /* test: CURLFTPMETHOD_NOCWD with home-relative path should - not emit CWD for first FTP access after login */ - curl_easy_cleanup(curl); - curl = curl_easy_init(); - if(!curl) { - curl_mfprintf(stderr, "curl_easy_init() failed\n"); - res = TEST_ERR_MAJOR_BAD; - goto test_cleanup; - } - - slist = curl_slist_append(NULL, "SYST"); - if(!slist) { - curl_mfprintf(stderr, "curl_slist_append() failed\n"); - res = TEST_ERR_MAJOR_BAD; - goto test_cleanup; - } - - test_setopt(curl, CURLOPT_URL, URL); - test_setopt(curl, CURLOPT_VERBOSE, 1L); - test_setopt(curl, CURLOPT_NOBODY, 1L); - test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_NOCWD); - test_setopt(curl, CURLOPT_QUOTE, slist); - res = curl_easy_perform(curl); - if(res) - goto test_cleanup; - - /* test: CURLFTPMETHOD_SINGLECWD with home-relative path should - not emit CWD for first FTP access after login */ - curl_easy_cleanup(curl); - curl = curl_easy_init(); - if(!curl) { - curl_mfprintf(stderr, "curl_easy_init() failed\n"); - res = TEST_ERR_MAJOR_BAD; - goto test_cleanup; - } - - test_setopt(curl, CURLOPT_URL, URL); - test_setopt(curl, CURLOPT_VERBOSE, 1L); - test_setopt(curl, CURLOPT_NOBODY, 1L); - test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_SINGLECWD); - test_setopt(curl, CURLOPT_QUOTE, slist); - res = curl_easy_perform(curl); - if(res) - goto test_cleanup; - - /* test: CURLFTPMETHOD_NOCWD with home-relative path should - not emit CWD for second FTP access when not needed + - bonus: see if path buffering survives curl_easy_reset() */ - curl_easy_reset(curl); - test_setopt(curl, CURLOPT_URL, URL); - test_setopt(curl, CURLOPT_VERBOSE, 1L); - test_setopt(curl, CURLOPT_NOBODY, 1L); - test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_NOCWD); - test_setopt(curl, CURLOPT_QUOTE, slist); - res = curl_easy_perform(curl); - + CURLcode res; + CURL *curl = NULL; + char *newURL = NULL; + struct curl_slist *slist = NULL; + + if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + curl_mfprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + curl = curl_easy_init(); + if(!curl) { + curl_mfprintf(stderr, "curl_easy_init() failed\n"); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + + /* test: CURLFTPMETHOD_SINGLECWD with absolute path should + skip CWD to entry path */ + newURL = curl_maprintf("%s/folderA/661", URL); + test_setopt(curl, CURLOPT_URL, newURL); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, 1L); + test_setopt(curl, CURLOPT_FTP_FILEMETHOD, CURLFTPMETHOD_SINGLECWD); + res = curl_easy_perform(curl); + if(res != CURLE_REMOTE_FILE_NOT_FOUND) + goto test_cleanup; + + curl_free(newURL); + newURL = curl_maprintf("%s/folderB/661", URL); + test_setopt(curl, CURLOPT_URL, newURL); + res = curl_easy_perform(curl); + if(res != CURLE_REMOTE_FILE_NOT_FOUND) + goto test_cleanup; + + /* test: CURLFTPMETHOD_NOCWD with absolute path should + never emit CWD (for both new and reused easy handle) */ + curl_easy_cleanup(curl); + curl = curl_easy_init(); + if(!curl) { + curl_mfprintf(stderr, "curl_easy_init() failed\n"); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + + curl_free(newURL); + newURL = curl_maprintf("%s/folderA/661", URL); + test_setopt(curl, CURLOPT_URL, newURL); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, 1L); + test_setopt(curl, CURLOPT_FTP_FILEMETHOD, CURLFTPMETHOD_NOCWD); + res = curl_easy_perform(curl); + if(res != CURLE_REMOTE_FILE_NOT_FOUND) + goto test_cleanup; + + /* curve ball: CWD /folderB before reusing connection with _NOCWD */ + curl_free(newURL); + newURL = curl_maprintf("%s/folderB/661", URL); + test_setopt(curl, CURLOPT_URL, newURL); + test_setopt(curl, CURLOPT_FTP_FILEMETHOD, CURLFTPMETHOD_SINGLECWD); + res = curl_easy_perform(curl); + if(res != CURLE_REMOTE_FILE_NOT_FOUND) + goto test_cleanup; + + curl_free(newURL); + newURL = curl_maprintf("%s/folderA/661", URL); + test_setopt(curl, CURLOPT_URL, newURL); + test_setopt(curl, CURLOPT_FTP_FILEMETHOD, CURLFTPMETHOD_NOCWD); + res = curl_easy_perform(curl); + if(res != CURLE_REMOTE_FILE_NOT_FOUND) + goto test_cleanup; + + /* test: CURLFTPMETHOD_NOCWD with home-relative path should + not emit CWD for first FTP access after login */ + curl_easy_cleanup(curl); + curl = curl_easy_init(); + if(!curl) { + curl_mfprintf(stderr, "curl_easy_init() failed\n"); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + + slist = curl_slist_append(NULL, "SYST"); + if(!slist) { + curl_mfprintf(stderr, "curl_slist_append() failed\n"); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_NOBODY, 1L); + test_setopt(curl, CURLOPT_FTP_FILEMETHOD, CURLFTPMETHOD_NOCWD); + test_setopt(curl, CURLOPT_QUOTE, slist); + res = curl_easy_perform(curl); + if(res) + goto test_cleanup; + + /* test: CURLFTPMETHOD_SINGLECWD with home-relative path should + not emit CWD for first FTP access after login */ + curl_easy_cleanup(curl); + curl = curl_easy_init(); + if(!curl) { + curl_mfprintf(stderr, "curl_easy_init() failed\n"); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_NOBODY, 1L); + test_setopt(curl, CURLOPT_FTP_FILEMETHOD, CURLFTPMETHOD_SINGLECWD); + test_setopt(curl, CURLOPT_QUOTE, slist); + res = curl_easy_perform(curl); + if(res) + goto test_cleanup; + + /* test: CURLFTPMETHOD_NOCWD with home-relative path should + not emit CWD for second FTP access when not needed + + bonus: see if path buffering survives curl_easy_reset() */ + curl_easy_reset(curl); + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_NOBODY, 1L); + test_setopt(curl, CURLOPT_FTP_FILEMETHOD, CURLFTPMETHOD_NOCWD); + test_setopt(curl, CURLOPT_QUOTE, slist); + res = curl_easy_perform(curl); test_cleanup: - if(res) - curl_mfprintf(stderr, "test encountered error %d\n", res); - curl_slist_free_all(slist); - curl_free(newURL); - curl_easy_cleanup(curl); - curl_global_cleanup(); + if(res) + curl_mfprintf(stderr, "test encountered error %d\n", res); + curl_slist_free_all(slist); + curl_free(newURL); + curl_easy_cleanup(curl); + curl_global_cleanup(); - return res; + return res; } diff --git a/vendor/curl/tests/libtest/lib666.c b/vendor/curl/tests/libtest/lib666.c index 4d2df8e0f1e..cff244dafb1 100644 --- a/vendor/curl/tests/libtest/lib666.c +++ b/vendor/curl/tests/libtest/lib666.c @@ -21,14 +21,14 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -static char testbuf[17000]; /* more than 16K */ - -CURLcode test(char *URL) +static CURLcode test_lib666(const char *URL) { + static char testbuf[17000]; /* more than 16K */ + CURL *curl = NULL; CURLcode res = CURLE_OK; curl_mime *mime = NULL; diff --git a/vendor/curl/tests/libtest/lib667.c b/vendor/curl/tests/libtest/lib667.c index 70856fcaa87..a46d1b8cdd7 100644 --- a/vendor/curl/tests/libtest/lib667.c +++ b/vendor/curl/tests/libtest/lib667.c @@ -21,21 +21,18 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -static char testdata[]= - "dummy"; - -struct WriteThis { - char *readptr; +struct t667_WriteThis { + const char *readptr; curl_off_t sizeleft; }; -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) +static size_t t667_read_cb(char *ptr, size_t size, size_t nmemb, void *userp) { - struct WriteThis *pooh = (struct WriteThis *)userp; + struct t667_WriteThis *pooh = (struct t667_WriteThis *)userp; int eof; if(size*nmemb < 1) @@ -54,13 +51,15 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) return 0; /* no more data left to deliver */ } -CURLcode test(char *URL) +static CURLcode test_lib667(const char *URL) { + static const char testdata[] = "dummy"; + CURL *easy = NULL; curl_mime *mime = NULL; curl_mimepart *part; CURLcode res = TEST_ERR_FAILURE; - struct WriteThis pooh; + struct t667_WriteThis pooh; /* * Check proper handling of mime encoder feature when the part read callback @@ -93,7 +92,8 @@ CURLcode test(char *URL) curl_mime_name(part, "field"); curl_mime_encoder(part, "base64"); /* Using an undefined length forces chunked transfer. */ - curl_mime_data_cb(part, (curl_off_t) -1, read_callback, NULL, NULL, &pooh); + curl_mime_data_cb(part, (curl_off_t) -1, t667_read_cb, + NULL, NULL, &pooh); /* Bind mime data to its easy handle. */ test_setopt(easy, CURLOPT_MIMEPOST, mime); diff --git a/vendor/curl/tests/libtest/lib668.c b/vendor/curl/tests/libtest/lib668.c index ef000510b11..219fb8b1508 100644 --- a/vendor/curl/tests/libtest/lib668.c +++ b/vendor/curl/tests/libtest/lib668.c @@ -21,23 +21,21 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -static char testdata[]= "dummy"; - -struct WriteThis { - char *readptr; +struct t668_WriteThis { + const char *readptr; curl_off_t sizeleft; }; -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) +static size_t t668_read_cb(char *ptr, size_t size, size_t nmemb, void *userp) { - struct WriteThis *pooh = (struct WriteThis *)userp; + struct t668_WriteThis *pooh = (struct t668_WriteThis *)userp; size_t len = strlen(pooh->readptr); - (void) size; /* Always 1.*/ + (void)size; /* Always 1.*/ if(len > nmemb) len = nmemb; @@ -48,13 +46,15 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) return len; } -CURLcode test(char *URL) +static CURLcode test_lib668(const char *URL) { + static const char testdata[] = "dummy"; + CURL *easy = NULL; curl_mime *mime = NULL; curl_mimepart *part; CURLcode res = TEST_ERR_FAILURE; - struct WriteThis pooh1, pooh2; + struct t668_WriteThis pooh1, pooh2; /* * Check early end of part data detection. @@ -87,12 +87,13 @@ CURLcode test(char *URL) curl_mime_name(part, "field1"); /* Early end of data detection can be done because the data size is known. */ curl_mime_data_cb(part, (curl_off_t) strlen(testdata), - read_callback, NULL, NULL, &pooh1); + t668_read_cb, NULL, NULL, &pooh1); part = curl_mime_addpart(mime); curl_mime_name(part, "field2"); /* Using an undefined length forces chunked transfer and disables early end of data detection for this part. */ - curl_mime_data_cb(part, (curl_off_t) -1, read_callback, NULL, NULL, &pooh2); + curl_mime_data_cb(part, (curl_off_t) -1, t668_read_cb, + NULL, NULL, &pooh2); part = curl_mime_addpart(mime); curl_mime_name(part, "field3"); /* Regular file part sources early end of data can be detected because diff --git a/vendor/curl/tests/libtest/lib670.c b/vendor/curl/tests/libtest/lib670.c index 2b54eac2d26..9dcdd7fd45e 100644 --- a/vendor/curl/tests/libtest/lib670.c +++ b/vendor/curl/tests/libtest/lib670.c @@ -21,27 +21,21 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" - -#include +#include "first.h" #include "memdebug.h" #define PAUSE_TIME 5 - -static const char testname[] = "field"; - -struct ReadThis { +struct t670_ReadThis { CURL *easy; time_t origin; int count; }; - -static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) +static size_t t670_read_cb(char *ptr, size_t size, size_t nmemb, void *userp) { - struct ReadThis *pooh = (struct ReadThis *) userp; + struct t670_ReadThis *pooh = (struct t670_ReadThis *) userp; time_t delta; if(size * nmemb < 1) @@ -65,16 +59,16 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) exit(1); } -#if !defined(LIB670) && !defined(LIB672) -static int xferinfo(void *clientp, curl_off_t dltotal, curl_off_t dlnow, - curl_off_t ultotal, curl_off_t ulnow) +static int t670_xferinfo(void *clientp, + curl_off_t dltotal, curl_off_t dlnow, + curl_off_t ultotal, curl_off_t ulnow) { - struct ReadThis *pooh = (struct ReadThis *) clientp; + struct t670_ReadThis *pooh = (struct t670_ReadThis *) clientp; - (void) dltotal; - (void) dlnow; - (void) ultotal; - (void) ulnow; + (void)dltotal; + (void)dlnow; + (void)ultotal; + (void)ulnow; if(pooh->origin) { time_t delta = time(NULL) - pooh->origin; @@ -90,27 +84,15 @@ static int xferinfo(void *clientp, curl_off_t dltotal, curl_off_t dlnow, return 0; } -#endif -CURLcode test(char *URL) +static CURLcode test_lib670(const char *URL) { -#if defined(LIB670) || defined(LIB671) + static const char testname[] = "field"; + curl_mime *mime = NULL; - curl_mimepart *part; -#else - CURLFORMcode formrc; struct curl_httppost *formpost = NULL; - struct curl_httppost *lastptr = NULL; -#endif -#if defined(LIB670) || defined(LIB672) - CURLM *multi = NULL; - CURLMcode mres; - CURLMsg *msg; - int msgs_left; - int still_running = 0; -#endif - struct ReadThis pooh; + struct t670_ReadThis pooh; CURLcode res = TEST_ERR_FAILURE; /* @@ -135,121 +117,131 @@ CURLcode test(char *URL) /* include headers in the output */ test_setopt(pooh.easy, CURLOPT_HEADER, 1L); -#if defined(LIB670) || defined(LIB671) - /* Build the mime tree. */ - mime = curl_mime_init(pooh.easy); - part = curl_mime_addpart(mime); - res = curl_mime_name(part, testname); - if(res != CURLE_OK) { - curl_mfprintf(stderr, - "Something went wrong when building the mime structure: %d\n", - res); - goto test_cleanup; - } + if(testnum == 670 || testnum == 671) { + curl_mimepart *part; + /* Build the mime tree. */ + mime = curl_mime_init(pooh.easy); + part = curl_mime_addpart(mime); + res = curl_mime_name(part, testname); + if(res != CURLE_OK) { + curl_mfprintf(stderr, + "Something went wrong when building the mime structure: %d\n", + res); + goto test_cleanup; + } - res = curl_mime_data_cb(part, (curl_off_t) 2, read_callback, - NULL, NULL, &pooh); - - /* Bind mime data to its easy handle. */ - if(res == CURLE_OK) - test_setopt(pooh.easy, CURLOPT_MIMEPOST, mime); -#else - /* Build the form. */ - formrc = curl_formadd(&formpost, &lastptr, - CURLFORM_COPYNAME, testname, - CURLFORM_STREAM, &pooh, - CURLFORM_CONTENTLEN, (curl_off_t) 2, - CURLFORM_END); - if(formrc) { - curl_mfprintf(stderr, "curl_formadd() = %d\n", (int) formrc); - goto test_cleanup; + res = curl_mime_data_cb(part, (curl_off_t) 2, t670_read_cb, + NULL, NULL, &pooh); + + /* Bind mime data to its easy handle. */ + if(res == CURLE_OK) + test_setopt(pooh.easy, CURLOPT_MIMEPOST, mime); } + else { + struct curl_httppost *lastptr = NULL; + CURLFORMcode formrc; + /* Build the form. */ + formrc = curl_formadd(&formpost, &lastptr, + CURLFORM_COPYNAME, testname, + CURLFORM_STREAM, &pooh, + CURLFORM_CONTENTLEN, (curl_off_t) 2, + CURLFORM_END); + if(formrc) { + curl_mfprintf(stderr, "curl_formadd() = %d\n", formrc); + goto test_cleanup; + } - /* We want to use our own read function. */ - test_setopt(pooh.easy, CURLOPT_READFUNCTION, read_callback); + /* We want to use our own read function. */ + test_setopt(pooh.easy, CURLOPT_READFUNCTION, t670_read_cb); - /* Send a multi-part formpost. */ - test_setopt(pooh.easy, CURLOPT_HTTPPOST, formpost); -#endif + /* Send a multi-part formpost. */ + test_setopt(pooh.easy, CURLOPT_HTTPPOST, formpost); + } -#if defined(LIB670) || defined(LIB672) - /* Use the multi interface. */ - multi = curl_multi_init(); - mres = curl_multi_add_handle(multi, pooh.easy); - while(!mres) { - struct timeval timeout; - int rc = 0; - fd_set fdread; - fd_set fdwrite; - fd_set fdexcept; - int maxfd = -1; - - mres = curl_multi_perform(multi, &still_running); - if(!still_running || mres != CURLM_OK) - break; - - if(pooh.origin) { - time_t delta = time(NULL) - pooh.origin; - - if(delta >= 4 * PAUSE_TIME) { - curl_mfprintf(stderr, "unpausing failed: drain problem?\n"); - res = CURLE_OPERATION_TIMEDOUT; + if(testnum == 670 || testnum == 672) { + CURLMcode mres; + CURLM *multi; + /* Use the multi interface. */ + multi = curl_multi_init(); + mres = curl_multi_add_handle(multi, pooh.easy); + while(!mres) { + struct timeval timeout; + int rc = 0; + fd_set fdread; + fd_set fdwrite; + fd_set fdexcept; + int maxfd = -1; + int still_running = 0; + + mres = curl_multi_perform(multi, &still_running); + if(!still_running || mres != CURLM_OK) break; - } - if(delta >= PAUSE_TIME) - curl_easy_pause(pooh.easy, CURLPAUSE_CONT); - } + if(pooh.origin) { + time_t delta = time(NULL) - pooh.origin; - FD_ZERO(&fdread); - FD_ZERO(&fdwrite); - FD_ZERO(&fdexcept); - timeout.tv_sec = 0; - timeout.tv_usec = 1000000 * PAUSE_TIME / 10; - mres = curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcept, &maxfd); - if(mres) - break; + if(delta >= 4 * PAUSE_TIME) { + curl_mfprintf(stderr, "unpausing failed: drain problem?\n"); + res = CURLE_OPERATION_TIMEDOUT; + break; + } + + if(delta >= PAUSE_TIME) + curl_easy_pause(pooh.easy, CURLPAUSE_CONT); + } + + FD_ZERO(&fdread); + FD_ZERO(&fdwrite); + FD_ZERO(&fdexcept); + timeout.tv_sec = 0; + timeout.tv_usec = 1000000 * PAUSE_TIME / 10; + mres = curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcept, &maxfd); + if(mres) + break; #ifdef _WIN32 - if(maxfd == -1) - Sleep(100); - else + if(maxfd == -1) + curlx_wait_ms(100); + else #endif - rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcept, &timeout); - if(rc == -1) { - curl_mfprintf(stderr, "Select error\n"); - break; - } - } - - if(mres != CURLM_OK) - for(;;) { - msg = curl_multi_info_read(multi, &msgs_left); - if(!msg) + rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcept, &timeout); + if(rc == -1) { + curl_mfprintf(stderr, "Select error\n"); break; - if(msg->msg == CURLMSG_DONE) { - res = msg->data.result; } } - curl_multi_remove_handle(multi, pooh.easy); - curl_multi_cleanup(multi); - -#else - /* Use the easy interface. */ - test_setopt(pooh.easy, CURLOPT_XFERINFODATA, &pooh); - test_setopt(pooh.easy, CURLOPT_XFERINFOFUNCTION, xferinfo); - test_setopt(pooh.easy, CURLOPT_NOPROGRESS, 0L); - res = curl_easy_perform(pooh.easy); -#endif + if(mres != CURLM_OK) + for(;;) { + int msgs_left; + CURLMsg *msg; + msg = curl_multi_info_read(multi, &msgs_left); + if(!msg) + break; + if(msg->msg == CURLMSG_DONE) { + res = msg->data.result; + } + } + curl_multi_remove_handle(multi, pooh.easy); + curl_multi_cleanup(multi); + } + else { + /* Use the easy interface. */ + test_setopt(pooh.easy, CURLOPT_XFERINFODATA, &pooh); + test_setopt(pooh.easy, CURLOPT_XFERINFOFUNCTION, t670_xferinfo); + test_setopt(pooh.easy, CURLOPT_NOPROGRESS, 0L); + res = curl_easy_perform(pooh.easy); + } test_cleanup: curl_easy_cleanup(pooh.easy); -#if defined(LIB670) || defined(LIB671) - curl_mime_free(mime); -#else - curl_formfree(formpost); -#endif + + if(testnum == 670 || testnum == 671) { + curl_mime_free(mime); + } + else { + curl_formfree(formpost); + } curl_global_cleanup(); return res; diff --git a/vendor/curl/tests/libtest/lib674.c b/vendor/curl/tests/libtest/lib674.c index 2a979a223cd..a46f2be6eb1 100644 --- a/vendor/curl/tests/libtest/lib674.c +++ b/vendor/curl/tests/libtest/lib674.c @@ -21,17 +21,15 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" /* * Get a single URL without select(). */ -CURLcode test(char *URL) +static CURLcode test_lib674(const char *URL) { CURL *handle = NULL; CURL *handle2; @@ -52,13 +50,12 @@ CURLcode test(char *URL) uc = curl_url_set(urlp, CURLUPART_URL, URL, 0); if(uc) { curl_mfprintf(stderr, "problem setting CURLUPART_URL: %s.", - curl_url_strerror(uc)); + curl_url_strerror(uc)); goto test_cleanup; } /* demonstrate override behavior */ - easy_setopt(handle, CURLOPT_CURLU, urlp); easy_setopt(handle, CURLOPT_VERBOSE, 1L); diff --git a/vendor/curl/tests/libtest/lib676.c b/vendor/curl/tests/libtest/lib676.c index ec2b23576ec..63437523df8 100644 --- a/vendor/curl/tests/libtest/lib676.c +++ b/vendor/curl/tests/libtest/lib676.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib676(const char *URL) { CURLcode res; CURL *curl; diff --git a/vendor/curl/tests/libtest/lib677.c b/vendor/curl/tests/libtest/lib677.c index daabd68faeb..526e1706c37 100644 --- a/vendor/curl/tests/libtest/lib677.c +++ b/vendor/curl/tests/libtest/lib677.c @@ -21,17 +21,15 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -static const char testcmd[] = "A1 IDLE\r\n"; -static char testbuf[1024]; - -CURLcode test(char *URL) +static CURLcode test_lib677(const char *URL) { + static const char testcmd[] = "A1 IDLE\r\n"; + static char testbuf[1024]; + CURLM *mcurl; CURL *curl = NULL; int mrun; @@ -89,7 +87,7 @@ CURLcode test(char *URL) } else if(ec) { curl_mfprintf(stderr, "curl_easy_send() failed, with code %d (%s)\n", - (int)ec, curl_easy_strerror(ec)); + ec, curl_easy_strerror(ec)); res = ec; goto test_cleanup; } @@ -110,7 +108,7 @@ CURLcode test(char *URL) } else if(ec) { curl_mfprintf(stderr, "curl_easy_recv() failed, with code %d (%s)\n", - (int)ec, curl_easy_strerror(ec)); + ec, curl_easy_strerror(ec)); res = ec; goto test_cleanup; } diff --git a/vendor/curl/tests/libtest/lib678.c b/vendor/curl/tests/libtest/lib678.c index c5646502c3d..78e03c004f9 100644 --- a/vendor/curl/tests/libtest/lib678.c +++ b/vendor/curl/tests/libtest/lib678.c @@ -21,10 +21,8 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" static int loadfile(const char *filename, void **filedata, size_t *filesize) @@ -78,12 +76,11 @@ static CURLcode test_cert_blob(const char *url, const char *cafile) } if(loadfile(cafile, &certdata, &certsize)) { - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); - curl_easy_setopt(curl, CURLOPT_HEADER, 1L); - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_USERAGENT, "CURLOPT_CAINFO_BLOB"); - curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, - (long)CURLSSLOPT_REVOKE_BEST_EFFORT); + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(curl, CURLOPT_HEADER, 1L); + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_USERAGENT, "CURLOPT_CAINFO_BLOB"); + curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_REVOKE_BEST_EFFORT); blob.data = certdata; blob.len = certsize; @@ -97,7 +94,7 @@ static CURLcode test_cert_blob(const char *url, const char *cafile) return code; } -CURLcode test(char *URL) +static CURLcode test_lib678(const char *URL) { CURLcode res = CURLE_OK; curl_global_init(CURL_GLOBAL_DEFAULT); diff --git a/vendor/curl/tests/libtest/lib694.c b/vendor/curl/tests/libtest/lib694.c index 81c0fcc9571..eb760fbee2c 100644 --- a/vendor/curl/tests/libtest/lib694.c +++ b/vendor/curl/tests/libtest/lib694.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" -CURLcode test(char *URL) +static CURLcode test_lib694(const char *URL) { CURLcode res; CURL *curl; @@ -48,7 +48,7 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_HEADER, 1L); test_setopt(curl, CURLOPT_VERBOSE, 1L); test_setopt(curl, CURLOPT_HTTPAUTH, - (long) (CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_NTLM)); + CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_NTLM); test_setopt(curl, CURLOPT_USERPWD, "me:password"); do { diff --git a/vendor/curl/tests/libtest/lib695.c b/vendor/curl/tests/libtest/lib695.c index d38c5e436d8..325897c357c 100644 --- a/vendor/curl/tests/libtest/lib695.c +++ b/vendor/curl/tests/libtest/lib695.c @@ -21,20 +21,19 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" #include "memdebug.h" - /* write callback that does nothing */ static size_t write_it(char *ptr, size_t size, size_t nmemb, void *userdata) { - (void) ptr; - (void) userdata; + (void)ptr; + (void)userdata; return size * nmemb; } -CURLcode test(char *URL) +static CURLcode test_lib695(const char *URL) { CURL *curl = NULL; curl_mime *mime1 = NULL; @@ -78,7 +77,7 @@ CURLcode test(char *URL) /* Check for errors */ if(res != CURLE_OK) curl_mfprintf(stderr, "curl_easy_perform() 1 failed: %s\n", - curl_easy_strerror(res)); + curl_easy_strerror(res)); else { /* phase two, create a mime struct using the mime1 handle */ mime2 = curl_mime_init(curl); @@ -92,7 +91,7 @@ CURLcode test(char *URL) if(res != CURLE_OK) curl_mfprintf(stderr, "curl_mime_subparts() failed: %sn", - curl_easy_strerror(res)); + curl_easy_strerror(res)); else { mime1 = NULL; @@ -102,7 +101,7 @@ CURLcode test(char *URL) /* Check for errors */ if(res != CURLE_OK) curl_mfprintf(stderr, "curl_easy_perform() 2 failed: %s\n", - curl_easy_strerror(res)); + curl_easy_strerror(res)); } } diff --git a/vendor/curl/tests/libtest/lib751.c b/vendor/curl/tests/libtest/lib751.c index ab2f923b959..0e0a1968e68 100644 --- a/vendor/curl/tests/libtest/lib751.c +++ b/vendor/curl/tests/libtest/lib751.c @@ -21,19 +21,15 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" -#include "testutil.h" -#include "warnless.h" #include "memdebug.h" -#define TEST_HANG_TIMEOUT 60 * 1000 - /* * Get a single URL without select(). */ -CURLcode test(char *URL) +static CURLcode test_lib751(const char *URL) { CURL *easies[1000]; CURLM *m; @@ -67,7 +63,7 @@ CURLcode test(char *URL) mres = curl_multi_add_handle(m, e); if(mres != CURLM_OK) { - printf("MULTI ERROR: %s\n", curl_multi_strerror(mres)); + curl_mfprintf(stderr, "MULTI ERROR: %s\n", curl_multi_strerror(mres)); res = CURLE_FAILED_INIT; goto test_cleanup; } @@ -76,7 +72,7 @@ CURLcode test(char *URL) test_cleanup: if(res) - printf("ERROR: %s\n", curl_easy_strerror(res)); + curl_mfprintf(stderr, "ERROR: %s\n", curl_easy_strerror(res)); for(i = 0; i < 1000; i++) { if(easies[i]) { diff --git a/vendor/curl/tests/libtest/lib753.c b/vendor/curl/tests/libtest/lib753.c new file mode 100644 index 00000000000..ea3f0268af0 --- /dev/null +++ b/vendor/curl/tests/libtest/lib753.c @@ -0,0 +1,184 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "first.h" + +#include "testtrace.h" +#include "memdebug.h" + +struct t753_transfer_status { + CURL *easy; + const char *name; + bool pause; + bool is_paused; + bool seen_welcome; +}; + +static size_t t753_write_cb(char *ptr, size_t size, size_t nmemb, void *userp) +{ + struct t753_transfer_status *st = userp; + size_t len = size * nmemb; + (void)ptr; + if(st->pause) { + curl_mfprintf(stderr, "[%s] write_cb(len=%zu), PAUSE\n", st->name, len); + st->is_paused = TRUE; + return CURL_READFUNC_PAUSE; + } + curl_mfprintf(stderr, "[%s] write_cb(len=%zu), CONSUME\n", st->name, len); + st->is_paused = FALSE; + return len; +} + +static size_t t753_hd_cb(char *ptr, size_t size, size_t nmemb, void *userp) +{ + struct t753_transfer_status *st = userp; + size_t len = size * nmemb; + curl_mfprintf(stderr, "[%s] hd_cb '%.*s'\n", st->name, (int)len, ptr); + if(!strcmp("230 Welcome you silly person\r\n", ptr)) { + st->seen_welcome = TRUE; + st->easy = NULL; + } + return len; +} + +static bool t753_setup(const char *URL, const char *name, + CURL **peasy, + struct t753_transfer_status *st) +{ + CURL *easy = NULL; + CURLcode res = CURLE_OK; + + *peasy = NULL; + memset(st, 0, sizeof(*st)); + st->name = name; + st->easy = easy; + st->pause = TRUE; + + easy_init(easy); + + easy_setopt(easy, CURLOPT_URL, URL); + easy_setopt(easy, CURLOPT_WRITEFUNCTION, t753_write_cb); + easy_setopt(easy, CURLOPT_WRITEDATA, st); + easy_setopt(easy, CURLOPT_HEADERFUNCTION, t753_hd_cb); + easy_setopt(easy, CURLOPT_HEADERDATA, st); + + easy_setopt(easy, CURLOPT_NOPROGRESS, 1L); + easy_setopt(easy, CURLOPT_DEBUGDATA, &debug_config); + easy_setopt(easy, CURLOPT_DEBUGFUNCTION, libtest_debug_cb); + easy_setopt(easy, CURLOPT_VERBOSE, 1L); + + *peasy = easy; + return TRUE; + +test_cleanup: + if(easy) + curl_easy_cleanup(easy); + return FALSE; +} + +static CURLcode test_lib753(const char *URL) +{ + CURL *easy1 = NULL, *easy2 = NULL; + CURLM *multi = NULL; + struct t753_transfer_status st1, st2; + CURLcode res = CURLE_OK; + CURLMcode mres; + int still_running; + + start_test_timing(); + + debug_config.nohex = TRUE; + debug_config.tracetime = TRUE; + + curl_global_init(CURL_GLOBAL_DEFAULT); + + curl_mfprintf(stderr, "init multi\n"); + multi = curl_multi_init(); + if(!multi) { + res = CURLE_OUT_OF_MEMORY; + goto test_cleanup; + } + + if(!t753_setup(URL, "EASY1", &easy1, &st1)) + goto test_cleanup; + + multi_add_handle(multi, easy1); + + multi_perform(multi, &still_running); + abort_on_test_timeout(); + curl_mfprintf(stderr, "multi_perform() -> %d running\n", still_running); + + while(still_running) { + int num; + + /* The purpose of this Test: + * 1. Violently cleanup EASY1 *without* removing it from the multi + * handle first. This MUST discard the connection that EASY1 holds, + * as EASY1 is not DONE at this point. + * With the env var CURL_FTP_PWD_STOP set, the connection will + * have no outstanding data at this point. This would allow + * reuse if the connection is not terminated by the cleanup. + * 2. Add EASY2 for the same URL and observe in the expected result + * that the connection is NOT reused, e.g. all FTP commands + * are sent again on the new connection. + */ + if(easy1 && st1.seen_welcome) { + curl_easy_cleanup(easy1); + easy1 = NULL; + if(!easy2) { + if(!t753_setup(URL, "EASY2", &easy2, &st2)) + goto test_cleanup; + st2.pause = FALSE; + multi_add_handle(multi, easy2); + } + } + + mres = curl_multi_wait(multi, NULL, 0, 1, &num); + if(mres != CURLM_OK) { + curl_mfprintf(stderr, "curl_multi_wait() returned %d\n", mres); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + + abort_on_test_timeout(); + + multi_perform(multi, &still_running); + curl_mfprintf(stderr, "multi_perform() -> %d running\n", still_running); + + abort_on_test_timeout(); + } + +test_cleanup: + + if(res) + curl_mfprintf(stderr, "ERROR: %s\n", curl_easy_strerror(res)); + + if(easy1) + curl_easy_cleanup(easy1); + if(easy2) + curl_easy_cleanup(easy2); + curl_multi_cleanup(multi); + curl_global_cleanup(); + + return res; +} diff --git a/vendor/curl/tests/libtest/lib757.c b/vendor/curl/tests/libtest/lib757.c new file mode 100644 index 00000000000..632818f9460 --- /dev/null +++ b/vendor/curl/tests/libtest/lib757.c @@ -0,0 +1,135 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "first.h" + +#include "memdebug.h" + +/* write callback that does nothing */ +static size_t write_757(char *ptr, size_t size, size_t nmemb, void *userdata) +{ + (void)ptr; + (void)userdata; + return size * nmemb; +} + +#define DATA757 "fun-times" +#define DATALEN (sizeof(DATA757) - 1) + +static size_t read_757(char *buffer, size_t size, size_t nitems, void *arg) +{ + (void)arg; + if((size * nitems) >= DATALEN) { + memcpy(buffer, DATA757, DATALEN); + return DATALEN; + } + return 0; +} + +static int seek_757(void *arg, curl_off_t offset, int origin) +{ + (void)arg; + (void)offset; + (void)origin; + return CURL_SEEKFUNC_OK; +} + +static CURLcode test_lib757(const char *URL) +{ + CURL *curl = NULL; + curl_mime *mime1 = NULL; + curl_mime *mime2 = NULL; + curl_mimepart *part; + CURLcode res = TEST_ERR_FAILURE; + + /* + * Check proper rewind when reusing a mime structure. + */ + + if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + curl_mfprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + curl = curl_easy_init(); + + /* First set the URL that is about to receive our POST. */ + test_setopt(curl, CURLOPT_URL, URL); + + /* get verbose debug output please */ + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + /* Do not write anything. */ + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_757); + + /* Build the first mime structure. */ + mime1 = curl_mime_init(curl); + part = curl_mime_addpart(mime1); + curl_mime_data_cb(part, DATALEN, read_757, seek_757, NULL, NULL); + curl_mime_type(part, "text/html"); + curl_mime_name(part, "data"); + + /* Use first mime structure as top level MIME POST. */ + curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime1); + + /* Perform the request, res gets the return code */ + res = curl_easy_perform(curl); + + /* Check for errors */ + if(res != CURLE_OK) + curl_mfprintf(stderr, "curl_easy_perform() 1 failed: %s\n", + curl_easy_strerror(res)); + else { + /* phase two, create a mime struct using the mime1 handle */ + mime2 = curl_mime_init(curl); + part = curl_mime_addpart(mime2); + + /* use the new mime setup */ + curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime2); + + /* Reuse previous mime structure as a child. */ + res = curl_mime_subparts(part, mime1); + + if(res != CURLE_OK) + curl_mfprintf(stderr, "curl_mime_subparts() failed: %sn", + curl_easy_strerror(res)); + else { + mime1 = NULL; + + /* Perform the request, res gets the return code */ + res = curl_easy_perform(curl); + + /* Check for errors */ + if(res != CURLE_OK) + curl_mfprintf(stderr, "curl_easy_perform() 2 failed: %s\n", + curl_easy_strerror(res)); + } + } + +test_cleanup: + curl_easy_cleanup(curl); + curl_mime_free(mime1); + curl_mime_free(mime2); + curl_global_cleanup(); + return res; +} diff --git a/vendor/curl/tests/libtest/memptr.c b/vendor/curl/tests/libtest/memptr.c index 9f241031fb6..64e9fd7f8a1 100644 --- a/vendor/curl/tests/libtest/memptr.c +++ b/vendor/curl/tests/libtest/memptr.c @@ -21,7 +21,8 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "test.h" +#include "first.h" + #include "curl_memory.h" #ifndef CURL_STATICLIB @@ -39,9 +40,6 @@ curl_free_callback Curl_cfree = (curl_free_callback)free; curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc; curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)strdup; curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc; -#if defined(_WIN32) && defined(UNICODE) -curl_wcsdup_callback Curl_cwcsdup = wcsdup; -#endif #if defined(_MSC_VER) && defined(_DLL) # pragma warning(pop) diff --git a/vendor/curl/tests/libtest/testtrace.c b/vendor/curl/tests/libtest/testtrace.c index 63bd17fe343..b221f38cd0f 100644 --- a/vendor/curl/tests/libtest/testtrace.c +++ b/vendor/curl/tests/libtest/testtrace.c @@ -21,20 +21,18 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ - -#include "test.h" -#include "testutil.h" #include "testtrace.h" + #include "memdebug.h" -struct libtest_trace_cfg libtest_debug_config; +struct libtest_trace_cfg debug_config; static time_t epoch_offset; /* for test time tracing */ static int known_offset; /* for test time tracing */ -static -void libtest_debug_dump(const char *timebuf, const char *text, FILE *stream, - const unsigned char *ptr, size_t size, int nohex) +void debug_dump(const char *timebuf, const char *text, + FILE *stream, const unsigned char *ptr, + size_t size, bool nohex) { size_t i; size_t c; @@ -63,9 +61,8 @@ void libtest_debug_dump(const char *timebuf, const char *text, FILE *stream, for(c = 0; (c < width) && (i + c < size); c++) { /* check for 0D0A; if found, skip past and start a new line of output */ - if(nohex && - (i + c + 1 < size) && (ptr[i + c] == 0x0D) && - (ptr[i + c + 1] == 0x0A)) { + if(nohex && (i + c + 1 < size) && ptr[i + c] == 0x0D && + ptr[i + c + 1] == 0x0A) { i += (c + 2 - width); break; } @@ -73,9 +70,8 @@ void libtest_debug_dump(const char *timebuf, const char *text, FILE *stream, ((ptr[i + c] >= 0x20) && (ptr[i + c] < 0x80)) ? ptr[i + c] : '.'); /* check again for 0D0A, to avoid an extra \n if it's at width */ - if(nohex && - (i + c + 2 < size) && (ptr[i + c + 1] == 0x0D) && - (ptr[i + c + 2] == 0x0A)) { + if(nohex && (i + c + 2 < size) && ptr[i + c + 1] == 0x0D && + ptr[i + c + 2] == 0x0A) { i += (c + 3 - width); break; } @@ -90,10 +86,8 @@ int libtest_debug_cb(CURL *handle, curl_infotype type, { struct libtest_trace_cfg *trace_cfg = userp; const char *text; - struct timeval tv; char timebuf[20]; char *timestr; - time_t secs; (void)handle; @@ -102,12 +96,15 @@ int libtest_debug_cb(CURL *handle, curl_infotype type, if(trace_cfg->tracetime) { struct tm *now; - tv = tutil_tvnow(); + struct curltime tv; + time_t secs; + tv = curlx_now(); if(!known_offset) { epoch_offset = time(NULL) - tv.tv_sec; known_offset = 1; } secs = epoch_offset + tv.tv_sec; + /* !checksrc! disable BANNEDFUNC 1 */ now = localtime(&secs); /* not thread safe but we don't care */ curl_msnprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06ld ", now->tm_hour, now->tm_min, now->tm_sec, (long)tv.tv_usec); @@ -115,7 +112,7 @@ int libtest_debug_cb(CURL *handle, curl_infotype type, switch(type) { case CURLINFO_TEXT: - curl_mfprintf(stderr, "%s== Info: %s", timestr, (char *)data); + curl_mfprintf(stderr, "%s== Info: %s", timestr, data); return 0; case CURLINFO_HEADER_OUT: text = "=> Send header"; @@ -139,7 +136,101 @@ int libtest_debug_cb(CURL *handle, curl_infotype type, return 0; } - libtest_debug_dump(timebuf, text, stderr, (unsigned char *)data, size, - trace_cfg->nohex); + debug_dump(timebuf, text, stderr, (const unsigned char *)data, size, + trace_cfg->nohex); + return 0; +} + +static void log_line_start(FILE *log, const char *idsbuf, curl_infotype type) +{ + /* + * This is the trace look that is similar to what libcurl makes on its + * own. + */ + static const char * const s_infotype[] = { + "* ", "< ", "> ", "{ ", "} ", "{ ", "} " + }; + if(idsbuf && *idsbuf) + curl_mfprintf(log, "%s%s", idsbuf, s_infotype[type]); + else + fputs(s_infotype[type], log); +} + +/* callback for CURLOPT_DEBUGFUNCTION (used in client tests) */ +int cli_debug_cb(CURL *handle, curl_infotype type, + char *data, size_t size, void *userp) +{ + FILE *output = stderr; + static int newl = 0; + static int traced_data = 0; + char idsbuf[60]; + curl_off_t xfer_id, conn_id; + + (void)handle; /* not used */ + (void)userp; + + if(!curl_easy_getinfo(handle, CURLINFO_XFER_ID, &xfer_id) && xfer_id >= 0) { + if(!curl_easy_getinfo(handle, CURLINFO_CONN_ID, &conn_id) && + conn_id >= 0) { + curl_msnprintf(idsbuf, sizeof(idsbuf), + "[%" CURL_FORMAT_CURL_OFF_T "-" + "%" CURL_FORMAT_CURL_OFF_T "] ", xfer_id, conn_id); + } + else { + curl_msnprintf(idsbuf, sizeof(idsbuf), + "[%" CURL_FORMAT_CURL_OFF_T "-x] ", xfer_id); + } + } + else + idsbuf[0] = 0; + + switch(type) { + case CURLINFO_HEADER_OUT: + if(size > 0) { + size_t st = 0; + size_t i; + for(i = 0; i < size - 1; i++) { + if(data[i] == '\n') { /* LF */ + if(!newl) { + log_line_start(output, idsbuf, type); + } + (void)fwrite(data + st, i - st + 1, 1, output); + st = i + 1; + newl = 0; + } + } + if(!newl) + log_line_start(output, idsbuf, type); + (void)fwrite(data + st, i - st + 1, 1, output); + } + newl = (size && (data[size - 1] != '\n')) ? 1 : 0; + traced_data = 0; + break; + case CURLINFO_TEXT: + case CURLINFO_HEADER_IN: + if(!newl) + log_line_start(output, idsbuf, type); + (void)fwrite(data, size, 1, output); + newl = (size && (data[size - 1] != '\n')) ? 1 : 0; + traced_data = 0; + break; + case CURLINFO_DATA_OUT: + case CURLINFO_DATA_IN: + case CURLINFO_SSL_DATA_IN: + case CURLINFO_SSL_DATA_OUT: + if(!traced_data) { + if(!newl) + log_line_start(output, idsbuf, type); + curl_mfprintf(output, "[%zu bytes data]\n", size); + newl = 0; + traced_data = 1; + } + break; + default: /* nada */ + newl = 0; + traced_data = 1; + break; + } + return 0; } diff --git a/vendor/curl/tests/libtest/testtrace.h b/vendor/curl/tests/libtest/testtrace.h index d7087c5366f..79d2f8529d9 100644 --- a/vendor/curl/tests/libtest/testtrace.h +++ b/vendor/curl/tests/libtest/testtrace.h @@ -23,15 +23,24 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ +#include "first.h" + +void debug_dump(const char *timebuf, const char *text, + FILE *stream, const unsigned char *ptr, + size_t size, bool nohex); struct libtest_trace_cfg { - int tracetime; /* 0 represents FALSE, anything else TRUE */ - int nohex; /* 0 represents FALSE, anything else TRUE */ + bool tracetime; + bool nohex; }; -extern struct libtest_trace_cfg libtest_debug_config; +extern struct libtest_trace_cfg debug_config; int libtest_debug_cb(CURL *handle, curl_infotype type, char *data, size_t size, void *userp); +/* callback for CURLOPT_DEBUGFUNCTION (client tests) */ +int cli_debug_cb(CURL *handle, curl_infotype type, + char *data, size_t size, void *userp); + #endif /* HEADER_LIBTEST_TESTTRACE_H */ diff --git a/vendor/curl/tests/libtest/testutil.c b/vendor/curl/tests/libtest/testutil.c index 27cb9373afc..269479c3cea 100644 --- a/vendor/curl/tests/libtest/testutil.c +++ b/vendor/curl/tests/libtest/testutil.c @@ -21,111 +21,35 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curl_setup.h" -#include #include "testutil.h" -#include "memdebug.h" -#ifdef _WIN32 +#include "memdebug.h" -struct timeval tutil_tvnow(void) +/* build request url */ +char *tutil_suburl(const char *base, int i) { - /* - ** GetTickCount() is available on _all_ Windows versions from W95 up - ** to nowadays. Returns milliseconds elapsed since last system boot, - ** increases monotonically and wraps once 49.7 days have elapsed. - */ - struct timeval now; - DWORD milliseconds = GetTickCount(); - now.tv_sec = (long)(milliseconds / 1000); - now.tv_usec = (long)((milliseconds % 1000) * 1000); - return now; + return curl_maprintf("%s%.4d", base, i); } -#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC) - -struct timeval tutil_tvnow(void) +#if defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) +void tutil_rlim2str(char *buf, size_t len, rlim_t val) { - /* - ** clock_gettime() is granted to be increased monotonically when the - ** monotonic clock is queried. Time starting point is unspecified, it - ** could be the system start-up time, the Epoch, or something else, - ** in any case the time starting point does not change once that the - ** system has started up. - */ - struct timeval now; - struct timespec tsnow; - if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) { - now.tv_sec = tsnow.tv_sec; - now.tv_usec = (int)(tsnow.tv_nsec / 1000); +#ifdef RLIM_INFINITY + if(val == RLIM_INFINITY) { + curl_msnprintf(buf, len, "INFINITY"); + return; } - /* - ** Even when the configure process has truly detected monotonic clock - ** availability, it might happen that it is not actually available at - ** run-time. When this occurs simply fallback to other time source. - */ -#ifdef HAVE_GETTIMEOFDAY +#endif +#ifdef HAVE_LONGLONG + if(sizeof(rlim_t) > sizeof(long)) + curl_msnprintf(buf, len, "%llu", (unsigned long long)val); else - (void)gettimeofday(&now, NULL); -#else - else { - now.tv_sec = time(NULL); - now.tv_usec = 0; - } #endif - return now; -} - -#elif defined(HAVE_GETTIMEOFDAY) - -struct timeval tutil_tvnow(void) -{ - /* - ** gettimeofday() is not granted to be increased monotonically, due to - ** clock drifting and external source time synchronization it can jump - ** forward or backward in time. - */ - struct timeval now; - (void)gettimeofday(&now, NULL); - return now; -} - -#else - -struct timeval tutil_tvnow(void) -{ - /* - ** time() returns the value of time in seconds since the Epoch. - */ - struct timeval now; - now.tv_sec = time(NULL); - now.tv_usec = 0; - return now; + { + if(sizeof(rlim_t) < sizeof(long)) + curl_msnprintf(buf, len, "%u", (unsigned int)val); + else + curl_msnprintf(buf, len, "%lu", (unsigned long)val); + } } - #endif - -/* - * Make sure that the first argument is the more recent time, as otherwise - * we'll get a weird negative time-diff back... - * - * Returns: the time difference in number of milliseconds. - */ -long tutil_tvdiff(struct timeval newer, struct timeval older) -{ - return (long)(newer.tv_sec-older.tv_sec)*1000+ - (long)(newer.tv_usec-older.tv_usec)/1000; -} - -/* - * Same as tutil_tvdiff but with full usec resolution. - * - * Returns: the time difference in seconds with subsecond resolution. - */ -double tutil_tvdiff_secs(struct timeval newer, struct timeval older) -{ - if(newer.tv_sec != older.tv_sec) - return (double)(newer.tv_sec-older.tv_sec)+ - (double)(newer.tv_usec-older.tv_usec)/1000000.0; - return (double)(newer.tv_usec-older.tv_usec)/1000000.0; -} diff --git a/vendor/curl/tests/libtest/testutil.h b/vendor/curl/tests/libtest/testutil.h index 8696689d9d0..7c98e0aadee 100644 --- a/vendor/curl/tests/libtest/testutil.h +++ b/vendor/curl/tests/libtest/testutil.h @@ -23,23 +23,17 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curl_setup.h" +#include "first.h" -struct timeval tutil_tvnow(void); +/* build request url */ +char *tutil_suburl(const char *base, int i); -/* - * Make sure that the first argument (t1) is the more recent time and t2 is - * the older time, as otherwise you get a weird negative time-diff back... - * - * Returns: the time difference in number of milliseconds. - */ -long tutil_tvdiff(struct timeval t1, struct timeval t2); +#ifdef HAVE_SYS_RESOURCE_H +#include /* for getrlimit() */ +#endif -/* - * Same as tutil_tvdiff but with full usec resolution. - * - * Returns: the time difference in seconds with subsecond resolution. - */ -double tutil_tvdiff_secs(struct timeval t1, struct timeval t2); +#if defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) +void tutil_rlim2str(char *buf, size_t len, rlim_t val); +#endif #endif /* HEADER_CURL_LIBTEST_TESTUTIL_H */ diff --git a/vendor/curl/tests/libtest/unitcheck.h b/vendor/curl/tests/libtest/unitcheck.h new file mode 100644 index 00000000000..8007f9f8b5c --- /dev/null +++ b/vendor/curl/tests/libtest/unitcheck.h @@ -0,0 +1,118 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "first.h" + +/* The fail macros mark the current test step as failed, and continue */ +#define fail_if(expr, msg) \ + do { \ + if(expr) { \ + curl_mfprintf(stderr, "%s:%d FAILED Assertion '%s' met: %s\n", \ + __FILE__, __LINE__, #expr, msg); \ + unitfail++; \ + } \ + } while(0) + +#define fail_unless(expr, msg) \ + do { \ + if(!(expr)) { \ + curl_mfprintf(stderr, "%s:%d Assertion '%s' FAILED: %s\n", \ + __FILE__, __LINE__, #expr, msg); \ + unitfail++; \ + } \ + } while(0) + +#define verify_memory(dynamic, check, len) \ + do { \ + if(dynamic && memcmp(dynamic, check, len)) { \ + curl_mfprintf(stderr, "%s:%d Memory buffer FAILED match size %d. " \ + "'%s' is not\n", __FILE__, __LINE__, len, \ + hexdump((const unsigned char *)check, len)); \ + curl_mfprintf(stderr, "%s:%d the same as '%s'\n", __FILE__, __LINE__, \ + hexdump((const unsigned char *)dynamic, len)); \ + unitfail++; \ + } \ + } while(0) + +/* fail() is for when the test case figured out by itself that a check + proved a failure */ +#define fail(msg) do { \ + curl_mfprintf(stderr, "%s:%d test FAILED: '%s'\n", \ + __FILE__, __LINE__, msg); \ + unitfail++; \ + } while(0) + +/* The abort macros mark the current test step as failed, and exit the test */ +#define abort_if(expr, msg) \ + do { \ + if(expr) { \ + curl_mfprintf(stderr, "%s:%d ABORT assertion '%s' met: %s\n", \ + __FILE__, __LINE__, #expr, msg); \ + unitfail++; \ + goto unit_test_abort; \ + } \ + } while(0) + +#define abort_unless(expr, msg) \ + do { \ + if(!(expr)) { \ + curl_mfprintf(stderr, "%s:%d ABORT assertion '%s' failed: %s\n", \ + __FILE__, __LINE__, #expr, msg); \ + unitfail++; \ + goto unit_test_abort; \ + } \ + } while(0) + +#define unittest_abort(msg) \ + do { \ + curl_mfprintf(stderr, "%s:%d test ABORTED: '%s'\n", \ + __FILE__, __LINE__, msg); \ + unitfail++; \ + goto unit_test_abort; \ + } while(0) + + +#define UNITTEST_BEGIN_SIMPLE \ + (void)arg; \ + { + +#define UNITTEST_END_SIMPLE \ + goto unit_test_abort; /* avoid warning */ \ + } \ +unit_test_abort: \ + return (CURLcode)unitfail; + +#define UNITTEST_BEGIN(setupfunc) \ + (void)arg; \ + if(setupfunc) { \ + fail("unit_setup() FAILURE"); \ + return (CURLcode)unitfail; \ + } \ + { + +#define UNITTEST_END(stopfunc) \ + goto unit_test_abort; /* avoid warning */ \ + } \ +unit_test_abort: \ + stopfunc; \ + return (CURLcode)unitfail; diff --git a/vendor/curl/tests/server/.gitignore b/vendor/curl/tests/server/.gitignore new file mode 100644 index 00000000000..8f6424697ef --- /dev/null +++ b/vendor/curl/tests/server/.gitignore @@ -0,0 +1,6 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +servers +servers.c diff --git a/vendor/curl/tests/server/dnsd.c b/vendor/curl/tests/server/dnsd.c index a9598810c3f..dc49723da31 100644 --- a/vendor/curl/tests/server/dnsd.c +++ b/vendor/curl/tests/server/dnsd.c @@ -21,43 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ - -#include "server_setup.h" - -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#ifndef UNDER_CE -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_SYS_FILIO_H -/* FIONREAD on Solaris 7 */ -#include -#endif - -#include - -#include - -#include /* from the private lib dir */ -#include "getpart.h" -#include "util.h" -#include "server_sockaddr.h" - -/* include memdebug.h last */ -#include +#include "first.h" static int dnsd_wrotepidfile = 0; static int dnsd_wroteportfile = 0; @@ -98,6 +62,20 @@ static int qname(const unsigned char **pkt, size_t *size) #define QTYPE_A 1 #define QTYPE_AAAA 28 +#define QTYPE_HTTPS 0x41 + +static const char *type2string(unsigned short qtype) +{ + switch(qtype) { + case QTYPE_A: + return "A"; + case QTYPE_AAAA: + return "AAAA"; + case QTYPE_HTTPS: + return "HTTPS"; + } + return ""; +} /* * Handle initial connection protocol. @@ -160,8 +138,7 @@ static int store_incoming(const unsigned char *data, size_t size, fprintf(server, "Z: %x\n", (id & 0x70) >> 4); fprintf(server, "RCODE: %x\n", (id & 0x0f)); #endif - qd = get16bit(&data, &size); - fprintf(server, "QDCOUNT: %04x\n", qd); + (void) get16bit(&data, &size); data += 6; /* skip ANCOUNT, NSCOUNT and ARCOUNT */ size -= 6; @@ -171,18 +148,19 @@ static int store_incoming(const unsigned char *data, size_t size, qptr = data; if(!qname(&data, &size)) { - fprintf(server, "QNAME: %s\n", name); qd = get16bit(&data, &size); - fprintf(server, "QTYPE: %04x\n", qd); + fprintf(server, "QNAME %s QTYPE %s\n", name, type2string(qd)); *qtype = qd; - logmsg("Question for '%s' type %x", name, qd); + logmsg("Question for '%s' type %x / %s", name, qd, + type2string(qd)); - qd = get16bit(&data, &size); - fprintf(server, "QCLASS: %04x\n", qd); + (void) get16bit(&data, &size); *qlen = qsize - size; /* total size of the query */ memcpy(qbuf, qptr, *qlen); } + else + logmsg("Bad input qname"); #if 0 for(i = 0; i < size; i++) { fprintf(server, "%02d", (unsigned int)data[i]); @@ -195,76 +173,6 @@ static int store_incoming(const unsigned char *data, size_t size, return 0; } -#if 0 -static int send_response(curl_socket_t sock, - struct sockaddr *addr, - curl_socklen_t addrlen, - unsigned short id) -{ - ssize_t rc; - unsigned char bytes[] = { - 0x80, 0xea, /* ID, overwrite */ - 0x81, 0x80, - /* - Flags: 0x8180 Standard query response, No error - 1... .... .... .... = Response: Message is a response - .000 0... .... .... = Opcode: Standard query (0) - .... .0.. .... .... = Authoritative: Server is not an authority for - domain - .... ..0. .... .... = Truncated: Message is not truncated - .... ...1 .... .... = Recursion desired: Do query recursively - .... .... 1... .... = Recursion available: Server can do recursive - queries - .... .... .0.. .... = Z: reserved (0) - .... .... ..0. .... = Answer authenticated: Answer/authority portion - was not authenticated by the server - .... .... ...0 .... = Non-authenticated data: Unacceptable - .... .... .... 0000 = Reply code: No error (0) - */ - 0x0, 0x1, /* QDCOUNT */ - 0x0, 0x4, /* ANCOUNT */ - 0x0, 0x0, /* NSCOUNT */ - 0x0, 0x0, /* ARCOUNT */ - - /* here's the question */ - 0x4, 0x63, 0x75, 0x72, 0x6c, 0x2, 0x73, 0x65, 0x0, /* curl.se */ - 0x0, 0x1, /* QTYPE: A */ - 0x0, 0x1, /* QCLASS: IN */ - - /* 4 answers */ - 0xc0, 0xc, /* points to curl.se */ - 0x0, 0x1, /* QTYPE A */ - 0x0, 0x1, /* QCLASS IN */ - 0x0, 0x0, 0xa, 0x14, /* Time to live: 2580 (43 minutes) */ - 0x0, 0x4, /* data length */ - 0x97, 0x65, 0x41, 0x5b, /* Address: 151.101.65.91 */ - - 0xc0, 0xc, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0xa, 0x14, - 0x0, 0x4, 0x97, 0x65, 0x81, 0x5b, /* Address: 151.101.129.91 */ - 0xc0, 0xc, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0xa, 0x14, - 0x0, 0x4, 0x97, 0x65, 0xc1, 0x5b, /* Address: 151.101.193.91 */ - 0xc0, 0xc, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0xa, 0x14, - 0x0, 0x4, 0x97, 0x65, 0x1, 0x5b, /* Address: 151.101.1.91 */ -#if 0 - /* 1 additional record (ARCOUNT) */ - - 0x0, 0x0, 0x29, 0x4, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0 -#endif - }; - size_t len = sizeof(bytes); - - bytes[0] = (unsigned char)(id >> 8); - bytes[1] = (unsigned char)(id & 0xff); - - rc = sendto(sock, bytes, len, 0, addr, addrlen); - if(rc != (ssize_t)len) { - fprintf(stderr, "failed sending %d bytes\n", (int)len); - } - return 0; -} -#endif - static void add_answer(unsigned char *bytes, size_t *w, const unsigned char *a, size_t alen, unsigned short qtype) @@ -305,6 +213,17 @@ static void add_answer(unsigned char *bytes, size_t *w, #define SENDTO3 size_t #endif +#define INSTRUCTIONS "dnsd.cmd" + +#define MAX_ALPN 5 + +static unsigned char ipv4_pref[4]; +static unsigned char ipv6_pref[16]; +static unsigned char alpn_pref[MAX_ALPN]; +static int alpn_count; +static unsigned char ancount_a; +static unsigned char ancount_aaaa; + /* this is an answer to a question */ static int send_response(curl_socket_t sock, const struct sockaddr *addr, curl_socklen_t addrlen, @@ -314,7 +233,7 @@ static int send_response(curl_socket_t sock, ssize_t rc; size_t i; int a; - unsigned char ancount = 3; + char addrbuf[128]; /* IP address buffer */ unsigned char bytes[256] = { 0x80, 0xea, /* ID, overwrite */ 0x81, 0x80, @@ -339,14 +258,9 @@ static int send_response(curl_socket_t sock, 0x0, 0x0, /* NSCOUNT */ 0x0, 0x0 /* ARCOUNT */ }; - static const unsigned char ipv4_localhost[] = { 127, 0, 0, 1 }; - static const unsigned char ipv6_localhost[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 - }; bytes[0] = (unsigned char)(id >> 8); bytes[1] = (unsigned char)(id & 0xff); - bytes[7] = ancount; if(qlen > (sizeof(bytes) - 12)) return -1; @@ -356,16 +270,28 @@ static int send_response(curl_socket_t sock, i = 12 + qlen; - for(a = 0; a < ancount; a++) { - switch(qtype) { - case QTYPE_A: - add_answer(bytes, &i, ipv4_localhost, sizeof(ipv4_localhost), QTYPE_A); - break; - case QTYPE_AAAA: - add_answer(bytes, &i, ipv6_localhost, sizeof(ipv6_localhost), - QTYPE_AAAA); - break; + switch(qtype) { + case QTYPE_A: + bytes[7] = ancount_a; + for(a = 0; a < ancount_a; a++) { + const unsigned char *store = ipv4_pref; + add_answer(bytes, &i, store, sizeof(ipv4_pref), QTYPE_A); + logmsg("Sending back A (%x) '%s'", QTYPE_A, + curlx_inet_ntop(AF_INET, store, addrbuf, sizeof(addrbuf))); } + break; + case QTYPE_AAAA: + bytes[7] = ancount_aaaa; + for(a = 0; a < ancount_aaaa; a++) { + const unsigned char *store = ipv6_pref; + add_answer(bytes, &i, store, sizeof(ipv6_pref), QTYPE_AAAA); + logmsg("Sending back AAAA (%x) '%s'", QTYPE_AAAA, + curlx_inet_ntop(AF_INET6, store, addrbuf, sizeof(addrbuf))); + } + break; + case QTYPE_HTTPS: + bytes[7] = 1; /* one answer */ + break; } #ifdef __AMIGA__ @@ -385,7 +311,69 @@ static int send_response(curl_socket_t sock, return 0; } -int main(int argc, char **argv) + +static void read_instructions(void) +{ + char file[256]; + FILE *f; + snprintf(file, sizeof(file), "%s/" INSTRUCTIONS, logdir); + f = fopen(file, FOPEN_READTEXT); + if(f) { + char buf[256]; + ancount_aaaa = ancount_a = 0; + alpn_count = 0; + while(fgets(buf, sizeof(buf), f)) { + char *p = strchr(buf, '\n'); + if(p) { + int rc; + *p = 0; + if(!strncmp("A: ", buf, 3)) { + rc = curlx_inet_pton(AF_INET, &buf[3], ipv4_pref); + ancount_a = (rc == 1); + } + else if(!strncmp("AAAA: ", buf, 6)) { + char *p6 = &buf[6]; + if(*p6 == '[') { + char *pt = strchr(p6, ']'); + if(pt) + *pt = 0; + p6++; + } + rc = curlx_inet_pton(AF_INET6, p6, ipv6_pref); + ancount_aaaa = (rc == 1); + } + else if(!strncmp("ALPN: ", buf, 6)) { + char *ap = &buf[6]; + rc = 0; + while(*ap) { + if('h' == *ap) { + ap++; + if(*ap >= '1' && *ap <= '3') { + if(alpn_count < MAX_ALPN) + alpn_pref[alpn_count++] = *ap; + } + else + break; + } + else + break; + } + } + else { + rc = 0; + } + if(rc != 1) { + logmsg("Bad line in %s: '%s'\n", file, buf); + } + } + } + fclose(f); + } + else + logmsg("Error opening file '%s'", file); +} + +static int test_dnsd(int argc, char **argv) { srvr_sockaddr_union_t me; ssize_t n = 0; @@ -500,8 +488,8 @@ int main(int argc, char **argv) } flag = 1; - if(0 != setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, - (void *)&flag, sizeof(flag))) { + if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + (void *)&flag, sizeof(flag))) { error = SOCKERRNO; logmsg("setsockopt(SO_REUSEADDR) failed with error (%d) %s", error, sstrerror(error)); @@ -527,7 +515,7 @@ int main(int argc, char **argv) rc = bind(sock, &me.sa, sizeof(me.sa6)); } #endif /* USE_IPV6 */ - if(0 != rc) { + if(rc) { error = SOCKERRNO; logmsg("Error binding socket on port %hu (%d) %s", port, error, sstrerror(error)); @@ -622,6 +610,10 @@ int main(int argc, char **argv) break; } + /* read once per incoming query, which is probably more than one + per test case */ + read_instructions(); + store_incoming(inbuffer, n, qbuf, &qlen, &qtype, &id); set_advisor_read_lock(loglockfile); @@ -637,8 +629,7 @@ int main(int argc, char **argv) clear_advisor_read_lock(loglockfile); } - logmsg("end of one transfer"); - + /* logmsg("end of one transfer"); */ } dnsd_cleanup: diff --git a/vendor/curl/tests/server/first.c b/vendor/curl/tests/server/first.c index 13b02d41c7a..0f30c780162 100644 --- a/vendor/curl/tests/server/first.c +++ b/vendor/curl/tests/server/first.c @@ -21,39 +21,35 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ +#include "first.h" + #include #include -#include "first.h" int main(int argc, char **argv) { - main_func_t main_func; - char *main_name; + entry_func_t entry_func; + char *entry_name; + size_t tmp; if(argc < 2) { fprintf(stderr, "Pass servername as first argument\n"); return 1; } - main_name = argv[1]; - main_func = NULL; - { - size_t tmp; - for(tmp = 0; s_mains[tmp].ptr; ++tmp) { - if(strcmp(main_name, s_mains[tmp].name) == 0) { - main_func = s_mains[tmp].ptr; - break; - } + entry_name = argv[1]; + entry_func = NULL; + for(tmp = 0; s_entries[tmp].ptr; ++tmp) { + if(strcmp(entry_name, s_entries[tmp].name) == 0) { + entry_func = s_entries[tmp].ptr; + break; } } - if(!main_func) { - fprintf(stderr, "Test '%s' not found.\n", main_name); + if(!entry_func) { + fprintf(stderr, "Test '%s' not found.\n", entry_name); return 99; } - --argc; - ++argv; - - return main_func(argc, argv); + return entry_func(argc - 1, argv + 1); } diff --git a/vendor/curl/tests/server/first.h b/vendor/curl/tests/server/first.h index 54863cdf38e..44dd272ce2b 100644 --- a/vendor/curl/tests/server/first.h +++ b/vendor/curl/tests/server/first.h @@ -23,11 +23,154 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -typedef int (*main_func_t)(int, char **); -struct onemain { +/* Test servers simply are standalone programs that do not use libcurl + * library. For convenience and to ease portability of these servers, + * some source code files from the libcurl subdirectory are also used + * to build the servers. In order to achieve proper linkage of these + * files on Windows targets it is necessary to build the test servers + * with CURL_STATICLIB defined, independently of how libcurl is built. + * For other platforms, this macro is a no-op and safe to set. + */ +#define CURL_STATICLIB + +#define WITHOUT_LIBCURL +#define CURL_NO_OLDIES + +#include "curl_setup.h" + +typedef int (*entry_func_t)(int, char **); + +struct entry_s { const char *name; - main_func_t ptr; + entry_func_t ptr; }; +extern const struct entry_s s_entries[]; + +#ifndef UNDER_CE +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETINET_IN6_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif + +#include + +/* adjust for old MSVC */ +#if defined(_MSC_VER) && (_MSC_VER < 1900) +# define snprintf _snprintf +#endif + +#ifdef _WIN32 +# define CURL_STRNICMP(p1, p2, n) _strnicmp(p1, p2, n) +#elif defined(HAVE_STRCASECMP) +# ifdef HAVE_STRINGS_H +# include +# endif +# define CURL_STRNICMP(p1, p2, n) strncasecmp(p1, p2, n) +#elif defined(HAVE_STRCMPI) +# define CURL_STRNICMP(p1, p2, n) strncmpi(p1, p2, n) +#elif defined(HAVE_STRICMP) +# define CURL_STRNICMP(p1, p2, n) strnicmp(p1, p2, n) +#else +# error "missing case insensitive comparison function" +#endif + +enum { + DOCNUMBER_NOTHING = -7, + DOCNUMBER_QUIT = -6, + DOCNUMBER_BADCONNECT = -5, + DOCNUMBER_INTERNAL = -4, + DOCNUMBER_CONNECT = -3, + DOCNUMBER_WERULEZ = -2, + DOCNUMBER_404 = -1 +}; + +#include /* for curl_socket_t */ + +#ifdef USE_UNIX_SOCKETS +#ifdef HAVE_SYS_UN_H +#include /* for sockaddr_un */ +#endif +#endif /* USE_UNIX_SOCKETS */ + +typedef union { + struct sockaddr sa; + struct sockaddr_in sa4; +#ifdef USE_IPV6 + struct sockaddr_in6 sa6; +#endif +#ifdef USE_UNIX_SOCKETS + struct sockaddr_un sau; +#endif +} srvr_sockaddr_union_t; + +/* getpart */ +#define GPE_NO_BUFFER_SPACE -2 +#define GPE_OUT_OF_MEMORY -1 +#define GPE_OK 0 +#define GPE_END_OF_FILE 1 + +extern int getpart(char **outbuf, size_t *outlen, + const char *main, const char *sub, FILE *stream); + +/* utility functions */ +extern char *data_to_hex(char *data, size_t len); +extern void logmsg(const char *msg, ...); +extern void loghex(unsigned char *buffer, ssize_t len); +extern unsigned char byteval(char *value); +extern int win32_init(void); +extern const char *sstrerror(int err); +extern FILE *test2fopen(long testno, const char *logdir2); +extern curl_off_t our_getpid(void); +extern int write_pidfile(const char *filename); +extern int write_portfile(const char *filename, int port); +extern void set_advisor_read_lock(const char *filename); +extern void clear_advisor_read_lock(const char *filename); +static volatile int got_exit_signal = 0; +static volatile int exit_signal = 0; +#ifdef _WIN32 +static HANDLE exit_event = NULL; +#endif +extern void install_signal_handlers(bool keep_sigalrm); +extern void restore_signal_handlers(bool keep_sigalrm); +#ifdef USE_UNIX_SOCKETS +extern int bind_unix_socket(curl_socket_t sock, const char *unix_socket, + struct sockaddr_un *sau); +#endif +extern unsigned short util_ultous(unsigned long ulnum); +extern curl_socket_t sockdaemon(curl_socket_t sock, + unsigned short *listenport, + const char *unix_socket, + bool bind_only); + +/* global variables */ +static const char *srcpath = "."; /* pointing to the test dir */ +static const char *pidname = NULL; +static const char *portname = NULL; /* none by default */ +static const char *serverlogfile = NULL; +static int serverlogslocked; +static const char *configfile = NULL; +static const char *logdir = "log"; +static char loglockfile[256]; +#ifdef USE_IPV6 +static bool use_ipv6 = FALSE; +#endif +static const char *ipv_inuse = "IPv4"; +static unsigned short server_port = 0; +static const char *socket_type = "IPv4"; +static int socket_domain = AF_INET; + +#define SERVERLOGS_LOCKDIR "lock" /* within logdir */ + #endif /* HEADER_SERVER_FIRST_H */ diff --git a/vendor/curl/tests/server/getpart.c b/vendor/curl/tests/server/getpart.c index 3ee836140a7..6bff92ab1ae 100644 --- a/vendor/curl/tests/server/getpart.c +++ b/vendor/curl/tests/server/getpart.c @@ -21,14 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "server_setup.h" - -#include "getpart.h" -#include /* from the private lib dir */ -#include "curl_memory.h" - -/* include memdebug.h last */ -#include +#include "first.h" #define EAT_SPACE(p) while(*(p) && ISSPACE(*(p))) (p)++ @@ -40,31 +33,6 @@ #define show(x) Curl_nop_stmt #endif -#if defined(UNDER_CE) -#define system_strdup _strdup -#else -#define system_strdup strdup -#endif - -#if defined(_MSC_VER) && defined(_DLL) -# pragma warning(push) -# pragma warning(disable:4232) /* MSVC extension, dllimport identity */ -#endif - -curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc; -curl_free_callback Curl_cfree = (curl_free_callback)free; -curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc; -curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup; -curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc; -#if defined(_WIN32) && defined(UNICODE) -curl_wcsdup_callback Curl_cwcsdup = NULL; /* not use in test code */ -#endif - -#if defined(_MSC_VER) && defined(_DLL) -# pragma warning(pop) -#endif - - /* * line_length() * @@ -109,7 +77,6 @@ static size_t line_length(const char *buffer, int bytestocheck) * GPE_END_OF_FILE * GPE_OK */ - static int readline(char **buffer, size_t *bufsize, size_t *length, FILE *stream) { @@ -174,7 +141,6 @@ static int readline(char **buffer, size_t *bufsize, size_t *length, * GPE_OUT_OF_MEMORY * GPE_OK */ - static int appenddata(char **dst_buf, /* dest buffer */ size_t *dst_len, /* dest buffer data length */ size_t *dst_alloc, /* dest buffer allocated size */ @@ -274,16 +240,15 @@ static int decodedata(char **buf, /* dest buffer */ * GPE_OUT_OF_MEMORY * GPE_OK */ - int getpart(char **outbuf, size_t *outlen, const char *main, const char *sub, FILE *stream) { # define MAX_TAG_LEN 200 - char couter[MAX_TAG_LEN + 1]; /* current outermost section */ - char cmain[MAX_TAG_LEN + 1]; /* current main section */ - char csub[MAX_TAG_LEN + 1]; /* current sub section */ - char ptag[MAX_TAG_LEN + 1]; /* potential tag */ - char patt[MAX_TAG_LEN + 1]; /* potential attributes */ + char curouter[MAX_TAG_LEN + 1]; /* current outermost section */ + char curmain[MAX_TAG_LEN + 1]; /* current main section */ + char cursub[MAX_TAG_LEN + 1]; /* current sub section */ + char ptag[MAX_TAG_LEN + 1]; /* potential tag */ + char patt[MAX_TAG_LEN + 1]; /* potential attributes */ char *buffer = NULL; char *ptr; char *end; @@ -313,7 +278,7 @@ int getpart(char **outbuf, size_t *outlen, return GPE_OUT_OF_MEMORY; *(*outbuf) = '\0'; - couter[0] = cmain[0] = csub[0] = ptag[0] = patt[0] = '\0'; + curouter[0] = curmain[0] = cursub[0] = ptag[0] = patt[0] = '\0'; while((error = readline(&buffer, &bufsize, &datalen, stream)) == GPE_OK) { @@ -349,10 +314,10 @@ int getpart(char **outbuf, size_t *outlen, memcpy(ptag, ptr, len.uns); ptag[len.uns] = '\0'; - if((STATE_INSUB == state) && !strcmp(csub, ptag)) { + if((STATE_INSUB == state) && !strcmp(cursub, ptag)) { /* end of current sub section */ state = STATE_INMAIN; - csub[0] = '\0'; + cursub[0] = '\0'; if(in_wanted_part) { /* Do we need to base64 decode the data? */ if(base64) { @@ -365,10 +330,10 @@ int getpart(char **outbuf, size_t *outlen, break; } } - else if((STATE_INMAIN == state) && !strcmp(cmain, ptag)) { + else if((STATE_INMAIN == state) && !strcmp(curmain, ptag)) { /* end of current main section */ state = STATE_OUTER; - cmain[0] = '\0'; + curmain[0] = '\0'; if(in_wanted_part) { /* Do we need to base64 decode the data? */ if(base64) { @@ -381,10 +346,10 @@ int getpart(char **outbuf, size_t *outlen, break; } } - else if((STATE_OUTER == state) && !strcmp(couter, ptag)) { + else if((STATE_OUTER == state) && !strcmp(curouter, ptag)) { /* end of outermost file section */ state = STATE_OUTSIDE; - couter[0] = '\0'; + curouter[0] = '\0'; if(in_wanted_part) break; } @@ -428,21 +393,21 @@ int getpart(char **outbuf, size_t *outlen, if(STATE_OUTSIDE == state) { /* outermost element () */ - strcpy(couter, ptag); + strcpy(curouter, ptag); state = STATE_OUTER; continue; } else if(STATE_OUTER == state) { /* start of a main section */ - strcpy(cmain, ptag); + strcpy(curmain, ptag); state = STATE_INMAIN; continue; } else if(STATE_INMAIN == state) { /* start of a sub section */ - strcpy(csub, ptag); + strcpy(cursub, ptag); state = STATE_INSUB; - if(!strcmp(cmain, main) && !strcmp(csub, sub)) { + if(!strcmp(curmain, main) && !strcmp(cursub, sub)) { /* start of wanted part */ in_wanted_part = 1; if(strstr(patt, "base64=")) diff --git a/vendor/curl/tests/server/memptr.c b/vendor/curl/tests/server/memptr.c new file mode 100644 index 00000000000..247bbf13ab8 --- /dev/null +++ b/vendor/curl/tests/server/memptr.c @@ -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 + * + ***************************************************************************/ +#include "first.h" + +#include "curl_memory.h" + +#ifdef UNDER_CE +#define system_strdup _strdup +#else +#define system_strdup strdup +#endif + +#if defined(_MSC_VER) && defined(_DLL) +# pragma warning(push) +# pragma warning(disable:4232) /* MSVC extension, dllimport identity */ +#endif + +curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc; +curl_free_callback Curl_cfree = (curl_free_callback)free; +curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc; +curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup; +curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc; + +#if defined(_MSC_VER) && defined(_DLL) +# pragma warning(pop) +#endif diff --git a/vendor/curl/tests/server/mqttd.c b/vendor/curl/tests/server/mqttd.c index 6ec031c5c73..7f5abf1b5d6 100644 --- a/vendor/curl/tests/server/mqttd.c +++ b/vendor/curl/tests/server/mqttd.c @@ -21,10 +21,10 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "server_setup.h" +#include "first.h" + #include #include -#include "util.h" /* Function * @@ -37,31 +37,6 @@ /* based on sockfilt.c */ -#ifndef UNDER_CE -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETINET_IN6_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif - -#include /* from the private lib dir */ -#include "getpart.h" -#include "server_sockaddr.h" - -#include "tool_binmode.h" - -/* include memdebug.h last */ -#include - #define MQTT_MSG_CONNECT 0x10 #define MQTT_MSG_CONNACK 0x20 #define MQTT_MSG_PUBLISH 0x30 @@ -106,7 +81,7 @@ static void mqttd_getconfig(void) while(fgets(buffer, sizeof(buffer), fp)) { char key[32]; char value[32]; - if(2 == sscanf(buffer, "%31s %31s", key, value)) { + if(sscanf(buffer, "%31s %31s", key, value) == 2) { if(!strcmp(key, "version")) { m_config.version = byteval(value); logmsg("version [%d] set", m_config.version); @@ -253,11 +228,8 @@ static int disconnect(FILE *dump, curl_socket_t fd) return 1; } - - /* do - encodedByte = X MOD 128 X = X DIV 128 @@ -463,6 +435,7 @@ static curl_socket_t mqttit(curl_socket_t fd) logmsg("Out of memory, unable to allocate buffer"); goto end; } + memset(buffer, 0, buff_size); do { unsigned char usr_flag = 0x80; @@ -693,12 +666,12 @@ static bool mqttd_incoming(curl_socket_t listenfd) FD_ZERO(&fds_err); /* there's always a socket to wait for */ -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif FD_SET(sockfd, &fds_read); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif @@ -739,150 +712,7 @@ static bool mqttd_incoming(curl_socket_t listenfd) return TRUE; } -static curl_socket_t mqttd_sockdaemon(curl_socket_t sock, - unsigned short *listenport, - bool bind_only) -{ - /* passive daemon style */ - srvr_sockaddr_union_t listener; - int flag; - int rc; - int totdelay = 0; - int maxretr = 10; - int delay = 20; - int attempt = 0; - int error = 0; - - do { - attempt++; - flag = 1; - rc = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, - (void *)&flag, sizeof(flag)); - if(rc) { - error = SOCKERRNO; - logmsg("setsockopt(SO_REUSEADDR) failed with error (%d) %s", - error, sstrerror(error)); - if(maxretr) { - rc = wait_ms(delay); - if(rc) { - /* should not happen */ - error = SOCKERRNO; - logmsg("wait_ms() failed with error (%d) %s", - error, sstrerror(error)); - sclose(sock); - return CURL_SOCKET_BAD; - } - if(got_exit_signal) { - logmsg("signalled to die, exiting..."); - sclose(sock); - return CURL_SOCKET_BAD; - } - totdelay += delay; - delay *= 2; /* double the sleep for next attempt */ - } - } - } while(rc && maxretr--); - - if(rc) { - logmsg("setsockopt(SO_REUSEADDR) failed %d times in %d ms. Error (%d) %s", - attempt, totdelay, error, strerror(error)); - logmsg("Continuing anyway..."); - } - - /* When the specified listener port is zero, it is actually a - request to let the system choose a non-zero available port. */ - -#ifdef USE_IPV6 - if(!use_ipv6) { -#endif - memset(&listener.sa4, 0, sizeof(listener.sa4)); - listener.sa4.sin_family = AF_INET; - listener.sa4.sin_addr.s_addr = INADDR_ANY; - listener.sa4.sin_port = htons(*listenport); - rc = bind(sock, &listener.sa, sizeof(listener.sa4)); -#ifdef USE_IPV6 - } - else { - memset(&listener.sa6, 0, sizeof(listener.sa6)); - listener.sa6.sin6_family = AF_INET6; - listener.sa6.sin6_addr = in6addr_any; - listener.sa6.sin6_port = htons(*listenport); - rc = bind(sock, &listener.sa, sizeof(listener.sa6)); - } -#endif /* USE_IPV6 */ - if(rc) { - error = SOCKERRNO; - logmsg("Error binding socket on port %hu (%d) %s", - *listenport, error, sstrerror(error)); - sclose(sock); - return CURL_SOCKET_BAD; - } - - if(!*listenport) { - /* The system was supposed to choose a port number, figure out which - port we actually got and update the listener port value with it. */ - curl_socklen_t la_size; - srvr_sockaddr_union_t localaddr; -#ifdef USE_IPV6 - if(!use_ipv6) -#endif - la_size = sizeof(localaddr.sa4); -#ifdef USE_IPV6 - else - la_size = sizeof(localaddr.sa6); -#endif - memset(&localaddr.sa, 0, (size_t)la_size); - if(getsockname(sock, &localaddr.sa, &la_size) < 0) { - error = SOCKERRNO; - logmsg("getsockname() failed with error (%d) %s", - error, sstrerror(error)); - sclose(sock); - return CURL_SOCKET_BAD; - } - switch(localaddr.sa.sa_family) { - case AF_INET: - *listenport = ntohs(localaddr.sa4.sin_port); - break; -#ifdef USE_IPV6 - case AF_INET6: - *listenport = ntohs(localaddr.sa6.sin6_port); - break; -#endif - default: - break; - } - if(!*listenport) { - /* Real failure, listener port shall not be zero beyond this point. */ - logmsg("Apparently getsockname() succeeded, with listener port zero."); - logmsg("A valid reason for this failure is a binary built without"); - logmsg("proper network library linkage. This might not be the only"); - logmsg("reason, but double check it before anything else."); - sclose(sock); - return CURL_SOCKET_BAD; - } - } - - /* bindonly option forces no listening */ - if(bind_only) { - logmsg("instructed to bind port without listening"); - return sock; - } - - /* start accepting connections */ - rc = listen(sock, 5); - if(0 != rc) { - error = SOCKERRNO; - logmsg("listen(%ld, 5) failed with error (%d) %s", - (long)sock, error, sstrerror(error)); - sclose(sock); - return CURL_SOCKET_BAD; - } - - return sock; -} - - -int main(int argc, char *argv[]) +static int test_mqttd(int argc, char *argv[]) { curl_socket_t sock = CURL_SOCKET_BAD; curl_socket_t msgsock = CURL_SOCKET_BAD; @@ -936,16 +766,16 @@ int main(int argc, char *argv[]) } else if(!strcmp("--ipv6", argv[arg])) { #ifdef USE_IPV6 + socket_domain = AF_INET6; ipv_inuse = "IPv6"; - use_ipv6 = TRUE; #endif arg++; } else if(!strcmp("--ipv4", argv[arg])) { /* for completeness, we support this option as well */ #ifdef USE_IPV6 + socket_domain = AF_INET; ipv_inuse = "IPv4"; - use_ipv6 = FALSE; #endif arg++; } @@ -987,20 +817,13 @@ int main(int argc, char *argv[]) return 2; #endif - CURL_SET_BINMODE(stdin); - CURL_SET_BINMODE(stdout); - CURL_SET_BINMODE(stderr); + CURLX_SET_BINMODE(stdin); + CURLX_SET_BINMODE(stdout); + CURLX_SET_BINMODE(stderr); install_signal_handlers(FALSE); -#ifdef USE_IPV6 - if(!use_ipv6) -#endif - sock = socket(AF_INET, SOCK_STREAM, 0); -#ifdef USE_IPV6 - else - sock = socket(AF_INET6, SOCK_STREAM, 0); -#endif + sock = socket(socket_domain, SOCK_STREAM, 0); if(CURL_SOCKET_BAD == sock) { error = SOCKERRNO; @@ -1010,7 +833,7 @@ int main(int argc, char *argv[]) { /* passive daemon style */ - sock = mqttd_sockdaemon(sock, &server_port, FALSE); + sock = sockdaemon(sock, &server_port, NULL, FALSE); if(CURL_SOCKET_BAD == sock) { goto mqttd_cleanup; } diff --git a/vendor/curl/tests/server/resolve.c b/vendor/curl/tests/server/resolve.c index b69c87c1fa8..cab3cb7dff8 100644 --- a/vendor/curl/tests/server/resolve.c +++ b/vendor/curl/tests/server/resolve.c @@ -21,7 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "server_setup.h" +#include "first.h" /* Purpose * @@ -33,23 +33,7 @@ * */ -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef _XOPEN_SOURCE_EXTENDED -/* This define is "almost" required to build on HP-UX 11 */ -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif - -#include "util.h" - -/* include memdebug.h last */ -#include - -int main(int argc, char *argv[]) +static int test_resolve(int argc, char *argv[]) { int arg = 1; const char *host = NULL; @@ -58,7 +42,7 @@ int main(int argc, char *argv[]) while(argc > arg) { if(!strcmp("--version", argv[arg])) { printf("resolve IPv4%s\n", -#if defined(CURLRES_IPV6) +#ifdef CURLRES_IPV6 "/IPv6" #else "" @@ -67,7 +51,7 @@ int main(int argc, char *argv[]) return 0; } else if(!strcmp("--ipv6", argv[arg])) { -#if defined(CURLRES_IPV6) +#ifdef CURLRES_IPV6 ipv_inuse = "IPv6"; use_ipv6 = TRUE; arg++; @@ -79,7 +63,7 @@ int main(int argc, char *argv[]) else if(!strcmp("--ipv4", argv[arg])) { /* for completeness, we support this option as well */ ipv_inuse = "IPv4"; -#if defined(CURLRES_IPV6) +#ifdef CURLRES_IPV6 use_ipv6 = FALSE; #endif arg++; @@ -92,7 +76,7 @@ int main(int argc, char *argv[]) puts("Usage: resolve [option] \n" " --version\n" " --ipv4" -#if defined(CURLRES_IPV6) +#ifdef CURLRES_IPV6 "\n --ipv6" #endif ); @@ -104,7 +88,7 @@ int main(int argc, char *argv[]) return 2; #endif -#if defined(CURLRES_IPV6) +#ifdef CURLRES_IPV6 if(use_ipv6) { /* Check that the system has IPv6 enabled before checking the resolver */ curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0); diff --git a/vendor/curl/tests/server/rtspd.c b/vendor/curl/tests/server/rtspd.c index fd994589227..67829922dc9 100644 --- a/vendor/curl/tests/server/rtspd.c +++ b/vendor/curl/tests/server/rtspd.c @@ -21,7 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "server_setup.h" +#include "first.h" /* * curl's test suite Real Time Streaming Protocol (RTSP) server. @@ -29,36 +29,10 @@ * This source file was started based on curl's HTTP test suite server. */ -#ifndef UNDER_CE -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETINET_IN6_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif #ifdef HAVE_NETINET_TCP_H #include /* for TCP_NODELAY */ #endif -#include /* from the private lib dir */ -#include "getpart.h" -#include "util.h" -#include "server_sockaddr.h" - -/* include memdebug.h last */ -#include - -#undef REQBUFSIZ -#define REQBUFSIZ 150000 - static long rtspd_prevtestno = -1; /* previous test number we served */ static long rtspd_prevpartno = -1; /* previous part number we served */ static bool rtspd_prevbounce = FALSE; /* instructs the server to override the @@ -82,7 +56,7 @@ typedef enum { ((p)[3] = (char)((l) & 0xFF))) struct rtspd_httprequest { - char reqbuf[REQBUFSIZ]; /* buffer area for the incoming request */ + char reqbuf[150000]; /* buffer area for the incoming request */ size_t checkindex; /* where to start checking of the request */ size_t offset; /* size of the incoming request */ long testno; /* test number found in the request */ @@ -146,22 +120,22 @@ static const char *docbadconnect = /* send back this on HTTP 404 file not found */ static const char *doc404_HTTP = "HTTP/1.1 404 Not Found\r\n" - "Server: " RTSPDVERSION "\r\n" - "Connection: close\r\n" - "Content-Type: text/html" - END_OF_HEADERS - "\n" - "\n" - "404 Not Found\n" - "\n" - "

Not Found

\n" - "The requested URL was not found on this server.\n" - "


" RTSPDVERSION "
\n" "\n"; + "Server: " RTSPDVERSION "\r\n" + "Connection: close\r\n" + "Content-Type: text/html" + END_OF_HEADERS + "\n" + "\n" + "404 Not Found\n" + "\n" + "

Not Found

\n" + "The requested URL was not found on this server.\n" + "


" RTSPDVERSION "
\n" "\n"; /* send back this on RTSP 404 file not found */ static const char *doc404_RTSP = "RTSP/1.0 404 Not Found\r\n" - "Server: " RTSPDVERSION - END_OF_HEADERS; + "Server: " RTSPDVERSION + END_OF_HEADERS; /* Default size to send away fake RTP data */ #define RTP_DATA_SIZE 12 @@ -295,7 +269,7 @@ static int rtspd_ProcessRequest(struct rtspd_httprequest *req) logmsg("instructed to stream"); req->rcmd = RCMD_STREAM; } - else if(1 == sscanf(ptr, "pipe: %d", &num)) { + else if(sscanf(ptr, "pipe: %d", &num) == 1) { logmsg("instructed to allow a pipe size of %d", num); if(num < 0) logmsg("negative pipe size ignored"); @@ -303,7 +277,7 @@ static int rtspd_ProcessRequest(struct rtspd_httprequest *req) req->pipe = num-1; /* decrease by one since we don't count the first request in this number */ } - else if(1 == sscanf(ptr, "skip: %d", &num)) { + else if(sscanf(ptr, "skip: %d", &num) == 1) { logmsg("instructed to skip this number of bytes %d", num); req->skip = num; } @@ -644,7 +618,7 @@ static int rtspd_get_request(curl_socket_t sock, struct rtspd_httprequest *req) /*** end of httprequest init ***/ - while(!done_processing && (req->offset < REQBUFSIZ-1)) { + while(!done_processing && (req->offset < sizeof(req->reqbuf)-1)) { if(pipereq_length && pipereq) { memmove(reqbuf, pipereq, pipereq_length); got = curlx_uztosz(pipereq_length); @@ -657,7 +631,8 @@ static int rtspd_get_request(curl_socket_t sock, struct rtspd_httprequest *req) client wants to send! */ got = sread(sock, reqbuf + req->offset, req->cl); else - got = sread(sock, reqbuf + req->offset, REQBUFSIZ-1 - req->offset); + got = sread(sock, reqbuf + req->offset, + sizeof(req->reqbuf)-1 - req->offset); } if(got_exit_signal) return 1; @@ -692,16 +667,16 @@ static int rtspd_get_request(curl_socket_t sock, struct rtspd_httprequest *req) } } - if((req->offset == REQBUFSIZ-1) && (got > 0)) { + if((req->offset == sizeof(req->reqbuf)-1) && (got > 0)) { logmsg("Request would overflow buffer, closing connection"); /* dump request received so far to external file anyway */ - reqbuf[REQBUFSIZ-1] = '\0'; + reqbuf[sizeof(req->reqbuf)-1] = '\0'; fail = 1; } - else if(req->offset > REQBUFSIZ-1) { + else if(req->offset > sizeof(req->reqbuf)-1) { logmsg("Request buffer overflow, closing connection"); /* dump request received so far to external file anyway */ - reqbuf[REQBUFSIZ-1] = '\0'; + reqbuf[sizeof(req->reqbuf)-1] = '\0'; fail = 1; } else @@ -741,19 +716,19 @@ static int rtspd_send_doc(curl_socket_t sock, struct rtspd_httprequest *req) default: case RCMD_NORMALREQ: break; /* continue with business as usual */ - case RCMD_STREAM: -#define STREAMTHIS "a string to stream 01234567890\n" - count = strlen(STREAMTHIS); + case RCMD_STREAM: { + static const char streamthis[] = "a string to stream 01234567890\n"; for(;;) { - written = swrite(sock, STREAMTHIS, count); + written = swrite(sock, streamthis, sizeof(streamthis)-1); if(got_exit_signal) return -1; - if(written != (ssize_t)count) { + if(written != (ssize_t)(sizeof(streamthis)-1)) { logmsg("Stopped streaming"); break; } } return -1; + } case RCMD_IDLE: /* Do nothing. Sit idle. Pretend it rains. */ return 0; @@ -809,7 +784,7 @@ static int rtspd_send_doc(curl_socket_t sock, struct rtspd_httprequest *req) else { FILE *stream = test2fopen(req->testno, logdir); char partbuf[80]="data"; - if(0 != req->partno) + if(req->partno) snprintf(partbuf, sizeof(partbuf), "data%ld", req->partno); if(!stream) { error = errno; @@ -960,19 +935,19 @@ static int rtspd_send_doc(curl_socket_t sock, struct rtspd_httprequest *req) int num; ptr = cmd; do { - if(2 == sscanf(ptr, "%31s %d", command, &num)) { + if(sscanf(ptr, "%31s %d", command, &num) == 2) { if(!strcmp("wait", command)) { logmsg("Told to sleep for %d seconds", num); quarters = num * 4; while(quarters > 0) { quarters--; - res = wait_ms(250); + res = curlx_wait_ms(250); if(got_exit_signal) break; if(res) { /* should not happen */ error = SOCKERRNO; - logmsg("wait_ms() failed with error (%d) %s", + logmsg("curlx_wait_ms() failed with error (%d) %s", error, sstrerror(error)); break; } @@ -1000,7 +975,7 @@ static int rtspd_send_doc(curl_socket_t sock, struct rtspd_httprequest *req) } -int main(int argc, char *argv[]) +static int test_rtspd(int argc, char *argv[]) { srvr_sockaddr_union_t me; curl_socket_t sock = CURL_SOCKET_BAD; @@ -1124,8 +1099,8 @@ int main(int argc, char *argv[]) } flag = 1; - if(0 != setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, - (void *)&flag, sizeof(flag))) { + if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + (void *)&flag, sizeof(flag))) { error = SOCKERRNO; logmsg("setsockopt(SO_REUSEADDR) failed with error (%d) %s", error, sstrerror(error)); @@ -1150,7 +1125,7 @@ int main(int argc, char *argv[]) rc = bind(sock, &me.sa, sizeof(me.sa6)); } #endif /* USE_IPV6 */ - if(0 != rc) { + if(rc) { error = SOCKERRNO; logmsg("Error binding socket on port %hu (%d) %s", port, error, sstrerror(error)); @@ -1204,7 +1179,7 @@ int main(int argc, char *argv[]) /* start accepting connections */ rc = listen(sock, 5); - if(0 != rc) { + if(rc) { error = SOCKERRNO; logmsg("listen() failed with error (%d) %s", error, sstrerror(error)); @@ -1249,7 +1224,7 @@ int main(int argc, char *argv[]) logmsg("====> Client connect"); -#ifdef TCP_NODELAY +#if defined(TCP_NODELAY) && !defined(__EMSCRIPTEN__) /* * Disable the Nagle algorithm to make it easier to send out a large * response in many small segments to torture the clients more. diff --git a/vendor/curl/tests/server/sockfilt.c b/vendor/curl/tests/server/sockfilt.c index 1e625eacb31..c8b21beee90 100644 --- a/vendor/curl/tests/server/sockfilt.c +++ b/vendor/curl/tests/server/sockfilt.c @@ -21,7 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "server_setup.h" +#include "first.h" /* Purpose * @@ -85,35 +85,8 @@ * it! */ -#ifndef UNDER_CE -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETINET_IN6_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif - -#include /* from the private lib dir */ -#include "inet_pton.h" -#include "util.h" -#include "server_sockaddr.h" -#include "timediff.h" - -#include "tool_binmode.h" - -/* include memdebug.h last */ -#include - /* buffer is this excessively large only to be able to support things like - test 1003 which tests exceedingly large server response lines */ + test 1003 which tests exceedingly large server response lines */ #define BUFFER_SIZE 17010 static bool verbose = FALSE; @@ -396,7 +369,7 @@ static void lograw(unsigned char *buffer, ssize_t len) * *buffer_len is the amount of data in the buffer (output) */ static bool read_data_block(unsigned char *buffer, ssize_t maxlen, - ssize_t *buffer_len) + ssize_t *buffer_len) { if(!read_stdin(buffer, 5)) return FALSE; @@ -581,6 +554,7 @@ static unsigned int WINAPI select_ws_wait_thread(void *lpParameter) return 0; } + static HANDLE select_ws_wait(HANDLE handle, HANDLE signal, HANDLE abort) { typedef uintptr_t curl_win_thread_handle_t; @@ -605,6 +579,7 @@ static HANDLE select_ws_wait(HANDLE handle, HANDLE signal, HANDLE abort) } return NULL; } + struct select_ws_data { int fd; /* provided file descriptor (indexed by nfd) */ long wsastate; /* internal pre-select state (indexed by nfd) */ @@ -613,6 +588,7 @@ struct select_ws_data { HANDLE signal; /* internal thread signal (indexed by nth) */ HANDLE thread; /* internal thread handle (indexed by nth) */ }; + static int select_ws(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *tv) { @@ -989,12 +965,12 @@ static bool juggle(curl_socket_t *sockfdp, FD_ZERO(&fds_write); FD_ZERO(&fds_err); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif FD_SET((curl_socket_t)fileno(stdin), &fds_read); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif @@ -1005,12 +981,12 @@ static bool juggle(curl_socket_t *sockfdp, /* server mode */ sockfd = listenfd; /* there's always a socket to wait for */ -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif FD_SET(sockfd, &fds_read); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif maxfd = (int)sockfd; @@ -1026,12 +1002,12 @@ static bool juggle(curl_socket_t *sockfdp, } else { /* there's always a socket to wait for */ -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif FD_SET(sockfd, &fds_read); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif maxfd = (int)sockfd; @@ -1043,12 +1019,12 @@ static bool juggle(curl_socket_t *sockfdp, sockfd = *sockfdp; /* sockfd turns CURL_SOCKET_BAD when our connection has been closed */ if(CURL_SOCKET_BAD != sockfd) { -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif FD_SET(sockfd, &fds_read); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif maxfd = (int)sockfd; @@ -1144,6 +1120,9 @@ static bool juggle(curl_socket_t *sockfdp, if(!read_data_block(buffer, sizeof(buffer), &buffer_len)) return FALSE; + if(buffer_len < 0) + return FALSE; + if(*mode == PASSIVE_LISTEN) { logmsg("*** We are disconnected!"); if(!disc_handshake()) @@ -1230,150 +1209,7 @@ static bool juggle(curl_socket_t *sockfdp, #endif } -static curl_socket_t sockfilt_sockdaemon(curl_socket_t sock, - unsigned short *listenport, - bool bind_only) -{ - /* passive daemon style */ - srvr_sockaddr_union_t listener; - int flag; - int rc; - int totdelay = 0; - int maxretr = 10; - int delay = 20; - int attempt = 0; - int error = 0; - - do { - attempt++; - flag = 1; - rc = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, - (void *)&flag, sizeof(flag)); - if(rc) { - error = SOCKERRNO; - logmsg("setsockopt(SO_REUSEADDR) failed with error (%d) %s", - error, sstrerror(error)); - if(maxretr) { - rc = wait_ms(delay); - if(rc) { - /* should not happen */ - error = SOCKERRNO; - logmsg("wait_ms() failed with error (%d) %s", - error, sstrerror(error)); - sclose(sock); - return CURL_SOCKET_BAD; - } - if(got_exit_signal) { - logmsg("signalled to die, exiting..."); - sclose(sock); - return CURL_SOCKET_BAD; - } - totdelay += delay; - delay *= 2; /* double the sleep for next attempt */ - } - } - } while(rc && maxretr--); - - if(rc) { - logmsg("setsockopt(SO_REUSEADDR) failed %d times in %d ms. Error (%d) %s", - attempt, totdelay, error, strerror(error)); - logmsg("Continuing anyway..."); - } - - /* When the specified listener port is zero, it is actually a - request to let the system choose a non-zero available port. */ - -#ifdef USE_IPV6 - if(!use_ipv6) { -#endif - memset(&listener.sa4, 0, sizeof(listener.sa4)); - listener.sa4.sin_family = AF_INET; - listener.sa4.sin_addr.s_addr = INADDR_ANY; - listener.sa4.sin_port = htons(*listenport); - rc = bind(sock, &listener.sa, sizeof(listener.sa4)); -#ifdef USE_IPV6 - } - else { - memset(&listener.sa6, 0, sizeof(listener.sa6)); - listener.sa6.sin6_family = AF_INET6; - listener.sa6.sin6_addr = in6addr_any; - listener.sa6.sin6_port = htons(*listenport); - rc = bind(sock, &listener.sa, sizeof(listener.sa6)); - } -#endif /* USE_IPV6 */ - if(rc) { - error = SOCKERRNO; - logmsg("Error binding socket on port %hu (%d) %s", - *listenport, error, sstrerror(error)); - sclose(sock); - return CURL_SOCKET_BAD; - } - - if(!*listenport) { - /* The system was supposed to choose a port number, figure out which - port we actually got and update the listener port value with it. */ - curl_socklen_t la_size; - srvr_sockaddr_union_t localaddr; -#ifdef USE_IPV6 - if(!use_ipv6) -#endif - la_size = sizeof(localaddr.sa4); -#ifdef USE_IPV6 - else - la_size = sizeof(localaddr.sa6); -#endif - memset(&localaddr.sa, 0, (size_t)la_size); - if(getsockname(sock, &localaddr.sa, &la_size) < 0) { - error = SOCKERRNO; - logmsg("getsockname() failed with error (%d) %s", - error, sstrerror(error)); - sclose(sock); - return CURL_SOCKET_BAD; - } - switch(localaddr.sa.sa_family) { - case AF_INET: - *listenport = ntohs(localaddr.sa4.sin_port); - break; -#ifdef USE_IPV6 - case AF_INET6: - *listenport = ntohs(localaddr.sa6.sin6_port); - break; -#endif - default: - break; - } - if(!*listenport) { - /* Real failure, listener port shall not be zero beyond this point. */ - logmsg("Apparently getsockname() succeeded, with listener port zero."); - logmsg("A valid reason for this failure is a binary built without"); - logmsg("proper network library linkage. This might not be the only"); - logmsg("reason, but double check it before anything else."); - sclose(sock); - return CURL_SOCKET_BAD; - } - } - - /* bindonly option forces no listening */ - if(bind_only) { - logmsg("instructed to bind port without listening"); - return sock; - } - - /* start accepting connections */ - rc = listen(sock, 5); - if(0 != rc) { - error = SOCKERRNO; - logmsg("listen() failed with error (%d) %s", - error, sstrerror(error)); - sclose(sock); - return CURL_SOCKET_BAD; - } - - return sock; -} - - -int main(int argc, char *argv[]) +static int test_sockfilt(int argc, char *argv[]) { srvr_sockaddr_union_t me; curl_socket_t sock = CURL_SOCKET_BAD; @@ -1423,16 +1259,16 @@ int main(int argc, char *argv[]) } else if(!strcmp("--ipv6", argv[arg])) { #ifdef USE_IPV6 + socket_domain = AF_INET6; ipv_inuse = "IPv6"; - use_ipv6 = TRUE; #endif arg++; } else if(!strcmp("--ipv4", argv[arg])) { /* for completeness, we support this option as well */ #ifdef USE_IPV6 + socket_domain = AF_INET; ipv_inuse = "IPv4"; - use_ipv6 = FALSE; #endif arg++; } @@ -1496,20 +1332,13 @@ int main(int argc, char *argv[]) return 2; #endif - CURL_SET_BINMODE(stdin); - CURL_SET_BINMODE(stdout); - CURL_SET_BINMODE(stderr); + CURLX_SET_BINMODE(stdin); + CURLX_SET_BINMODE(stdout); + CURLX_SET_BINMODE(stderr); install_signal_handlers(false); -#ifdef USE_IPV6 - if(!use_ipv6) -#endif - sock = socket(AF_INET, SOCK_STREAM, 0); -#ifdef USE_IPV6 - else - sock = socket(AF_INET6, SOCK_STREAM, 0); -#endif + sock = socket(socket_domain, SOCK_STREAM, 0); if(CURL_SOCKET_BAD == sock) { error = SOCKERRNO; @@ -1521,31 +1350,33 @@ int main(int argc, char *argv[]) if(server_connectport) { /* Active mode, we should connect to the given port number */ mode = ACTIVE; + switch(socket_domain) { + case AF_INET: + memset(&me.sa4, 0, sizeof(me.sa4)); + me.sa4.sin_family = AF_INET; + me.sa4.sin_port = htons(server_connectport); + me.sa4.sin_addr.s_addr = INADDR_ANY; + if(!addr) + addr = "127.0.0.1"; + curlx_inet_pton(AF_INET, addr, &me.sa4.sin_addr); + + rc = connect(sock, &me.sa, sizeof(me.sa4)); + break; #ifdef USE_IPV6 - if(!use_ipv6) { -#endif - memset(&me.sa4, 0, sizeof(me.sa4)); - me.sa4.sin_family = AF_INET; - me.sa4.sin_port = htons(server_connectport); - me.sa4.sin_addr.s_addr = INADDR_ANY; - if(!addr) - addr = "127.0.0.1"; - curlx_inet_pton(AF_INET, addr, &me.sa4.sin_addr); - - rc = connect(sock, &me.sa, sizeof(me.sa4)); -#ifdef USE_IPV6 - } - else { - memset(&me.sa6, 0, sizeof(me.sa6)); - me.sa6.sin6_family = AF_INET6; - me.sa6.sin6_port = htons(server_connectport); - if(!addr) - addr = "::1"; - curlx_inet_pton(AF_INET6, addr, &me.sa6.sin6_addr); - - rc = connect(sock, &me.sa, sizeof(me.sa6)); - } + case AF_INET6: + memset(&me.sa6, 0, sizeof(me.sa6)); + me.sa6.sin6_family = AF_INET6; + me.sa6.sin6_port = htons(server_connectport); + if(!addr) + addr = "::1"; + curlx_inet_pton(AF_INET6, addr, &me.sa6.sin6_addr); + + rc = connect(sock, &me.sa, sizeof(me.sa6)); + break; #endif /* USE_IPV6 */ + default: + rc = 1; + } if(rc) { error = SOCKERRNO; logmsg("Error connecting to port %hu (%d) %s", @@ -1558,7 +1389,7 @@ int main(int argc, char *argv[]) } else { /* passive daemon style */ - sock = sockfilt_sockdaemon(sock, &server_port, s_bind_only); + sock = sockdaemon(sock, &server_port, NULL, s_bind_only); if(CURL_SOCKET_BAD == sock) { write_stdout("FAIL\n", 5); goto sockfilt_cleanup; diff --git a/vendor/curl/tests/server/socksd.c b/vendor/curl/tests/server/socksd.c index f5df0eff441..4d599e16b61 100644 --- a/vendor/curl/tests/server/socksd.c +++ b/vendor/curl/tests/server/socksd.c @@ -21,7 +21,8 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "server_setup.h" +#include "first.h" + #include /* Function @@ -57,31 +58,6 @@ /* based on sockfilt.c */ -#ifndef UNDER_CE -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETINET_IN6_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif - -#include /* from the private lib dir */ -#include "inet_pton.h" -#include "util.h" -#include "server_sockaddr.h" -#include "tool_binmode.h" - -/* include memdebug.h last */ -#include - static const char *backendaddr = "127.0.0.1"; static unsigned short backendport = 0; /* default is use client's */ @@ -146,7 +122,7 @@ static void socksd_getconfig(void) while(fgets(buffer, sizeof(buffer), fp)) { char key[32]; char value[260]; - if(2 == sscanf(buffer, "%31s %259s", key, value)) { + if(sscanf(buffer, "%31s %259s", key, value) == 2) { if(!strcmp(key, "version")) { s_config.version = byteval(value); logmsg("version [%d] set", s_config.version); @@ -653,35 +629,35 @@ static bool socksd_incoming(curl_socket_t listenfd) FD_ZERO(&fds_err); /* there's always a socket to wait for */ -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif FD_SET(sockfd, &fds_read); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif for(i = 0; i < 2; i++) { if(c[i].used) { curl_socket_t fd = c[i].clientfd; -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif FD_SET(fd, &fds_read); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif if((int)fd > maxfd) maxfd = (int)fd; fd = c[i].remotefd; -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif FD_SET(fd, &fds_read); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif if((int)fd > maxfd) @@ -754,167 +730,7 @@ static bool socksd_incoming(curl_socket_t listenfd) return TRUE; } -static curl_socket_t socksd_sockdaemon(curl_socket_t sock, - unsigned short *listenport, - const char *unix_socket, - bool bind_only) -{ - /* passive daemon style */ - srvr_sockaddr_union_t listener; - int flag; - int rc; - int totdelay = 0; - int maxretr = 10; - int delay = 20; - int attempt = 0; - int error = 0; - -#ifndef USE_UNIX_SOCKETS - (void)unix_socket; -#endif - - do { - attempt++; - flag = 1; - rc = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, - (void *)&flag, sizeof(flag)); - if(rc) { - error = SOCKERRNO; - logmsg("setsockopt(SO_REUSEADDR) failed with error (%d) %s", - error, sstrerror(error)); - if(maxretr) { - rc = wait_ms(delay); - if(rc) { - /* should not happen */ - error = SOCKERRNO; - logmsg("wait_ms() failed with error (%d) %s", - error, sstrerror(error)); - sclose(sock); - return CURL_SOCKET_BAD; - } - if(got_exit_signal) { - logmsg("signalled to die, exiting..."); - sclose(sock); - return CURL_SOCKET_BAD; - } - totdelay += delay; - delay *= 2; /* double the sleep for next attempt */ - } - } - } while(rc && maxretr--); - - if(rc) { - logmsg("setsockopt(SO_REUSEADDR) failed %d times in %d ms. Error (%d) %s", - attempt, totdelay, error, strerror(error)); - logmsg("Continuing anyway..."); - } - - /* When the specified listener port is zero, it is actually a - request to let the system choose a non-zero available port. */ - - switch(socket_domain) { - case AF_INET: - memset(&listener.sa4, 0, sizeof(listener.sa4)); - listener.sa4.sin_family = AF_INET; - listener.sa4.sin_addr.s_addr = INADDR_ANY; - listener.sa4.sin_port = htons(*listenport); - rc = bind(sock, &listener.sa, sizeof(listener.sa4)); - break; -#ifdef USE_IPV6 - case AF_INET6: - memset(&listener.sa6, 0, sizeof(listener.sa6)); - listener.sa6.sin6_family = AF_INET6; - listener.sa6.sin6_addr = in6addr_any; - listener.sa6.sin6_port = htons(*listenport); - rc = bind(sock, &listener.sa, sizeof(listener.sa6)); - break; -#endif /* USE_IPV6 */ -#ifdef USE_UNIX_SOCKETS - case AF_UNIX: - rc = bind_unix_socket(sock, unix_socket, &listener.sau); -#endif - } - - if(rc) { - error = SOCKERRNO; -#ifdef USE_UNIX_SOCKETS - if(socket_domain == AF_UNIX) - logmsg("Error binding socket on path %s (%d) %s", - unix_socket, error, sstrerror(error)); - else -#endif - logmsg("Error binding socket on port %hu (%d) %s", - *listenport, error, sstrerror(error)); - sclose(sock); - return CURL_SOCKET_BAD; - } - - if(!*listenport -#ifdef USE_UNIX_SOCKETS - && !unix_socket -#endif - ) { - /* The system was supposed to choose a port number, figure out which - port we actually got and update the listener port value with it. */ - curl_socklen_t la_size; - srvr_sockaddr_union_t localaddr; -#ifdef USE_IPV6 - if(socket_domain == AF_INET6) - la_size = sizeof(localaddr.sa6); - else -#endif - la_size = sizeof(localaddr.sa4); - memset(&localaddr.sa, 0, (size_t)la_size); - if(getsockname(sock, &localaddr.sa, &la_size) < 0) { - error = SOCKERRNO; - logmsg("getsockname() failed with error (%d) %s", - error, sstrerror(error)); - sclose(sock); - return CURL_SOCKET_BAD; - } - switch(localaddr.sa.sa_family) { - case AF_INET: - *listenport = ntohs(localaddr.sa4.sin_port); - break; -#ifdef USE_IPV6 - case AF_INET6: - *listenport = ntohs(localaddr.sa6.sin6_port); - break; -#endif - default: - break; - } - if(!*listenport) { - /* Real failure, listener port shall not be zero beyond this point. */ - logmsg("Apparently getsockname() succeeded, with listener port zero."); - logmsg("A valid reason for this failure is a binary built without"); - logmsg("proper network library linkage. This might not be the only"); - logmsg("reason, but double check it before anything else."); - sclose(sock); - return CURL_SOCKET_BAD; - } - } - - /* bindonly option forces no listening */ - if(bind_only) { - logmsg("instructed to bind port without listening"); - return sock; - } - - /* start accepting connections */ - rc = listen(sock, 5); - if(0 != rc) { - error = SOCKERRNO; - logmsg("listen() failed with error (%d) %s", error, sstrerror(error)); - sclose(sock); - return CURL_SOCKET_BAD; - } - - return sock; -} - - -int main(int argc, char *argv[]) +static int test_socksd(int argc, char *argv[]) { curl_socket_t sock = CURL_SOCKET_BAD; curl_socket_t msgsock = CURL_SOCKET_BAD; @@ -1045,9 +861,9 @@ int main(int argc, char *argv[]) return 2; #endif - CURL_SET_BINMODE(stdin); - CURL_SET_BINMODE(stdout); - CURL_SET_BINMODE(stderr); + CURLX_SET_BINMODE(stdin); + CURLX_SET_BINMODE(stdout); + CURLX_SET_BINMODE(stderr); install_signal_handlers(false); @@ -1062,7 +878,7 @@ int main(int argc, char *argv[]) { /* passive daemon style */ - sock = socksd_sockdaemon(sock, &server_port, unix_socket, FALSE); + sock = sockdaemon(sock, &server_port, unix_socket, FALSE); if(CURL_SOCKET_BAD == sock) { goto socks5_cleanup; } diff --git a/vendor/curl/tests/server/sws.c b/vendor/curl/tests/server/sws.c index 67a01cfdc08..2b94e529383 100644 --- a/vendor/curl/tests/server/sws.c +++ b/vendor/curl/tests/server/sws.c @@ -21,7 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "server_setup.h" +#include "first.h" /* sws.c: simple (silly?) web server @@ -30,40 +30,13 @@ */ -#ifndef UNDER_CE -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETINET_IN6_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif #ifdef HAVE_NETINET_TCP_H #include /* for TCP_NODELAY */ #endif -#include /* from the private lib dir */ -#include "getpart.h" -#include "inet_pton.h" -#include "util.h" -#include "server_sockaddr.h" - -/* include memdebug.h last */ -#include - static bool use_gopher = FALSE; static bool is_proxy = FALSE; -#undef REQBUFSIZ -#define REQBUFSIZ (2*1024*1024) - #define MAX_SLEEP_TIME_MS 250 static long sws_prevtestno = -1; /* previous test number we served */ @@ -78,7 +51,7 @@ static bool sws_prevbounce = FALSE; /* instructs the server to override the #define RCMD_STREAM 2 /* told to stream */ struct sws_httprequest { - char reqbuf[REQBUFSIZ]; /* buffer area for the incoming request */ + char reqbuf[2*1024*1024]; /* buffer area for the incoming request */ bool connect_request; /* if a CONNECT */ unsigned short connect_port; /* the port number CONNECT used */ size_t checkindex; /* where to start checking of the request */ @@ -170,22 +143,22 @@ static const char *docquit_sws = /* send back this on 404 file not found */ static const char *doc404 = "HTTP/1.1 404 Not Found\r\n" - "Server: " SWSVERSION "\r\n" - "Connection: close\r\n" - "Content-Type: text/html" - END_OF_HEADERS - "\n" - "\n" - "404 Not Found\n" - "\n" - "

Not Found

\n" - "The requested URL was not found on this server.\n" - "


" SWSVERSION "
\n" "\n"; + "Server: " SWSVERSION "\r\n" + "Connection: close\r\n" + "Content-Type: text/html" + END_OF_HEADERS + "\n" + "\n" + "404 Not Found\n" + "\n" + "

Not Found

\n" + "The requested URL was not found on this server.\n" + "


" SWSVERSION "
\n" "\n"; /* work around for handling trailing headers */ static int already_recv_zeroed_chunk = FALSE; -#ifdef TCP_NODELAY +#if defined(TCP_NODELAY) && defined(CURL_TCP_NODELAY_SUPPORTED) /* returns true if the current socket is an IP one */ static bool socket_domain_is_ip(void) { @@ -210,7 +183,7 @@ static int parse_cmdfile(struct sws_httprequest *req) int testnum = DOCNUMBER_NOTHING; char buf[256]; while(fgets(buf, sizeof(buf), f)) { - if(1 == sscanf(buf, "Testnum %d", &testnum)) { + if(sscanf(buf, "Testnum %d", &testnum) == 1) { logmsg("[%s] cmdfile says testnum %d", cmdfile, testnum); req->testno = testnum; } @@ -282,7 +255,7 @@ static int sws_parse_servercmd(struct sws_httprequest *req) logmsg("swsclose: close this connection after response"); req->close = TRUE; } - else if(1 == sscanf(cmd, "skip: %d", &num)) { + else if(sscanf(cmd, "skip: %d", &num) == 1) { logmsg("instructed to skip this number of bytes %d", num); req->skip = num; } @@ -290,11 +263,11 @@ static int sws_parse_servercmd(struct sws_httprequest *req) logmsg("instructed to reject Expect: 100-continue"); req->noexpect = TRUE; } - else if(1 == sscanf(cmd, "delay: %d", &num)) { + else if(sscanf(cmd, "delay: %d", &num) == 1) { logmsg("instructed to delay %d msecs after connect", num); req->delay = num; } - else if(1 == sscanf(cmd, "writedelay: %d", &num)) { + else if(sscanf(cmd, "writedelay: %d", &num) == 1) { logmsg("instructed to delay %d msecs between packets", num); req->writedelay = num; } @@ -432,7 +405,6 @@ static int sws_ProcessRequest(struct sws_httprequest *req) logmsg("No test number in path"); req->testno = DOCNUMBER_NOTHING; } - } if(req->testno == DOCNUMBER_NOTHING) { @@ -839,7 +811,8 @@ static int sws_get_request(curl_socket_t sock, struct sws_httprequest *req) if(req->open) { logmsg("wait for websocket traffic"); do { - got = sread(sock, reqbuf + req->offset, REQBUFSIZ - req->offset); + got = sread(sock, reqbuf + req->offset, + sizeof(req->reqbuf) - req->offset); if(got > 0) { req->offset += got; logmsg("Got %zu bytes from client", got); @@ -857,12 +830,12 @@ static int sws_get_request(curl_socket_t sock, struct sws_httprequest *req) FD_ZERO(&input); FD_ZERO(&output); got = 0; -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif FD_SET(sock, &input); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif do { @@ -890,7 +863,7 @@ static int sws_get_request(curl_socket_t sock, struct sws_httprequest *req) return -1; } - if(req->offset >= REQBUFSIZ-1) { + if(req->offset >= sizeof(req->reqbuf)-1) { /* buffer is already full; do nothing */ overflow = 1; } @@ -901,7 +874,8 @@ static int sws_get_request(curl_socket_t sock, struct sws_httprequest *req) client wants to send! */ got = sread(sock, reqbuf + req->offset, req->cl); else - got = sread(sock, reqbuf + req->offset, REQBUFSIZ-1 - req->offset); + got = sread(sock, reqbuf + req->offset, + sizeof(req->reqbuf)-1 - req->offset); if(got_exit_signal) return -1; @@ -935,16 +909,16 @@ static int sws_get_request(curl_socket_t sock, struct sws_httprequest *req) return -1; } - if(overflow || (req->offset == REQBUFSIZ-1 && got > 0)) { + if(overflow || (req->offset == sizeof(req->reqbuf)-1 && got > 0)) { logmsg("Request would overflow buffer, closing connection"); /* dump request received so far to external file anyway */ - reqbuf[REQBUFSIZ-1] = '\0'; + reqbuf[sizeof(req->reqbuf)-1] = '\0'; fail = 1; } - else if(req->offset > REQBUFSIZ-1) { + else if(req->offset > sizeof(req->reqbuf)-1) { logmsg("Request buffer overflow, closing connection"); /* dump request received so far to external file anyway */ - reqbuf[REQBUFSIZ-1] = '\0'; + reqbuf[sizeof(req->reqbuf)-1] = '\0'; fail = 1; } else @@ -985,19 +959,19 @@ static int sws_send_doc(curl_socket_t sock, struct sws_httprequest *req) default: case RCMD_NORMALREQ: break; /* continue with business as usual */ - case RCMD_STREAM: -#define STREAMTHIS "a string to stream 01234567890\n" - count = strlen(STREAMTHIS); + case RCMD_STREAM: { + static const char streamthis[] = "a string to stream 01234567890\n"; for(;;) { - written = swrite(sock, STREAMTHIS, count); + written = swrite(sock, streamthis, sizeof(streamthis)-1); if(got_exit_signal) return -1; - if(written != (ssize_t)count) { + if(written != (ssize_t)(sizeof(streamthis)-1)) { logmsg("Stopped streaming"); break; } } return -1; + } case RCMD_IDLE: /* Do nothing. Sit idle. Pretend it rains. */ return 0; @@ -1135,7 +1109,7 @@ static int sws_send_doc(curl_socket_t sock, struct sws_httprequest *req) written = swrite(sock, buffer, num); if(written < 0) { if((SOCKEWOULDBLOCK == SOCKERRNO) || (EAGAIN == SOCKERRNO)) { - wait_ms(10); + curlx_wait_ms(10); goto retry; } sendfailure = TRUE; @@ -1159,7 +1133,7 @@ static int sws_send_doc(curl_socket_t sock, struct sws_httprequest *req) int sleep_time = msecs_left > MAX_SLEEP_TIME_MS ? MAX_SLEEP_TIME_MS : msecs_left; intervals--; - wait_ms(sleep_time); + curlx_wait_ms(sleep_time); msecs_left -= sleep_time; } } @@ -1197,17 +1171,17 @@ static int sws_send_doc(curl_socket_t sock, struct sws_httprequest *req) int num; ptr = cmd; do { - if(2 == sscanf(ptr, "%31s %d", command, &num)) { + if(sscanf(ptr, "%31s %d", command, &num) == 2) { if(!strcmp("wait", command)) { logmsg("Told to sleep for %d seconds", num); quarters = num * 4; while((quarters > 0) && !got_exit_signal) { quarters--; - res = wait_ms(250); + res = curlx_wait_ms(250); if(res) { /* should not happen */ error = SOCKERRNO; - logmsg("wait_ms() failed with error (%d) %s", + logmsg("curlx_wait_ms() failed with error (%d) %s", error, sstrerror(error)); break; } @@ -1265,12 +1239,12 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port) return CURL_SOCKET_BAD; } -#ifdef TCP_NODELAY +#if defined(TCP_NODELAY) && defined(CURL_TCP_NODELAY_SUPPORTED) if(socket_domain_is_ip()) { /* Disable the Nagle algorithm */ curl_socklen_t flag = 1; - if(0 != setsockopt(serverfd, IPPROTO_TCP, TCP_NODELAY, - (void *)&flag, sizeof(flag))) + if(setsockopt(serverfd, IPPROTO_TCP, TCP_NODELAY, + (void *)&flag, sizeof(flag))) logmsg("====> TCP_NODELAY for server connection failed"); } #endif @@ -1278,7 +1252,7 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port) /* We want to do the connect() in a non-blocking mode, since * Windows has an internal retry logic that may lead to long * timeouts if the peer is not listening. */ - if(0 != curlx_nonblock(serverfd, TRUE)) { + if(curlx_nonblock(serverfd, TRUE)) { error = SOCKERRNO; logmsg("curlx_nonblock(TRUE) failed with error (%d) %s", error, sstrerror(error)); @@ -1333,12 +1307,12 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port) timeout.tv_sec = 1; /* 1000 ms */ FD_ZERO(&output); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif FD_SET(serverfd, &output); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif while(1) { @@ -1347,10 +1321,10 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port) goto error; else if(rc > 0) { curl_socklen_t errSize = sizeof(error); - if(0 != getsockopt(serverfd, SOL_SOCKET, SO_ERROR, - (void *)&error, &errSize)) + if(getsockopt(serverfd, SOL_SOCKET, SO_ERROR, + (void *)&error, &errSize)) error = SOCKERRNO; - if((0 == error) || (SOCKEISCONN == error)) + if((error == 0) || (SOCKEISCONN == error)) goto success; else if((error != SOCKEINPROGRESS) && (error != SOCKEWOULDBLOCK)) goto error; @@ -1372,7 +1346,7 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port) logmsg("connected fine to %s%s%s:%hu, now tunnel", op_br, ipaddr, cl_br, port); - if(0 != curlx_nonblock(serverfd, FALSE)) { + if(curlx_nonblock(serverfd, FALSE)) { error = SOCKERRNO; logmsg("curlx_nonblock(FALSE) failed with error (%d) %s", error, sstrerror(error)); @@ -1430,7 +1404,7 @@ static void http_connect(curl_socket_t *infdp, 'end of headers' separate from the server data that follows. This is done to prevent triggering libcurl known bug #39. */ for(loop = 2; (loop > 0) && !got_exit_signal; loop--) - wait_ms(250); + curlx_wait_ms(250); if(got_exit_signal) goto http_connect_cleanup; @@ -1465,12 +1439,12 @@ static void http_connect(curl_socket_t *infdp, /* listener socket is monitored to allow client to establish secondary tunnel only when this tunnel is not established and primary one is fully operational */ -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif FD_SET(rootfd, &input); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif maxfd = rootfd; @@ -1482,12 +1456,12 @@ static void http_connect(curl_socket_t *infdp, if(clientfd[i] != CURL_SOCKET_BAD) { if(poll_client_rd[i]) { /* unless told not to do so, monitor readability */ -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif FD_SET(clientfd[i], &input); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif if(clientfd[i] > maxfd) @@ -1496,12 +1470,12 @@ static void http_connect(curl_socket_t *infdp, if(poll_client_wr[i] && toc[i]) { /* unless told not to do so, monitor writability if there is data ready to be sent to client */ -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif FD_SET(clientfd[i], &output); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif if(clientfd[i] > maxfd) @@ -1512,12 +1486,12 @@ static void http_connect(curl_socket_t *infdp, if(serverfd[i] != CURL_SOCKET_BAD) { if(poll_server_rd[i]) { /* unless told not to do so, monitor readability */ -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif FD_SET(serverfd[i], &input); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif if(serverfd[i] > maxfd) @@ -1526,12 +1500,12 @@ static void http_connect(curl_socket_t *infdp, if(poll_server_wr[i] && tos[i]) { /* unless told not to do so, monitor writability if there is data ready to be sent to server */ -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif FD_SET(serverfd[i], &output); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif if(serverfd[i] > maxfd) @@ -1571,12 +1545,12 @@ static void http_connect(curl_socket_t *infdp, } memset(req2, 0, sizeof(*req2)); logmsg("====> Client connect DATA"); -#ifdef TCP_NODELAY +#if defined(TCP_NODELAY) && defined(CURL_TCP_NODELAY_SUPPORTED) if(socket_domain_is_ip()) { /* Disable the Nagle algorithm */ curl_socklen_t flag = 1; - if(0 != setsockopt(datafd, IPPROTO_TCP, TCP_NODELAY, - (void *)&flag, sizeof(flag))) + if(setsockopt(datafd, IPPROTO_TCP, TCP_NODELAY, + (void *)&flag, sizeof(flag))) logmsg("====> TCP_NODELAY for client DATA connection failed"); } #endif @@ -1595,7 +1569,7 @@ static void http_connect(curl_socket_t *infdp, if(!err && req2->connect_request) { /* sleep to prevent triggering libcurl known bug #39. */ for(loop = 2; (loop > 0) && !got_exit_signal; loop--) - wait_ms(250); + curlx_wait_ms(250); if(!got_exit_signal) { /* connect to the server */ serverfd[SWS_DATA] = connect_to(ipaddr, req2->connect_port); @@ -1749,7 +1723,7 @@ static void http_connect(curl_socket_t *infdp, if(tcp_fin_wr) /* allow kernel to place FIN bit packet on the wire */ - wait_ms(250); + curlx_wait_ms(250); /* socket clearing */ for(i = 0; i <= max_tunnel_idx; i++) { @@ -1865,7 +1839,7 @@ static curl_socket_t accept_connection(curl_socket_t sock) return CURL_SOCKET_BAD; } - if(0 != curlx_nonblock(msgsock, TRUE)) { + if(curlx_nonblock(msgsock, TRUE)) { error = SOCKERRNO; logmsg("curlx_nonblock failed with error (%d) %s", error, sstrerror(error)); @@ -1873,8 +1847,8 @@ static curl_socket_t accept_connection(curl_socket_t sock) return CURL_SOCKET_BAD; } - if(0 != setsockopt(msgsock, SOL_SOCKET, SO_KEEPALIVE, - (void *)&flag, sizeof(flag))) { + if(setsockopt(msgsock, SOL_SOCKET, SO_KEEPALIVE, + (void *)&flag, sizeof(flag))) { error = SOCKERRNO; logmsg("setsockopt(SO_KEEPALIVE) failed with error (%d) %s", error, sstrerror(error)); @@ -1897,14 +1871,14 @@ static curl_socket_t accept_connection(curl_socket_t sock) all_sockets[num_sockets] = msgsock; num_sockets += 1; -#ifdef TCP_NODELAY +#if defined(TCP_NODELAY) && defined(CURL_TCP_NODELAY_SUPPORTED) if(socket_domain_is_ip()) { /* * Disable the Nagle algorithm to make it easier to send out a large * response in many small segments to torture the clients more. */ - if(0 != setsockopt(msgsock, IPPROTO_TCP, TCP_NODELAY, - (void *)&flag, sizeof(flag))) + if(setsockopt(msgsock, IPPROTO_TCP, TCP_NODELAY, + (void *)&flag, sizeof(flag))) logmsg("====> TCP_NODELAY failed"); } #endif @@ -1989,7 +1963,7 @@ static int service_connection(curl_socket_t msgsock, return -1; } -int main(int argc, char *argv[]) +static int test_sws(int argc, char *argv[]) { srvr_sockaddr_union_t me; curl_socket_t sock = CURL_SOCKET_BAD; @@ -2188,14 +2162,14 @@ int main(int argc, char *argv[]) } flag = 1; - if(0 != setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, - (void *)&flag, sizeof(flag))) { + if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + (void *)&flag, sizeof(flag))) { error = SOCKERRNO; logmsg("setsockopt(SO_REUSEADDR) failed with error (%d) %s", error, sstrerror(error)); goto sws_cleanup; } - if(0 != curlx_nonblock(sock, TRUE)) { + if(curlx_nonblock(sock, TRUE)) { error = SOCKERRNO; logmsg("curlx_nonblock failed with error (%d) %s", error, sstrerror(error)); @@ -2224,7 +2198,7 @@ int main(int argc, char *argv[]) rc = bind_unix_socket(sock, unix_socket, &me.sau); #endif /* USE_UNIX_SOCKETS */ } - if(0 != rc) { + if(rc) { error = SOCKERRNO; #ifdef USE_UNIX_SOCKETS if(socket_domain == AF_UNIX) @@ -2290,7 +2264,7 @@ int main(int argc, char *argv[]) /* start accepting connections */ rc = listen(sock, 50); - if(0 != rc) { + if(rc) { error = SOCKERRNO; logmsg("listen() failed with error (%d) %s", error, sstrerror(error)); goto sws_cleanup; @@ -2348,12 +2322,12 @@ int main(int argc, char *argv[]) for(socket_idx = 0; socket_idx < num_sockets; ++socket_idx) { /* Listen on all sockets */ -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warith-conversion" #endif FD_SET(all_sockets[socket_idx], &input); -#if defined(__DJGPP__) +#ifdef __DJGPP__ #pragma GCC diagnostic pop #endif if(all_sockets[socket_idx] > maxfd) @@ -2393,7 +2367,7 @@ int main(int argc, char *argv[]) if(CURL_SOCKET_BAD == msgsock) goto sws_cleanup; if(req->delay) - wait_ms(req->delay); + curlx_wait_ms(req->delay); } while(msgsock > 0); active--; } @@ -2425,7 +2399,7 @@ int main(int argc, char *argv[]) wait a very small amount of time before doing so. If this is not done client might get an ECONNRESET before reading a single byte of server-reply. */ - wait_ms(50); + curlx_wait_ms(50); if(all_sockets[socket_idx] != CURL_SOCKET_BAD) { sclose(all_sockets[socket_idx]); diff --git a/vendor/curl/tests/server/tftpd.c b/vendor/curl/tests/server/tftpd.c index 8b936eea785..193afac1377 100644 --- a/vendor/curl/tests/server/tftpd.c +++ b/vendor/curl/tests/server/tftpd.c @@ -49,30 +49,16 @@ * * SPDX-License-Identifier: BSD-4-Clause-UC */ - -#include "server_setup.h" +#include "first.h" #ifdef HAVE_SYS_IOCTL_H -#include -#endif -#ifndef UNDER_CE -#include +#include /* for ioctl() */ #endif #ifdef HAVE_FCNTL_H #include #endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif #ifdef HAVE_SYS_FILIO_H -/* FIONREAD on Solaris 7 */ -#include +#include /* FIONREAD on Solaris 7 */ #endif #include @@ -83,14 +69,40 @@ #include -#include /* from the private lib dir */ -#include "getpart.h" -#include "util.h" -#include "server_sockaddr.h" -#include "tftp.h" +/***************************************************************************** +* This is a rewrite/clone of the arpa/tftp.h file for systems without it. * +*****************************************************************************/ +#define SEGSIZE 512 /* data segment size */ + +#if defined(__GNUC__) && ((__GNUC__ >= 3) || \ + ((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 7))) +# define PACKED_STRUCT __attribute__((__packed__)) +#else +# define PACKED_STRUCT /* NOTHING */ +#endif -/* include memdebug.h last */ -#include +/* Using a packed struct as binary in a program is begging for problems, but + the tftpd server was written like this so we have this struct here to make + things build. */ + +struct tftphdr { + unsigned short th_opcode; /* packet type */ + unsigned short th_block; /* all sorts of things */ + char th_data[1]; /* data or error string */ +} PACKED_STRUCT; + +#define th_stuff th_block +#define th_code th_block +#define th_msg th_data + +#define TFTP_EUNDEF 0 +#define TFTP_ENOTFOUND 1 +#define TFTP_EACCESS 2 +#define TFTP_ENOSPACE 3 +#define TFTP_EBADOP 4 +#define TFTP_EBADID 5 +#define TFTP_EEXISTS 6 +#define TFTP_ENOUSER 7 /***************************************************************************** * STRUCT DECLARATIONS AND DEFINES * @@ -147,9 +159,6 @@ struct bf { #define TIMEOUT 5 -#undef MIN -#define MIN(x,y) ((x)<(y)?(x):(y)) - #define REQUEST_DUMP "server.input" /***************************************************************************** @@ -360,7 +369,7 @@ static void read_ahead(struct testcase *test, if(convert == 0) { /* The former file reading code did this: b->counter = read(fileno(file), dp->th_data, SEGSIZE); */ - size_t copy_n = MIN(SEGSIZE, test->rcount); + size_t copy_n = CURLMIN(SEGSIZE, test->rcount); memcpy(dp->th_data, test->rptr, copy_n); /* decrease amount, advance pointer */ @@ -472,7 +481,7 @@ static ssize_t write_behind(struct testcase *test, int convert) } /* formerly putc(c, file); */ - if(1 != write(test->ofile, &c, 1)) + if(write(test->ofile, &c, 1) != 1) break; skipit: prevchar = c; @@ -499,15 +508,15 @@ static int synchnet(curl_socket_t f /* socket to flush */) curl_socklen_t fromaddrlen; for(;;) { -#if defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO) +#ifdef HAVE_IOCTLSOCKET_CAMEL_FIONBIO long i; - (void) IoctlSocket(f, FIONBIO, &i); + (void)IoctlSocket(f, FIONBIO, &i); #elif defined(HAVE_IOCTLSOCKET) unsigned long i; - (void) ioctlsocket(f, FIONREAD, &i); + (void)ioctlsocket(f, FIONREAD, &i); #else int i; - (void) ioctl(f, FIONREAD, &i); + (void)ioctl(f, FIONREAD, &i); #endif if(i) { j++; @@ -519,8 +528,8 @@ static int synchnet(curl_socket_t f /* socket to flush */) else fromaddrlen = sizeof(fromaddr.sa6); #endif - (void) recvfrom(f, rbuf, sizeof(rbuf), 0, - &fromaddr.sa, &fromaddrlen); + (void)recvfrom(f, rbuf, sizeof(rbuf), 0, + &fromaddr.sa, &fromaddrlen); } else break; @@ -528,7 +537,7 @@ static int synchnet(curl_socket_t f /* socket to flush */) return j; } -int main(int argc, char **argv) +static int test_tftpd(int argc, char **argv) { srvr_sockaddr_union_t me; struct tftphdr *tp; @@ -653,8 +662,8 @@ int main(int argc, char **argv) } flag = 1; - if(0 != setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, - (void *)&flag, sizeof(flag))) { + if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + (void *)&flag, sizeof(flag))) { error = SOCKERRNO; logmsg("setsockopt(SO_REUSEADDR) failed with error (%d) %s", error, sstrerror(error)); @@ -680,7 +689,7 @@ int main(int argc, char **argv) rc = bind(sock, &me.sa, sizeof(me.sa6)); } #endif /* USE_IPV6 */ - if(0 != rc) { + if(rc) { error = SOCKERRNO; logmsg("Error binding socket on port %hu (%d) %s", port, error, sstrerror(error)); @@ -826,7 +835,6 @@ int main(int argc, char **argv) } logmsg("end of one transfer"); - } tftpd_cleanup: @@ -1021,7 +1029,7 @@ static int tftpd_parse_servercmd(struct testcase *req) cmd = orgcmd; while(cmd && cmdsize) { char *check; - if(1 == sscanf(cmd, "writedelay: %d", &num)) { + if(sscanf(cmd, "writedelay: %d", &num) == 1) { logmsg("instructed to delay %d secs between packets", num); req->writedelay = num; } @@ -1110,7 +1118,7 @@ static int validate_access(struct testcase *test, stream = test2fopen(testno, logdir); - if(0 != partno) + if(partno) snprintf(partbuf, sizeof(partbuf), "data%ld", partno); if(!stream) { @@ -1171,12 +1179,12 @@ static void sendtftp(struct testcase *test, const struct formats *pf) sdp->th_block = htons(sendblock); timeout = 0; #ifdef HAVE_SIGSETJMP - (void) sigsetjmp(timeoutbuf, 1); + (void)sigsetjmp(timeoutbuf, 1); #endif if(test->writedelay) { logmsg("Pausing %d seconds before %d bytes", test->writedelay, size); - wait_ms(1000*test->writedelay); + curlx_wait_ms(1000*test->writedelay); } send_data: @@ -1215,7 +1223,7 @@ static void sendtftp(struct testcase *test, const struct formats *pf) break; } /* Re-synchronize with the other side */ - (void) synchnet(peer); + (void)synchnet(peer); if(sap->th_block == (sendblock-1)) { goto send_data; } @@ -1249,7 +1257,7 @@ static void recvtftp(struct testcase *test, const struct formats *pf) rap->th_block = htons(recvblock); recvblock++; #ifdef HAVE_SIGSETJMP - (void) sigsetjmp(timeoutbuf, 1); + (void)sigsetjmp(timeoutbuf, 1); #endif send_ack: logmsg("write"); @@ -1283,7 +1291,7 @@ static void recvtftp(struct testcase *test, const struct formats *pf) break; /* normal */ } /* Re-synchronize with the other side */ - (void) synchnet(peer); + (void)synchnet(peer); if(rdp->th_block == (recvblock-1)) goto send_ack; /* rexmit */ } @@ -1307,7 +1315,7 @@ static void recvtftp(struct testcase *test, const struct formats *pf) rap->th_opcode = htons(opcode_ACK); /* send the "final" ack */ rap->th_block = htons(recvblock); - (void) swrite(peer, &ackbuf.storage[0], 4); + (void)swrite(peer, &ackbuf.storage[0], 4); #if defined(HAVE_ALARM) && defined(SIGALRM) mysignal(SIGALRM, justtimeout); /* just abort read on timeout */ alarm(rexmtval); @@ -1322,7 +1330,7 @@ static void recvtftp(struct testcase *test, const struct formats *pf) if(n >= 4 && /* if read some data */ rdp->th_opcode == opcode_DATA && /* and got a data block */ recvblock == rdp->th_block) { /* then my last ack was lost */ - (void) swrite(peer, &ackbuf.storage[0], 4); /* resend final ack */ + (void)swrite(peer, &ackbuf.storage[0], 4); /* resend final ack */ } abort: /* make sure the output file is closed in case of abort */ diff --git a/vendor/curl/tests/server/util.c b/vendor/curl/tests/server/util.c index 81b01386dbe..26a5dd17f70 100644 --- a/vendor/curl/tests/server/util.c +++ b/vendor/curl/tests/server/util.c @@ -21,44 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "server_setup.h" +#include "first.h" -#ifndef UNDER_CE -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef _XOPEN_SOURCE_EXTENDED -/* This define is "almost" required to build on HP-UX 11 */ -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif - -#ifdef MSDOS -#include /* delay() */ -#endif - -#include /* from the private lib dir */ -#include "util.h" - -/* need init from main() */ -const char *pidname = NULL; -const char *portname = NULL; /* none by default */ -const char *serverlogfile = NULL; -int serverlogslocked; -const char *configfile = NULL; -const char *logdir = "log"; -char loglockfile[256]; -#ifdef USE_IPV6 -bool use_ipv6 = FALSE; +#ifdef HAVE_FCNTL_H +#include #endif -const char *ipv_inuse = "IPv4"; -unsigned short server_port = 0; -const char *socket_type = "IPv4"; -int socket_domain = AF_INET; /* This function returns a pointer to STATIC memory. It converts the given * binary lump to a hex formatted string usable for output in logs or @@ -87,6 +54,25 @@ char *data_to_hex(char *data, size_t len) return buf; } +void loghex(unsigned char *buffer, ssize_t len) +{ + char data[12000]; + ssize_t i; + unsigned char *ptr = buffer; + char *optr = data; + ssize_t width = 0; + int left = sizeof(data); + + for(i = 0; i < len && (left >= 0); i++) { + snprintf(optr, left, "%02x", ptr[i]); + width += 2; + optr += 2; + left -= 2; + } + if(width) + logmsg("'%s'", data); +} + void logmsg(const char *msg, ...) { va_list ap; @@ -145,25 +131,6 @@ void logmsg(const char *msg, ...) } } -void loghex(unsigned char *buffer, ssize_t len) -{ - char data[12000]; - ssize_t i; - unsigned char *ptr = buffer; - char *optr = data; - ssize_t width = 0; - int left = sizeof(data); - - for(i = 0; i < len && (left >= 0); i++) { - snprintf(optr, left, "%02x", ptr[i]); - width += 2; - optr += 2; - left -= 2; - } - if(width) - logmsg("'%s'", data); -} - unsigned char byteval(char *value) { unsigned long num = strtoul(value, NULL, 10); @@ -186,7 +153,7 @@ static void win32_cleanup(void) { #ifdef USE_WINSOCK WSACleanup(); -#endif /* USE_WINSOCK */ +#endif /* flush buffers of all streams regardless of their mode */ _flushall(); @@ -229,11 +196,11 @@ const char *sstrerror(int err) static char buf[512]; return curlx_winapi_strerror(err, buf, sizeof(buf)); } +#else +#define sstrerror(e) strerror(e) #endif /* _WIN32 */ -/* set by the main code to point to where the test dir is */ -const char *srcpath = "."; - +/* fopens the test case file */ FILE *test2fopen(long testno, const char *logdir2) { FILE *stream; @@ -251,53 +218,6 @@ FILE *test2fopen(long testno, const char *logdir2) return stream; } -/* - * Portable function used for waiting a specific amount of ms. - * Waiting indefinitely with this function is not allowed, a - * zero or negative timeout value will return immediately. - * - * Return values: - * -1 = system call error, or invalid timeout value - * 0 = specified timeout has elapsed - */ -int wait_ms(timediff_t timeout_ms) -{ - int r = 0; - - if(!timeout_ms) - return 0; - if(timeout_ms < 0) { - SET_SOCKERRNO(SOCKEINVAL); - return -1; - } -#if defined(MSDOS) - delay((unsigned int)timeout_ms); -#elif defined(_WIN32) - /* prevent overflow, timeout_ms is typecast to ULONG/DWORD. */ -#if TIMEDIFF_T_MAX >= ULONG_MAX - if(timeout_ms >= ULONG_MAX) - timeout_ms = ULONG_MAX-1; - /* do not use ULONG_MAX, because that is equal to INFINITE */ -#endif - Sleep((DWORD)timeout_ms); -#else - /* avoid using poll() for this since it behaves incorrectly with no sockets - on Apple operating systems */ - { - struct timeval pending_tv; - r = select(0, NULL, NULL, NULL, curlx_mstotv(&pending_tv, timeout_ms)); - } -#endif /* _WIN32 */ - if(r) { - if((r == -1) && (SOCKERRNO == SOCKEINTR)) - /* make EINTR from select or poll not a "lethal" error */ - r = 0; - else - r = -1; - } - return r; -} - #ifdef _WIN32 #define t_getpid() GetCurrentProcessId() #else @@ -435,17 +355,6 @@ static HANDLE thread_main_window = NULL; static HWND hidden_main_window = NULL; #endif -/* var which if set indicates that the program should finish execution */ -volatile int got_exit_signal = 0; - -/* if next is set indicates the first signal handled in exit_signal_handler */ -volatile int exit_signal = 0; - -#ifdef _WIN32 -/* event which if set indicates that the program should finish */ -HANDLE exit_event = NULL; -#endif - /* signal handler that will be triggered to indicate that the program * should finish its execution in a controlled manner as soon as possible. * The first time this is called it will set got_exit_signal to one and @@ -651,7 +560,7 @@ static SIGHANDLER_T set_signal(int signum, SIGHANDLER_T handler, if(oldhdlr != SIG_ERR) siginterrupt(signum, (int) restartable); #else - (void) restartable; + (void)restartable; #endif return oldhdlr; @@ -731,31 +640,31 @@ void restore_signal_handlers(bool keep_sigalrm) { #ifdef SIGHUP if(SIG_ERR != old_sighup_handler) - (void) set_signal(SIGHUP, old_sighup_handler, FALSE); + (void)set_signal(SIGHUP, old_sighup_handler, FALSE); #endif #ifdef SIGPIPE if(SIG_ERR != old_sigpipe_handler) - (void) set_signal(SIGPIPE, old_sigpipe_handler, FALSE); + (void)set_signal(SIGPIPE, old_sigpipe_handler, FALSE); #endif #ifdef SIGALRM if(!keep_sigalrm) { if(SIG_ERR != old_sigalrm_handler) - (void) set_signal(SIGALRM, old_sigalrm_handler, FALSE); + (void)set_signal(SIGALRM, old_sigalrm_handler, FALSE); } #else (void)keep_sigalrm; #endif #ifdef SIGINT if(SIG_ERR != old_sigint_handler) - (void) set_signal(SIGINT, old_sigint_handler, FALSE); + (void)set_signal(SIGINT, old_sigint_handler, FALSE); #endif #ifdef SIGTERM if(SIG_ERR != old_sigterm_handler) - (void) set_signal(SIGTERM, old_sigterm_handler, FALSE); + (void)set_signal(SIGTERM, old_sigterm_handler, FALSE); #endif #if defined(SIGBREAK) && defined(_WIN32) if(SIG_ERR != old_sigbreak_handler) - (void) set_signal(SIGBREAK, old_sigbreak_handler, FALSE); + (void)set_signal(SIGBREAK, old_sigbreak_handler, FALSE); #endif #ifdef _WIN32 #ifndef UNDER_CE @@ -798,7 +707,7 @@ int bind_unix_socket(curl_socket_t sock, const char *unix_socket, } strcpy(sau->sun_path, unix_socket); rc = bind(sock, (struct sockaddr*)sau, sizeof(struct sockaddr_un)); - if(0 != rc && SOCKERRNO == SOCKEADDRINUSE) { + if(rc && SOCKERRNO == SOCKEADDRINUSE) { struct_stat statbuf; /* socket already exists. Perhaps it is stale? */ curl_socket_t unixfd = socket(AF_UNIX, SOCK_STREAM, 0); @@ -811,7 +720,7 @@ int bind_unix_socket(curl_socket_t sock, const char *unix_socket, rc = connect(unixfd, (struct sockaddr*)sau, sizeof(struct sockaddr_un)); error = SOCKERRNO; sclose(unixfd); - if(0 != rc && SOCKECONNREFUSED != error) { + if(rc && error != SOCKECONNREFUSED) { logmsg("Failed to connect to %s (%d) %s", unix_socket, error, sstrerror(error)); return rc; @@ -823,7 +732,7 @@ int bind_unix_socket(curl_socket_t sock, const char *unix_socket, #else rc = lstat(unix_socket, &statbuf); #endif - if(0 != rc) { + if(rc) { logmsg("Error binding socket, failed to stat %s (%d) %s", unix_socket, errno, strerror(errno)); return rc; @@ -836,7 +745,7 @@ int bind_unix_socket(curl_socket_t sock, const char *unix_socket, #endif /* dead socket, cleanup and retry bind */ rc = unlink(unix_socket); - if(0 != rc) { + if(rc) { logmsg("Error binding socket, failed to unlink %s (%d) %s", unix_socket, errno, strerror(errno)); return rc; @@ -868,3 +777,166 @@ unsigned short util_ultous(unsigned long ulnum) # pragma warning(pop) #endif } + +curl_socket_t sockdaemon(curl_socket_t sock, + unsigned short *listenport, + const char *unix_socket, + bool bind_only) +{ + /* passive daemon style */ + srvr_sockaddr_union_t listener; + int flag; + int rc; + int totdelay = 0; + int maxretr = 10; + int delay = 20; + int attempt = 0; + int error = 0; + +#ifndef USE_UNIX_SOCKETS + (void)unix_socket; +#endif + + do { + attempt++; + flag = 1; + rc = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + (void *)&flag, sizeof(flag)); + if(rc) { + error = SOCKERRNO; + logmsg("setsockopt(SO_REUSEADDR) failed with error (%d) %s", + error, sstrerror(error)); + if(maxretr) { + rc = curlx_wait_ms(delay); + if(rc) { + /* should not happen */ + error = SOCKERRNO; + logmsg("curlx_wait_ms() failed with error (%d) %s", + error, sstrerror(error)); + sclose(sock); + return CURL_SOCKET_BAD; + } + if(got_exit_signal) { + logmsg("signalled to die, exiting..."); + sclose(sock); + return CURL_SOCKET_BAD; + } + totdelay += delay; + delay *= 2; /* double the sleep for next attempt */ + } + } + } while(rc && maxretr--); + + if(rc) { + logmsg("setsockopt(SO_REUSEADDR) failed %d times in %d ms. Error (%d) %s", + attempt, totdelay, error, strerror(error)); + logmsg("Continuing anyway..."); + } + + /* When the specified listener port is zero, it is actually a + request to let the system choose a non-zero available port. */ + + switch(socket_domain) { + case AF_INET: + memset(&listener.sa4, 0, sizeof(listener.sa4)); + listener.sa4.sin_family = AF_INET; + listener.sa4.sin_addr.s_addr = INADDR_ANY; + listener.sa4.sin_port = htons(*listenport); + rc = bind(sock, &listener.sa, sizeof(listener.sa4)); + break; +#ifdef USE_IPV6 + case AF_INET6: + memset(&listener.sa6, 0, sizeof(listener.sa6)); + listener.sa6.sin6_family = AF_INET6; + listener.sa6.sin6_addr = in6addr_any; + listener.sa6.sin6_port = htons(*listenport); + rc = bind(sock, &listener.sa, sizeof(listener.sa6)); + break; +#endif /* USE_IPV6 */ +#ifdef USE_UNIX_SOCKETS + case AF_UNIX: + rc = bind_unix_socket(sock, unix_socket, &listener.sau); + break; +#endif + default: + rc = 1; + } + + if(rc) { + error = SOCKERRNO; +#ifdef USE_UNIX_SOCKETS + if(socket_domain == AF_UNIX) + logmsg("Error binding socket on path %s (%d) %s", + unix_socket, error, sstrerror(error)); + else +#endif + logmsg("Error binding socket on port %hu (%d) %s", + *listenport, error, sstrerror(error)); + sclose(sock); + return CURL_SOCKET_BAD; + } + + if(!*listenport +#ifdef USE_UNIX_SOCKETS + && !unix_socket +#endif + ) { + /* The system was supposed to choose a port number, figure out which + port we actually got and update the listener port value with it. */ + curl_socklen_t la_size; + srvr_sockaddr_union_t localaddr; +#ifdef USE_IPV6 + if(socket_domain == AF_INET6) + la_size = sizeof(localaddr.sa6); + else +#endif + la_size = sizeof(localaddr.sa4); + memset(&localaddr.sa, 0, (size_t)la_size); + if(getsockname(sock, &localaddr.sa, &la_size) < 0) { + error = SOCKERRNO; + logmsg("getsockname() failed with error (%d) %s", + error, sstrerror(error)); + sclose(sock); + return CURL_SOCKET_BAD; + } + switch(localaddr.sa.sa_family) { + case AF_INET: + *listenport = ntohs(localaddr.sa4.sin_port); + break; +#ifdef USE_IPV6 + case AF_INET6: + *listenport = ntohs(localaddr.sa6.sin6_port); + break; +#endif + default: + break; + } + if(!*listenport) { + /* Real failure, listener port shall not be zero beyond this point. */ + logmsg("Apparently getsockname() succeeded, with listener port zero."); + logmsg("A valid reason for this failure is a binary built without"); + logmsg("proper network library linkage. This might not be the only"); + logmsg("reason, but double check it before anything else."); + sclose(sock); + return CURL_SOCKET_BAD; + } + } + + /* bindonly option forces no listening */ + if(bind_only) { + logmsg("instructed to bind port without listening"); + return sock; + } + + /* start accepting connections */ + rc = listen(sock, 5); + if(rc) { + error = SOCKERRNO; + logmsg("listen(%ld, 5) failed with error (%d) %s", + (long)sock, error, sstrerror(error)); + sclose(sock); + return CURL_SOCKET_BAD; + } + + return sock; +} diff --git a/vendor/curl/tests/tunit/.gitignore b/vendor/curl/tests/tunit/.gitignore new file mode 100644 index 00000000000..97fa1ba521c --- /dev/null +++ b/vendor/curl/tests/tunit/.gitignore @@ -0,0 +1,6 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +tunits +tunits.c diff --git a/vendor/curl/tests/tunit/tool1394.c b/vendor/curl/tests/tunit/tool1394.c index ef398ab22f2..77a2021b0a8 100644 --- a/vendor/curl/tests/tunit/tool1394.c +++ b/vendor/curl/tests/tunit/tool1394.c @@ -21,29 +21,17 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "tool_getparam.h" -#include -#include -#include - #include "memdebug.h" /* LAST include file */ -static CURLcode unit_setup(void) -{ - return CURLE_OK; -} - -static void unit_stop(void) +static CURLcode test_tool1394(const char *arg) { + UNITTEST_BEGIN_SIMPLE -} - -UNITTEST_START - - const char *values[] = { + static const char *values[] = { /* -E parameter */ /* exp. cert name */ /* exp. passphrase */ "foo:bar:baz", "foo", "bar:baz", "foo\\:bar:baz", "foo:bar", "baz", @@ -86,20 +74,20 @@ UNITTEST_START if(certname) { if(strcmp(p[1], certname)) { printf("expected certname '%s' but got '%s' " - "for -E param '%s'\n", p[1], certname, p[0]); + "for -E param '%s'\n", p[1], certname, p[0]); fail("assertion failure"); } } else { printf("expected certname '%s' but got NULL " - "for -E param '%s'\n", p[1], p[0]); + "for -E param '%s'\n", p[1], p[0]); fail("assertion failure"); } } else { if(certname) { printf("expected certname NULL but got '%s' " - "for -E param '%s'\n", certname, p[0]); + "for -E param '%s'\n", certname, p[0]); fail("assertion failure"); } } @@ -107,20 +95,20 @@ UNITTEST_START if(passphrase) { if(strcmp(p[2], passphrase)) { printf("expected passphrase '%s' but got '%s'" - "for -E param '%s'\n", p[2], passphrase, p[0]); + "for -E param '%s'\n", p[2], passphrase, p[0]); fail("assertion failure"); } } else { printf("expected passphrase '%s' but got NULL " - "for -E param '%s'\n", p[2], p[0]); + "for -E param '%s'\n", p[2], p[0]); fail("assertion failure"); } } else { if(passphrase) { printf("expected passphrase NULL but got '%s' " - "for -E param '%s'\n", passphrase, p[0]); + "for -E param '%s'\n", passphrase, p[0]); fail("assertion failure"); } } @@ -130,4 +118,5 @@ UNITTEST_START free(passphrase); } -UNITTEST_STOP + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/tunit/tool1604.c b/vendor/curl/tests/tunit/tool1604.c index f2b727b6293..db7ed141240 100644 --- a/vendor/curl/tests/tunit/tool1604.c +++ b/vendor/curl/tests/tunit/tool1604.c @@ -21,29 +21,14 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "tool_cfgable.h" #include "tool_doswin.h" -#include -#include -#include - #include "memdebug.h" /* LAST include file */ -static CURLcode unit_setup(void) -{ - return CURLE_OK; -} - -static void unit_stop(void) -{ - -} - #if defined(_WIN32) || defined(MSDOS) - static char *getflagstr(int flags) { char *buf = malloc(256); @@ -71,16 +56,21 @@ static char *getcurlcodestr(int cc) } return buf; } +#endif + +static CURLcode test_tool1604(const char *arg) +{ + UNITTEST_BEGIN_SIMPLE -struct data { - const char *input; - int flags; - const char *expected_output; - SANITIZEcode expected_result; -}; +#if defined(_WIN32) || defined(MSDOS) + struct data { + const char *input; + int flags; + const char *expected_output; + SANITIZEcode expected_result; + }; -UNITTEST_START -{ /* START sanitize_file_name */ + /* START sanitize_file_name */ struct data data[] = { { "", 0, "", SANITIZE_ERR_OK @@ -256,13 +246,10 @@ UNITTEST_START free(received_ccstr); free(expected_ccstr); } -} /* END sanitize_file_name */ - + /* END sanitize_file_name */ #else -UNITTEST_START -{ fprintf(stderr, "Skipped test not for this platform\n"); -} #endif /* _WIN32 || MSDOS */ -UNITTEST_STOP + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/tunit/tool1621.c b/vendor/curl/tests/tunit/tool1621.c index b6135e4e647..c7dfedddce2 100644 --- a/vendor/curl/tests/tunit/tool1621.c +++ b/vendor/curl/tests/tunit/tool1621.c @@ -21,72 +21,66 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" -#include "urldata.h" -#include "url.h" +#include "tool_xattr.h" #include "memdebug.h" /* LAST include file */ -static CURLcode unit_setup(void) +static CURLcode test_tool1621(const char *arg) { - return CURLE_OK; -} - -static void unit_stop(void) -{ -} + UNITTEST_BEGIN_SIMPLE -#ifndef USE_XATTR -/* stripcredentials isn't available in this case */ +#ifdef USE_XATTR /* Required for stripcredentials() */ -UNITTEST_START -UNITTEST_STOP -#else + struct checkthis { + const char *input; + const char *output; + }; -char *stripcredentials(const char *url); - -struct checkthis { - const char *input; - const char *output; -}; - -static const struct checkthis tests[] = { - { "ninja://foo@example.com", "(null)" }, /* unsupported scheme */ - { "pop3s://foo@example.com", "pop3s://example.com/" }, - { "ldap://foo@example.com", "ldap://example.com/" }, - { "https://foo@example.com", "https://example.com/" }, - { "https://localhost:45", "https://localhost:45/" }, - { "https://foo@localhost:45", "https://localhost:45/" }, - { "http://daniel:password@localhost", "http://localhost/" }, - { "http://daniel@localhost", "http://localhost/" }, - { "https://user:pass@localhost:45", "https://localhost:45/" }, - { "http://localhost/", "http://localhost/" }, - { "http://odd%40host/", "(null)" }, /* bad host */ - { "http://user@odd%40host/", "(null)" }, /* bad host */ - { "http://host/@path/", "http://host/@path/" }, - { "http://emptypw:@host/", "http://host/" }, - { "http://:emptyuser@host/", "http://host/" }, - { "http://odd%40user@host/", "http://host/" }, - { "http://only%40one%40host/", "(null)" }, /* bad host */ - { "http://odder%3auser@host/", "http://host/" }, - { NULL, NULL } /* end marker */ -}; + static const struct checkthis tests[] = { + { "ninja://foo@example.com", "(null)" }, /* unsupported scheme */ +#if defined(USE_SSL) && !defined(CURL_DISABLE_POP3) + { "pop3s://foo@example.com", "pop3s://example.com/" }, +#endif +#ifndef CURL_DISABLE_LDAP + { "ldap://foo@example.com", "ldap://example.com/" }, +#endif +#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) + { "https://foo@example.com", "https://example.com/" }, + { "https://localhost:45", "https://localhost:45/" }, + { "https://foo@localhost:45", "https://localhost:45/" }, + { "https://user:pass@localhost:45", "https://localhost:45/" }, +#endif +#ifndef CURL_DISABLE_HTTP + { "http://daniel:password@localhost", "http://localhost/" }, + { "http://daniel@localhost", "http://localhost/" }, + { "http://localhost/", "http://localhost/" }, + { "http://odd%40host/", "(null)" }, /* bad host */ + { "http://user@odd%40host/", "(null)" }, /* bad host */ + { "http://host/@path/", "http://host/@path/" }, + { "http://emptypw:@host/", "http://host/" }, + { "http://:emptyuser@host/", "http://host/" }, + { "http://odd%40user@host/", "http://host/" }, + { "http://only%40one%40host/", "(null)" }, /* bad host */ + { "http://odder%3auser@host/", "http://host/" }, +#endif + { NULL, NULL } /* end marker */ + }; -UNITTEST_START -{ int i; for(i = 0; tests[i].input; i++) { const char *url = tests[i].input; char *stripped = stripcredentials(url); - char *strippedstr = stripped ? stripped : "(null)"; - printf("Test %u got input \"%s\", output: \"%s\"\n", - i, tests[i].input, strippedstr); + const char *strippedstr = stripped ? stripped : "(null)"; + printf("Test %u got input \"%s\", output: \"%s\", expected: \"%s\"\n", + i, tests[i].input, strippedstr, tests[i].output); fail_if(strcmp(tests[i].output, strippedstr), tests[i].output); curl_free(stripped); } -} -UNITTEST_STOP #endif + + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/.gitignore b/vendor/curl/tests/unit/.gitignore new file mode 100644 index 00000000000..bae3c1a7602 --- /dev/null +++ b/vendor/curl/tests/unit/.gitignore @@ -0,0 +1,6 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +units +units.c diff --git a/vendor/curl/tests/unit/unit1300.c b/vendor/curl/tests/unit/unit1300.c index 55caaca1a1a..a5ddf11f498 100644 --- a/vendor/curl/tests/unit/unit1300.c +++ b/vendor/curl/tests/unit/unit1300.c @@ -21,13 +21,10 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "llist.h" - -static struct Curl_llist llist; - -static struct Curl_llist llist_destination; +#include "unitprotos.h" static void test_Curl_llist_dtor(void *key, void *value) { @@ -36,19 +33,13 @@ static void test_Curl_llist_dtor(void *key, void *value) (void)value; } -static CURLcode unit_setup(void) +static CURLcode test_unit1300(const char *arg) { - Curl_llist_init(&llist, test_Curl_llist_dtor); - Curl_llist_init(&llist_destination, test_Curl_llist_dtor); - return CURLE_OK; -} + UNITTEST_BEGIN_SIMPLE -static void unit_stop(void) -{ -} + struct Curl_llist llist; + struct Curl_llist llist_destination; -UNITTEST_START -{ int unusedData_case1 = 1; int unusedData_case2 = 2; int unusedData_case3 = 3; @@ -62,6 +53,9 @@ UNITTEST_START struct Curl_llist_node *to_remove; size_t llist_size; + Curl_llist_init(&llist, test_Curl_llist_dtor); + Curl_llist_init(&llist_destination, test_Curl_llist_dtor); + /** * testing llist_init * case 1: @@ -271,5 +265,6 @@ UNITTEST_START Curl_llist_destroy(&llist, NULL); Curl_llist_destroy(&llist_destination, NULL); + + UNITTEST_END_SIMPLE } -UNITTEST_STOP diff --git a/vendor/curl/tests/unit/unit1302.c b/vendor/curl/tests/unit/unit1302.c index d0e85f634fd..54693631ff5 100644 --- a/vendor/curl/tests/unit/unit1302.c +++ b/vendor/curl/tests/unit/unit1302.c @@ -21,171 +21,179 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "urldata.h" #include "url.h" /* for Curl_safefree */ -#include "curlx/base64.h" #include "memdebug.h" /* LAST include file */ -static struct Curl_easy *testdata; +struct etest { + const char *input; + size_t ilen; + const char *output; + size_t olen; +}; -static CURLcode unit_setup(void) +static CURLcode test_unit1302(const char *arg) { - CURLcode res = CURLE_OK; - - global_init(CURL_GLOBAL_ALL); - testdata = curl_easy_init(); - if(!testdata) { - curl_global_cleanup(); - return CURLE_OUT_OF_MEMORY; + UNITTEST_BEGIN_SIMPLE + CURLcode rc; + unsigned int i; + + /* common base64 encoding */ + struct etest encode[] = { + {"iiiiii", 1, "aQ==", 4 }, + {"iiiiii", 2, "aWk=", 4 }, + {"iiiiii", 3, "aWlp", 4 }, + {"iiiiii", 4, "aWlpaQ==", 8 }, + {"iiiiii", 5, "aWlpaWk=", 8 }, + {"iiiiii", 6, "aWlpaWlp", 8 }, + {"iiiiiii", 7, "aWlpaWlpaQ==", 12 }, + {"iiiiiiii", 8, "aWlpaWlpaWk=", 12 }, + {"iiiiiiiii", 9, "aWlpaWlpaWlp", 12 }, + {"iiiiiiiiii", 10, "aWlpaWlpaWlpaQ==", 16 }, + {"iiiiiiiiiii", 11, "aWlpaWlpaWlpaWk=", 16 }, + {"iiiiiiiiiiii", 12, "aWlpaWlpaWlpaWlp", 16 }, + {"\xff\x01\xfe\x02", 4, "/wH+Ag==", 8 }, + {"\xff\xff\xff\xff", 4, "/////w==", 8 }, + {"\x00\x00\x00\x00", 4, "AAAAAA==", 8 }, + {"\x00\x00\x00\x00", 1, "AA==", 4 }, + }; + + /* base64 URL encoding */ + struct etest url[] = { + {"", 0, "", 0 }, + {"iiiiiiiiiii", 1, "aQ", 2 }, + {"iiiiiiiiiii", 2, "aWk", 3 }, + {"iiiiiiiiiii", 3, "aWlp", 4 }, + {"iiiiiiiiiii", 4, "aWlpaQ", 6 }, + {"iiiiiiiiiii", 5, "aWlpaWk", 7 }, + {"iiiiiiiiiii", 6, "aWlpaWlp", 8 }, + {"iiiiiiiiiii", 7, "aWlpaWlpaQ", 10 }, + {"iiiiiiiiiii", 8, "aWlpaWlpaWk", 11 }, + {"iiiiiiiiiii", 9, "aWlpaWlpaWlp", 12 }, + {"iiiiiiiiiii", 10, "aWlpaWlpaWlpaQ", 14 }, + {"iiiiiiiiiii", 11, "aWlpaWlpaWlpaWk", 15 }, + {"iiiiiiiiiiii", 12, "aWlpaWlpaWlpaWlp", 16 }, + {"\xff\x01\xfe\x02", 4, "_wH-Ag", 6 }, + {"\xff\xff\xff\xff", 4, "_____w", 6 }, + {"\xff\x00\xff\x00", 4, "_wD_AA", 6 }, + {"\x00\xff\x00\xff", 4, "AP8A_w", 6 }, + {"\x00\x00\x00\x00", 4, "AAAAAA", 6 }, + {"\x00", 1, "AA", 2 }, + {"\x01", 1, "AQ", 2 }, + {"\x02", 1, "Ag", 2 }, + {"\x03", 1, "Aw", 2 }, + {"\x04", 1, "BA", 2 }, /* spellchecker:disable-line */ + {"\x05", 1, "BQ", 2 }, + {"\x06", 1, "Bg", 2 }, + {"\x07", 1, "Bw", 2 }, + {"\x08", 1, "CA", 2 }, + {"\x09", 1, "CQ", 2 }, + {"\x0a", 1, "Cg", 2 }, + {"\x0b", 1, "Cw", 2 }, + {"\x0c", 1, "DA", 2 }, + {"\x0d", 1, "DQ", 2 }, + {"\x0e", 1, "Dg", 2 }, + {"\x0f", 1, "Dw", 2 }, + {"\x10", 1, "EA", 2 }, + }; + + /* bad decode inputs */ + struct etest badecode[] = { + {"", 0, "", 0 }, /* no dats means error */ + {"", 0, "a", 1 }, /* data is too short */ + {"", 0, "aQ", 2 }, /* data is too short */ + {"", 0, "aQ=", 3 }, /* data is too short */ + {"", 0, "====", 1 }, /* data is only padding characters */ + {"", 0, "====", 2 }, /* data is only padding characters */ + {"", 0, "====", 3 }, /* data is only padding characters */ + {"", 0, "====", 4 }, /* data is only padding characters */ + {"", 0, "a===", 4 }, /* contains three padding characters */ + {"", 0, "a=Q=", 4 }, /* contains a padding character mid input */ + {"", 0, "aWlpa=Q=", 8 }, /* contains a padding character mid input */ + {"", 0, "a\x1f==", 4 }, /* contains illegal base64 character */ + {"", 0, "abcd ", 5 }, /* contains illegal base64 character */ + {"", 0, "abcd ", 6 }, /* contains illegal base64 character */ + {"", 0, " abcd", 5 }, /* contains illegal base64 character */ + {"", 0, "_abcd", 5 }, /* contains illegal base64 character */ + {"", 0, "abcd-", 5 }, /* contains illegal base64 character */ + {"", 0, "abcd_", 5 }, /* contains illegal base64 character */ + {"", 0, "aWlpaWlpaQ==-", 17}, /* bad character after padding */ + {"", 0, "aWlpaWlpaQ==_", 17}, /* bad character after padding */ + {"", 0, "aWlpaWlpaQ== ", 17}, /* bad character after padding */ + {"", 0, "aWlpaWlpaQ=", 15} /* unaligned size, missing a padding char */ + }; + + for(i = 0 ; i < CURL_ARRAYSIZE(encode); i++) { + struct etest *e = &encode[i]; + char *out; + unsigned char *decoded; + size_t olen; + size_t dlen; + + /* first encode */ + rc = curlx_base64_encode(e->input, e->ilen, &out, &olen); + abort_unless(rc == CURLE_OK, "return code should be CURLE_OK"); + abort_unless(olen == e->olen, "wrong output size"); + if(memcmp(out, e->output, e->olen)) { + fprintf(stderr, "Test %u encoded badly\n", i); + unitfail++; + } + Curl_safefree(out); + + /* then verify decode */ + rc = curlx_base64_decode(e->output, &decoded, &dlen); + if(rc != CURLE_OK) { + fprintf(stderr, "Test %u URL decode returned %d\n", i, (int)rc); + unitfail++; + } + if(dlen != e->ilen) { + fprintf(stderr, "Test %u URL decode output length %d instead of %d\n", + i, (int)dlen, (int)e->ilen); + unitfail++; + } + if(memcmp(decoded, e->input, dlen)) { + fprintf(stderr, "Test %u URL decoded badly. Got '%s', expected '%s'\n", + i, decoded, e->input); + unitfail++; + } + + Curl_safefree(decoded); } - return res; -} - -static void unit_stop(void) -{ - curl_easy_cleanup(testdata); - curl_global_cleanup(); -} - -UNITTEST_START - -char *output; -unsigned char *decoded; -size_t size = 0; -unsigned char anychar = 'x'; -CURLcode rc; - -rc = curlx_base64_encode("i", 1, &output, &size); -fail_unless(rc == CURLE_OK, "return code should be CURLE_OK"); -fail_unless(size == 4, "size should be 4"); -verify_memory(output, "aQ==", 4); -Curl_safefree(output); - -rc = curlx_base64_encode("ii", 2, &output, &size); -fail_unless(rc == CURLE_OK, "return code should be CURLE_OK"); -fail_unless(size == 4, "size should be 4"); -verify_memory(output, "aWk=", 4); -Curl_safefree(output); - -rc = curlx_base64_encode("iii", 3, &output, &size); -fail_unless(rc == CURLE_OK, "return code should be CURLE_OK"); -fail_unless(size == 4, "size should be 4"); -verify_memory(output, "aWlp", 4); -Curl_safefree(output); - -rc = curlx_base64_encode("iiii", 4, &output, &size); -fail_unless(rc == CURLE_OK, "return code should be CURLE_OK"); -fail_unless(size == 8, "size should be 8"); -verify_memory(output, "aWlpaQ==", 8); -Curl_safefree(output); - -rc = curlx_base64_encode("\xff\x01\xfe\x02", 4, &output, &size); -fail_unless(rc == CURLE_OK, "return code should be CURLE_OK"); -fail_unless(size == 8, "size should be 8"); -verify_memory(output, "/wH+Ag==", 8); -Curl_safefree(output); - -rc = curlx_base64url_encode("\xff\x01\xfe\x02", 4, &output, &size); -fail_unless(rc == CURLE_OK, "return code should be CURLE_OK"); -fail_unless(size == 6, "size should be 6"); -verify_memory(output, "_wH-Ag", 6); -Curl_safefree(output); - -rc = curlx_base64url_encode("iiii", 4, &output, &size); -fail_unless(rc == CURLE_OK, "return code should be CURLE_OK"); -fail_unless(size == 6, "size should be 6"); -verify_memory(output, "aWlpaQ", 6); -Curl_safefree(output); -/* 0 length makes it do strlen() */ -rc = curlx_base64_encode("iiii", 0, &output, &size); -fail_unless(rc == CURLE_OK, "return code should be CURLE_OK"); -fail_unless(size == 8, "size should be 8"); -verify_memory(output, "aWlpaQ==", 8); -Curl_safefree(output); - -rc = curlx_base64_encode("", 0, &output, &size); -fail_unless(rc == CURLE_OK, "return code should be CURLE_OK"); -fail_unless(size == 0, "size should be 0"); -fail_unless(output && !output[0], "output should be a zero-length string"); -Curl_safefree(output); - -rc = curlx_base64url_encode("", 0, &output, &size); -fail_unless(rc == CURLE_OK, "return code should be CURLE_OK"); -fail_unless(size == 0, "size should be 0"); -fail_unless(output && !output[0], "output should be a zero-length string"); -Curl_safefree(output); - -rc = curlx_base64_decode("aWlpaQ==", &decoded, &size); -fail_unless(rc == CURLE_OK, "return code should be CURLE_OK"); -fail_unless(size == 4, "size should be 4"); -verify_memory(decoded, "iiii", 4); -Curl_safefree(decoded); - -rc = curlx_base64_decode("aWlp", &decoded, &size); -fail_unless(rc == CURLE_OK, "return code should be CURLE_OK"); -fail_unless(size == 3, "size should be 3"); -verify_memory(decoded, "iii", 3); -Curl_safefree(decoded); - -rc = curlx_base64_decode("aWk=", &decoded, &size); -fail_unless(rc == CURLE_OK, "return code should be CURLE_OK"); -fail_unless(size == 2, "size should be 2"); -verify_memory(decoded, "ii", 2); -Curl_safefree(decoded); - -rc = curlx_base64_decode("aQ==", &decoded, &size); -fail_unless(rc == CURLE_OK, "return code should be CURLE_OK"); -fail_unless(size == 1, "size should be 1"); -verify_memory(decoded, "i", 2); -Curl_safefree(decoded); - -/* This is illegal input as the data is too short */ -size = 1; /* not zero */ -decoded = &anychar; /* not NULL */ -rc = curlx_base64_decode("aQ", &decoded, &size); -fail_unless(rc == CURLE_BAD_CONTENT_ENCODING, - "return code should be CURLE_BAD_CONTENT_ENCODING"); -fail_unless(size == 0, "size should be 0"); -fail_if(decoded, "returned pointer should be NULL"); - -/* This is illegal input as it contains three padding characters */ -size = 1; /* not zero */ -decoded = &anychar; /* not NULL */ -rc = curlx_base64_decode("a===", &decoded, &size); -fail_unless(rc == CURLE_BAD_CONTENT_ENCODING, - "return code should be CURLE_BAD_CONTENT_ENCODING"); -fail_unless(size == 0, "size should be 0"); -fail_if(decoded, "returned pointer should be NULL"); - -/* This is illegal input as it contains a padding character mid input */ -size = 1; /* not zero */ -decoded = &anychar; /* not NULL */ -rc = curlx_base64_decode("a=Q=", &decoded, &size); -fail_unless(rc == CURLE_BAD_CONTENT_ENCODING, - "return code should be CURLE_BAD_CONTENT_ENCODING"); -fail_unless(size == 0, "size should be 0"); -fail_if(decoded, "returned pointer should be NULL"); - -/* This is also illegal input as it contains a padding character mid input */ -size = 1; /* not zero */ -decoded = &anychar; /* not NULL */ -rc = curlx_base64_decode("aWlpa=Q=", &decoded, &size); -fail_unless(rc == CURLE_BAD_CONTENT_ENCODING, - "return code should be CURLE_BAD_CONTENT_ENCODING"); -fail_unless(size == 0, "size should be 0"); -fail_if(decoded, "returned pointer should be NULL"); - -/* This is garbage input as it contains an illegal base64 character */ -size = 1; /* not zero */ -decoded = &anychar; /* not NULL */ -rc = curlx_base64_decode("a\x1f==", &decoded, &size); -fail_unless(rc == CURLE_BAD_CONTENT_ENCODING, - "return code should be CURLE_BAD_CONTENT_ENCODING"); -fail_unless(size == 0, "size should be 0"); -fail_if(decoded, "returned pointer should be NULL"); + for(i = 0 ; i < CURL_ARRAYSIZE(url); i++) { + struct etest *e = &url[i]; + char *out; + size_t olen; + rc = curlx_base64url_encode(e->input, e->ilen, &out, &olen); + abort_unless(rc == CURLE_OK, "return code should be CURLE_OK"); + if(olen != e->olen) { + fprintf(stderr, "Test %u URL encoded output length %d instead of %d\n", + i, (int)olen, (int)e->olen); + } + if(memcmp(out, e->output, e->olen)) { + fprintf(stderr, "Test %u URL encoded badly. Got '%s', expected '%s'\n", + i, out, e->output); + unitfail++; + } + Curl_safefree(out); + } + for(i = 0 ; i < CURL_ARRAYSIZE(badecode); i++) { + struct etest *e = &badecode[i]; + unsigned char *decoded; + size_t dlen; + + /* then verify decode with illegal inputs */ + rc = curlx_base64_decode(e->output, &decoded, &dlen); + if(rc != CURLE_BAD_CONTENT_ENCODING) { + fprintf(stderr, "Test %u URL bad decoded badly. " + "Returned '%d', expected '%d'\n", + i, (int)rc, CURLE_BAD_CONTENT_ENCODING); + unitfail++; + } + } -UNITTEST_STOP + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/unit1303.c b/vendor/curl/tests/unit/unit1303.c index 95f0630560f..49ff3e69f2c 100644 --- a/vendor/curl/tests/unit/unit1303.c +++ b/vendor/curl/tests/unit/unit1303.c @@ -21,30 +21,28 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "urldata.h" #include "connect.h" #include "memdebug.h" /* LAST include file */ -static struct Curl_easy *testdata; - -static CURLcode unit_setup(void) +static CURLcode t1303_setup(struct Curl_easy **easy) { CURLcode res = CURLE_OK; global_init(CURL_GLOBAL_ALL); - testdata = curl_easy_init(); - if(!testdata) { + *easy = curl_easy_init(); + if(!*easy) { curl_global_cleanup(); return CURLE_OUT_OF_MEMORY; } return res; } -static void unit_stop(void) +static void t1303_stop(struct Curl_easy *easy) { - curl_easy_cleanup(testdata); + curl_easy_cleanup(easy); curl_global_cleanup(); } @@ -55,8 +53,8 @@ static void unit_stop(void) /* macro to set the pretended current time */ #define NOW(x,y) now.tv_sec = x; now.tv_usec = y /* macro to set the millisecond based timeouts to use */ -#define TIMEOUTS(x,y) testdata->set.timeout = x; \ - testdata->set.connecttimeout = y +#define TIMEOUTS(x,y) easy->set.timeout = x; \ + easy->set.connecttimeout = y /* * To test: @@ -67,21 +65,25 @@ static void unit_stop(void) * N various values of now */ -struct timetest { - int now_s; - int now_us; - unsigned int timeout_ms; - unsigned int connecttimeout_ms; - bool connecting; - timediff_t result; - const char *comment; -}; - -UNITTEST_START +static CURLcode test_unit1303(const char *arg) { + struct Curl_easy *easy; + + UNITTEST_BEGIN(t1303_setup(&easy)) + struct curltime now; unsigned int i; + struct timetest { + int now_s; + int now_us; + unsigned int timeout_ms; + unsigned int connecttimeout_ms; + bool connecting; + timediff_t result; + const char *comment; + }; + const struct timetest run[] = { /* both timeouts set, not connecting */ {BASE + 4, 0, 10000, 8000, FALSE, 6000, "6 seconds should be left"}, @@ -137,18 +139,19 @@ UNITTEST_START }; /* this is the pretended start time of the transfer */ - testdata->progress.t_startsingle.tv_sec = BASE; - testdata->progress.t_startsingle.tv_usec = 0; - testdata->progress.t_startop.tv_sec = BASE; - testdata->progress.t_startop.tv_usec = 0; + easy->progress.t_startsingle.tv_sec = BASE; + easy->progress.t_startsingle.tv_usec = 0; + easy->progress.t_startop.tv_sec = BASE; + easy->progress.t_startop.tv_usec = 0; for(i = 0; i < CURL_ARRAYSIZE(run); i++) { timediff_t timeout; NOW(run[i].now_s, run[i].now_us); TIMEOUTS(run[i].timeout_ms, run[i].connecttimeout_ms); - timeout = Curl_timeleft(testdata, &now, run[i].connecting); + timeout = Curl_timeleft(easy, &now, run[i].connecting); if(timeout != run[i].result) fail(run[i].comment); } + + UNITTEST_END(t1303_stop(easy)) } -UNITTEST_STOP diff --git a/vendor/curl/tests/unit/unit1304.c b/vendor/curl/tests/unit/unit1304.c index 46ccd1745ca..250a2ee3f61 100644 --- a/vendor/curl/tests/unit/unit1304.c +++ b/vendor/curl/tests/unit/unit1304.c @@ -21,30 +21,25 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "netrc.h" #include "memdebug.h" /* LAST include file */ #ifndef CURL_DISABLE_NETRC -static char *s_login; -static char *s_password; - -static CURLcode unit_setup(void) +static void t1304_stop(char **password, char **login) { - s_password = NULL; - s_login = NULL; - return CURLE_OK; + Curl_safefree(*password); + Curl_safefree(*login); } -static void unit_stop(void) +static CURLcode test_unit1304(const char *arg) { - Curl_safefree(s_password); - Curl_safefree(s_login); -} + char *login = NULL; + char *password = NULL; + + UNITTEST_BEGIN_SIMPLE -UNITTEST_START -{ int result; struct store_netrc store; @@ -53,142 +48,140 @@ UNITTEST_START */ Curl_netrc_init(&store); result = Curl_parsenetrc(&store, - "test.example.com", &s_login, &s_password, arg); + "test.example.com", &login, &password, arg); fail_unless(result == 1, "Host not found should return 1"); - abort_unless(s_password == NULL, "password did not return NULL!"); - abort_unless(s_login == NULL, "user did not return NULL!"); + abort_unless(password == NULL, "password did not return NULL!"); + abort_unless(login == NULL, "user did not return NULL!"); Curl_netrc_cleanup(&store); /* * Test a non existent login in our netrc file. */ - s_login = (char *)CURL_UNCONST("me"); + login = (char *)CURL_UNCONST("me"); Curl_netrc_init(&store); result = Curl_parsenetrc(&store, - "example.com", &s_login, &s_password, arg); + "example.com", &login, &password, arg); fail_unless(result == 0, "Host should have been found"); - abort_unless(s_password == NULL, "password is not NULL!"); + abort_unless(password == NULL, "password is not NULL!"); Curl_netrc_cleanup(&store); /* * Test a non existent login and host in our netrc file. */ - s_login = (char *)CURL_UNCONST("me"); + login = (char *)CURL_UNCONST("me"); Curl_netrc_init(&store); result = Curl_parsenetrc(&store, - "test.example.com", &s_login, &s_password, arg); + "test.example.com", &login, &password, arg); fail_unless(result == 1, "Host not found should return 1"); - abort_unless(s_password == NULL, "password is not NULL!"); + abort_unless(password == NULL, "password is not NULL!"); Curl_netrc_cleanup(&store); /* * Test a non existent login (substring of an existing one) in our * netrc file. */ - s_login = (char *)CURL_UNCONST("admi"); + login = (char *)CURL_UNCONST("admi"); /* spellchecker:disable-line */ Curl_netrc_init(&store); result = Curl_parsenetrc(&store, - "example.com", &s_login, &s_password, arg); + "example.com", &login, &password, arg); fail_unless(result == 0, "Host should have been found"); - abort_unless(s_password == NULL, "password is not NULL!"); + abort_unless(password == NULL, "password is not NULL!"); Curl_netrc_cleanup(&store); /* * Test a non existent login (superstring of an existing one) * in our netrc file. */ - s_login = (char *)CURL_UNCONST("adminn"); + login = (char *)CURL_UNCONST("adminn"); Curl_netrc_init(&store); result = Curl_parsenetrc(&store, - "example.com", &s_login, &s_password, arg); + "example.com", &login, &password, arg); fail_unless(result == 0, "Host should have been found"); - abort_unless(s_password == NULL, "password is not NULL!"); + abort_unless(password == NULL, "password is not NULL!"); Curl_netrc_cleanup(&store); /* * Test for the first existing host in our netrc file - * with s_login[0] = 0. + * with login[0] = 0. */ - s_login = NULL; + login = NULL; Curl_netrc_init(&store); result = Curl_parsenetrc(&store, - "example.com", &s_login, &s_password, arg); + "example.com", &login, &password, arg); fail_unless(result == 0, "Host should have been found"); - abort_unless(s_password != NULL, "returned NULL!"); - fail_unless(strncmp(s_password, "passwd", 6) == 0, + abort_unless(password != NULL, "returned NULL!"); + fail_unless(strncmp(password, "passwd", 6) == 0, "password should be 'passwd'"); - abort_unless(s_login != NULL, "returned NULL!"); - fail_unless(strncmp(s_login, "admin", 5) == 0, "login should be 'admin'"); + abort_unless(login != NULL, "returned NULL!"); + fail_unless(strncmp(login, "admin", 5) == 0, "login should be 'admin'"); Curl_netrc_cleanup(&store); /* * Test for the first existing host in our netrc file - * with s_login[0] != 0. + * with login[0] != 0. */ - free(s_password); - free(s_login); - s_password = NULL; - s_login = NULL; + free(password); + free(login); + password = NULL; + login = NULL; Curl_netrc_init(&store); result = Curl_parsenetrc(&store, - "example.com", &s_login, &s_password, arg); + "example.com", &login, &password, arg); fail_unless(result == 0, "Host should have been found"); - abort_unless(s_password != NULL, "returned NULL!"); - fail_unless(strncmp(s_password, "passwd", 6) == 0, + abort_unless(password != NULL, "returned NULL!"); + fail_unless(strncmp(password, "passwd", 6) == 0, "password should be 'passwd'"); - abort_unless(s_login != NULL, "returned NULL!"); - fail_unless(strncmp(s_login, "admin", 5) == 0, "login should be 'admin'"); + abort_unless(login != NULL, "returned NULL!"); + fail_unless(strncmp(login, "admin", 5) == 0, "login should be 'admin'"); Curl_netrc_cleanup(&store); /* * Test for the second existing host in our netrc file - * with s_login[0] = 0. + * with login[0] = 0. */ - free(s_password); - s_password = NULL; - free(s_login); - s_login = NULL; + free(password); + password = NULL; + free(login); + login = NULL; Curl_netrc_init(&store); result = Curl_parsenetrc(&store, - "curl.example.com", &s_login, &s_password, arg); + "curl.example.com", &login, &password, arg); fail_unless(result == 0, "Host should have been found"); - abort_unless(s_password != NULL, "returned NULL!"); - fail_unless(strncmp(s_password, "none", 4) == 0, + abort_unless(password != NULL, "returned NULL!"); + fail_unless(strncmp(password, "none", 4) == 0, "password should be 'none'"); - abort_unless(s_login != NULL, "returned NULL!"); - fail_unless(strncmp(s_login, "none", 4) == 0, "login should be 'none'"); + abort_unless(login != NULL, "returned NULL!"); + fail_unless(strncmp(login, "none", 4) == 0, "login should be 'none'"); Curl_netrc_cleanup(&store); /* * Test for the second existing host in our netrc file - * with s_login[0] != 0. + * with login[0] != 0. */ - free(s_password); - free(s_login); - s_password = NULL; - s_login = NULL; + free(password); + free(login); + password = NULL; + login = NULL; Curl_netrc_init(&store); result = Curl_parsenetrc(&store, - "curl.example.com", &s_login, &s_password, arg); + "curl.example.com", &login, &password, arg); fail_unless(result == 0, "Host should have been found"); - abort_unless(s_password != NULL, "returned NULL!"); - fail_unless(strncmp(s_password, "none", 4) == 0, + abort_unless(password != NULL, "returned NULL!"); + fail_unless(strncmp(password, "none", 4) == 0, "password should be 'none'"); - abort_unless(s_login != NULL, "returned NULL!"); - fail_unless(strncmp(s_login, "none", 4) == 0, "login should be 'none'"); + abort_unless(login != NULL, "returned NULL!"); + fail_unless(strncmp(login, "none", 4) == 0, "login should be 'none'"); Curl_netrc_cleanup(&store); + + UNITTEST_END(t1304_stop(&password, &login)) } -UNITTEST_STOP #else -static CURLcode unit_setup(void) -{ - return CURLE_OK; -} -static void unit_stop(void) + +static CURLcode test_unit1304(const char *arg) { + UNITTEST_BEGIN_SIMPLE + UNITTEST_END_SIMPLE } -UNITTEST_START -UNITTEST_STOP #endif diff --git a/vendor/curl/tests/unit/unit1305.c b/vendor/curl/tests/unit/unit1305.c index 2df5f284a22..e95e2994535 100644 --- a/vendor/curl/tests/unit/unit1305.c +++ b/vendor/curl/tests/unit/unit1305.c @@ -21,43 +21,34 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #ifdef HAVE_NETINET_IN_H -# include +#include #endif #ifdef HAVE_NETDB_H -# include +#include #endif #ifdef HAVE_ARPA_INET_H -# include +#include #endif -#include - #include "hash.h" #include "hostip.h" #include "memdebug.h" /* LAST include file */ -static struct Curl_easy *testdata; static struct Curl_dnscache hp; static char *data_key; static struct Curl_dns_entry *data_node; -static CURLcode unit_setup(void) +static CURLcode t1305_setup(void) { - testdata = curl_easy_init(); - if(!testdata) { - curl_global_cleanup(); - return CURLE_OUT_OF_MEMORY; - } - Curl_dnscache_init(&hp, 7); return CURLE_OK; } -static void unit_stop(void) +static void t1305_stop(void) { if(data_node) { Curl_freeaddrinfo(data_node->addr); @@ -65,15 +56,12 @@ static void unit_stop(void) } free(data_key); Curl_dnscache_destroy(&hp); - - curl_easy_cleanup(testdata); - curl_global_cleanup(); } static struct Curl_addrinfo *fake_ai(void) { static struct Curl_addrinfo *ai; - static const char dummy[]="dummy"; + static const char dummy[] = "dummy"; size_t namelen = sizeof(dummy); /* including the null-terminator */ ai = calloc(1, sizeof(struct Curl_addrinfo) + sizeof(struct sockaddr_in) + @@ -109,14 +97,15 @@ static CURLcode create_node(void) return CURLE_OK; } - -UNITTEST_START +static CURLcode test_unit1305(const char *arg) +{ + UNITTEST_BEGIN(t1305_setup()) struct Curl_dns_entry *nodep; size_t key_len; /* Test 1305 exits without adding anything to the hash */ - if(strcmp(arg, "1305") != 0) { + if(testnum == 1306) { CURLcode rc = create_node(); abort_unless(rc == CURLE_OK, "data node creation failed"); key_len = strlen(data_key); @@ -128,4 +117,5 @@ UNITTEST_START data_node = NULL; } -UNITTEST_STOP + UNITTEST_END(t1305_stop()) +} diff --git a/vendor/curl/tests/unit/unit1307.c b/vendor/curl/tests/unit/unit1307.c index 5f678cffc90..6eb1d4826b7 100644 --- a/vendor/curl/tests/unit/unit1307.c +++ b/vendor/curl/tests/unit/unit1307.c @@ -21,19 +21,10 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "curl_fnmatch.h" -static CURLcode unit_setup(void) -{ - return CURLE_OK; -} - -static void unit_stop(void) -{ -} - #ifndef CURL_DISABLE_FTP /* @@ -57,202 +48,6 @@ static void unit_stop(void) #define MAC_NOMATCH ((CURL_FNMATCH_NOMATCH << MAC_SHIFT) | MAC_DIFFER) #define MAC_FAIL ((CURL_FNMATCH_FAIL << MAC_SHIFT) | MAC_DIFFER) -struct testcase { - const char *pattern; - const char *string; - int result; -}; - -static const struct testcase tests[] = { - /* brackets syntax */ - {"*[*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" - "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" - "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\001\177[[[[[[[[[[[[[[[[[[[[[", - "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" - "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" - "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[", - NOMATCH|MAC_FAIL}, - - { "\\[", "[", MATCH }, - { "[", "[", NOMATCH|LINUX_MATCH|MAC_FAIL}, - { "[]", "[]", NOMATCH|LINUX_MATCH|MAC_FAIL}, - { "[][]", "[", MATCH }, - { "[][]", "]", MATCH }, - { "[[]", "[", MATCH }, - { "[[[]", "[", MATCH }, - { "[[[[]", "[", MATCH }, - { "[[[[]", "[", MATCH }, - - { "[][[]", "]", MATCH }, - { "[][[[]", "[", MATCH }, - { "[[]", "]", NOMATCH }, - - { "[a@]", "a", MATCH }, - - { "[a-z]", "a", MATCH }, - { "[a-z]", "A", NOMATCH }, - { "?[a-z]", "?Z", NOMATCH }, - { "[A-Z]", "C", MATCH }, - { "[A-Z]", "c", NOMATCH }, - { "[0-9]", "7", MATCH }, - { "[7-8]", "7", MATCH }, - { "[7-]", "7", MATCH }, - { "[7-]", "-", MATCH }, - { "[7-]", "[", NOMATCH }, - { "[a-bA-F]", "F", MATCH }, - { "[a-bA-B9]", "9", MATCH }, - { "[a-bA-B98]", "8", MATCH }, - { "[a-bA-B98]", "C", NOMATCH }, - { "[a-bA-Z9]", "F", MATCH }, - { "[a-bA-Z9]ero*", "Zero chance.", MATCH }, - { "S[a-][x]opho*", "Saxophone", MATCH }, - { "S[a-][x]opho*", "SaXophone", NOMATCH }, - { "S[a-][x]*.txt", "S-x.txt", MATCH }, - { "[\\a-\\b]", "a", MATCH }, - { "[\\a-\\b]", "b", MATCH }, - { "[?*[][?*[][?*[]", "?*[", MATCH }, - { "[][?*-]", "]", MATCH }, - { "[][?*-]", "[", MATCH }, - { "[][?*-]", "?", MATCH }, - { "[][?*-]", "*", MATCH }, - { "[][?*-]", "-", MATCH }, - { "[]?*-]", "-", MATCH }, - { "[\xFF]", "\xFF", MATCH|LINUX_FAIL|MAC_FAIL}, - { "?/b/c", "a/b/c", MATCH }, - { "^_{}~", "^_{}~", MATCH }, - { "!#%+,-./01234567889", "!#%+,-./01234567889", MATCH }, - { "PQRSTUVWXYZ]abcdefg", "PQRSTUVWXYZ]abcdefg", MATCH }, - { ":;=@ABCDEFGHIJKLMNO", ":;=@ABCDEFGHIJKLMNO", MATCH }, - - /* negate */ - { "[!a]", "b", MATCH }, - { "[!a]", "a", NOMATCH }, - { "[^a]", "b", MATCH }, - { "[^a]", "a", NOMATCH }, - { "[^a-z0-9A-Z]", "a", NOMATCH }, - { "[^a-z0-9A-Z]", "-", MATCH }, - { "curl[!a-z]lib", "curl lib", MATCH }, - { "curl[! ]lib", "curl lib", NOMATCH }, - { "[! ][ ]", " ", NOMATCH }, - { "[! ][ ]", "a ", MATCH }, - { "*[^a].t?t", "a.txt", NOMATCH }, - { "*[^a].t?t", "ba.txt", NOMATCH }, - { "*[^a].t?t", "ab.txt", MATCH }, - { "*[^a]", "", NOMATCH }, - { "[!\xFF]", "", NOMATCH|LINUX_FAIL}, - { "[!\xFF]", "\xFF", NOMATCH|LINUX_FAIL|MAC_FAIL}, - { "[!\xFF]", "a", MATCH|LINUX_FAIL|MAC_FAIL}, - { "[!?*[]", "?", NOMATCH }, - { "[!!]", "!", NOMATCH }, - { "[!!]", "x", MATCH }, - - { "[[:alpha:]]", "a", MATCH }, - { "[[:alpha:]]", "9", NOMATCH }, - { "[[:alnum:]]", "a", MATCH }, - { "[[:alnum:]]", "[", NOMATCH }, - { "[[:alnum:]]", "]", NOMATCH }, - { "[[:alnum:]]", "9", MATCH }, - { "[[:digit:]]", "9", MATCH }, - { "[[:xdigit:]]", "9", MATCH }, - { "[[:xdigit:]]", "F", MATCH }, - { "[[:xdigit:]]", "G", NOMATCH }, - { "[[:upper:]]", "U", MATCH }, - { "[[:upper:]]", "u", NOMATCH }, - { "[[:lower:]]", "l", MATCH }, - { "[[:lower:]]", "L", NOMATCH }, - { "[[:print:]]", "L", MATCH }, - { "[[:print:]]", "\10", NOMATCH }, - { "[[:print:]]", "\10", NOMATCH }, - { "[[:space:]]", " ", MATCH }, - { "[[:space:]]", "x", NOMATCH }, - { "[[:graph:]]", " ", NOMATCH }, - { "[[:graph:]]", "x", MATCH }, - { "[[:blank:]]", "\t", MATCH }, - { "[[:blank:]]", " ", MATCH }, - { "[[:blank:]]", "\r", NOMATCH }, - { "[^[:blank:]]", "\t", NOMATCH }, - { "[^[:print:]]", "\10", MATCH }, - { "[[:lower:]][[:lower:]]", "ll", MATCH }, - { "[[:foo:]]", "bar", NOMATCH|MAC_FAIL}, - { "[[:foo:]]", "f]", MATCH|LINUX_NOMATCH|MAC_FAIL}, - - { "Curl[[:blank:]];-)", "Curl ;-)", MATCH }, - { "*[[:blank:]]*", " ", MATCH }, - { "*[[:blank:]]*", "", NOMATCH }, - { "*[[:blank:]]*", "hi, im_Pavel", MATCH }, - - /* common using */ - { "filename.dat", "filename.dat", MATCH }, - { "*curl*", "lets use curl!!", MATCH }, - { "filename.txt", "filename.dat", NOMATCH }, - { "*.txt", "text.txt", MATCH }, - { "*.txt", "a.txt", MATCH }, - { "*.txt", ".txt", MATCH }, - { "*.txt", "txt", NOMATCH }, - { "??.txt", "99.txt", MATCH }, - { "??.txt", "a99.txt", NOMATCH }, - { "?.???", "a.txt", MATCH }, - { "*.???", "somefile.dat", MATCH }, - { "*.???", "photo.jpeg", NOMATCH }, - { ".*", ".htaccess", MATCH }, - { ".*", ".", MATCH }, - { ".*", "..", MATCH }, - - /* many stars => one star */ - { "**.txt", "text.txt", MATCH }, - { "***.txt", "t.txt", MATCH }, - { "****.txt", ".txt", MATCH }, - - /* empty string or pattern */ - { "", "", MATCH }, - { "", "hello", NOMATCH }, - { "file", "", NOMATCH }, - { "?", "", NOMATCH }, - { "*", "", MATCH }, - { "x", "", NOMATCH }, - - /* backslash */ - { "\\", "\\", MATCH|LINUX_NOMATCH}, - { "\\\\", "\\", MATCH }, - { "\\\\", "\\\\", NOMATCH }, - { "\\?", "?", MATCH }, - { "\\*", "*", MATCH }, - { "?.txt", "?.txt", MATCH }, - { "*.txt", "*.txt", MATCH }, - { "\\?.txt", "?.txt", MATCH }, - { "\\*.txt", "*.txt", MATCH }, - { "\\?.txt", "x.txt", NOMATCH }, - { "\\*.txt", "x.txt", NOMATCH }, - { "\\*\\\\.txt", "*\\.txt", MATCH }, - { "*\\**\\?*\\\\*", "cc*cc?cccc", NOMATCH }, - { "*\\?*\\**", "cc?cc", NOMATCH }, - { "\\\"\\$\\&\\'\\(\\)", "\"$&'()", MATCH }, - { "\\*\\?\\[\\\\\\`\\|", "*?[\\`|", MATCH }, - { "[\\a\\b]c", "ac", MATCH }, - { "[\\a\\b]c", "bc", MATCH }, - { "[\\a\\b]d", "bc", NOMATCH }, - { "[a-bA-B\\?]", "?", MATCH }, - { "cu[a-ab-b\\r]l", "curl", MATCH }, - { "[\\a-z]", "c", MATCH }, - - { "?*?*?.*?*", "abc.c", MATCH }, - { "?*?*?.*?*", "abcc", NOMATCH }, - { "?*?*?.*?*", "abc.", NOMATCH }, - { "?*?*?.*?*", "abc.c++", MATCH }, - { "?*?*?.*?*", "abcdef.c++", MATCH }, - { "?*?*?.?", "abcdef.c", MATCH }, - { "?*?*?.?", "abcdef.cd", NOMATCH }, - - /* https://codepoints.net/U+00E4 Latin Small Letter A with Diaeresis */ - { "Lindm\xc3\xa4tarv", "Lindm\xc3\xa4tarv", MATCH }, - - { "", "", MATCH}, - {"**]*[*[\x13]**[*\x13)]*]*[**[*\x13~r-]*]**[.*]*[\xe3\xe3\xe3\xe3\xe3\xe3" - "\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3" - "\xe3\xe3\xe3\xe3\xe3*[\x13]**[*\x13)]*]*[*[\x13]*[~r]*]*\xba\x13\xa6~b-]*", - "a", NOMATCH|LINUX_FAIL} -}; - static const char *ret2name(int i) { switch(i) { @@ -268,15 +63,215 @@ static const char *ret2name(int i) /* not reached */ } -enum system { - SYSTEM_CUSTOM, - SYSTEM_LINUX, - SYSTEM_MACOS -}; - -UNITTEST_START +static CURLcode test_unit1307(const char *arg) { + UNITTEST_BEGIN_SIMPLE + + struct testcase { + const char *pattern; + const char *string; + int result; + }; + + static const struct testcase tests[] = { + /* brackets syntax */ + {"*[*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\001\177[[[[[[[[[[[[[[[[[[[[[", + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[", + NOMATCH|MAC_FAIL}, + + { "\\[", "[", MATCH }, + { "[", "[", NOMATCH|LINUX_MATCH|MAC_FAIL}, + { "[]", "[]", NOMATCH|LINUX_MATCH|MAC_FAIL}, + { "[][]", "[", MATCH }, + { "[][]", "]", MATCH }, + { "[[]", "[", MATCH }, + { "[[[]", "[", MATCH }, + { "[[[[]", "[", MATCH }, + { "[[[[]", "[", MATCH }, + + { "[][[]", "]", MATCH }, + { "[][[[]", "[", MATCH }, + { "[[]", "]", NOMATCH }, + + { "[a@]", "a", MATCH }, + + { "[a-z]", "a", MATCH }, + { "[a-z]", "A", NOMATCH }, + { "?[a-z]", "?Z", NOMATCH }, + { "[A-Z]", "C", MATCH }, + { "[A-Z]", "c", NOMATCH }, + { "[0-9]", "7", MATCH }, + { "[7-8]", "7", MATCH }, + { "[7-]", "7", MATCH }, + { "[7-]", "-", MATCH }, + { "[7-]", "[", NOMATCH }, + { "[a-bA-F]", "F", MATCH }, + { "[a-bA-B9]", "9", MATCH }, + { "[a-bA-B98]", "8", MATCH }, + { "[a-bA-B98]", "C", NOMATCH }, + { "[a-bA-Z9]", "F", MATCH }, + { "[a-bA-Z9]ero*", "Zero chance.", MATCH }, + { "S[a-][x]opho*", "Saxophone", MATCH }, + { "S[a-][x]opho*", "SaXophone", NOMATCH }, + { "S[a-][x]*.txt", "S-x.txt", MATCH }, + { "[\\a-\\b]", "a", MATCH }, + { "[\\a-\\b]", "b", MATCH }, + { "[?*[][?*[][?*[]", "?*[", MATCH }, + { "[][?*-]", "]", MATCH }, + { "[][?*-]", "[", MATCH }, + { "[][?*-]", "?", MATCH }, + { "[][?*-]", "*", MATCH }, + { "[][?*-]", "-", MATCH }, + { "[]?*-]", "-", MATCH }, + { "[\xFF]", "\xFF", MATCH|LINUX_FAIL|MAC_FAIL}, + { "?/b/c", "a/b/c", MATCH }, + { "^_{}~", "^_{}~", MATCH }, + { "!#%+,-./01234567889", "!#%+,-./01234567889", MATCH }, + { "PQRSTUVWXYZ]abcdefg", "PQRSTUVWXYZ]abcdefg", MATCH }, + { ":;=@ABCDEFGHIJKLMNO", ":;=@ABCDEFGHIJKLMNO", MATCH }, + + /* negate */ + { "[!a]", "b", MATCH }, + { "[!a]", "a", NOMATCH }, + { "[^a]", "b", MATCH }, + { "[^a]", "a", NOMATCH }, + { "[^a-z0-9A-Z]", "a", NOMATCH }, + { "[^a-z0-9A-Z]", "-", MATCH }, + { "curl[!a-z]lib", "curl lib", MATCH }, + { "curl[! ]lib", "curl lib", NOMATCH }, + { "[! ][ ]", " ", NOMATCH }, + { "[! ][ ]", "a ", MATCH }, + { "*[^a].t?t", "a.txt", NOMATCH }, + { "*[^a].t?t", "ca.txt", NOMATCH }, + { "*[^a].t?t", "ac.txt", MATCH }, + { "*[^a]", "", NOMATCH }, + { "[!\xFF]", "", NOMATCH|LINUX_FAIL}, + { "[!\xFF]", "\xFF", NOMATCH|LINUX_FAIL|MAC_FAIL}, + { "[!\xFF]", "a", MATCH|LINUX_FAIL|MAC_FAIL}, + { "[!?*[]", "?", NOMATCH }, + { "[!!]", "!", NOMATCH }, + { "[!!]", "x", MATCH }, + + { "[[:alpha:]]", "a", MATCH }, + { "[[:alpha:]]", "9", NOMATCH }, + { "[[:alnum:]]", "a", MATCH }, + { "[[:alnum:]]", "[", NOMATCH }, + { "[[:alnum:]]", "]", NOMATCH }, + { "[[:alnum:]]", "9", MATCH }, + { "[[:digit:]]", "9", MATCH }, + { "[[:xdigit:]]", "9", MATCH }, + { "[[:xdigit:]]", "F", MATCH }, + { "[[:xdigit:]]", "G", NOMATCH }, + { "[[:upper:]]", "U", MATCH }, + { "[[:upper:]]", "u", NOMATCH }, + { "[[:lower:]]", "l", MATCH }, + { "[[:lower:]]", "L", NOMATCH }, + { "[[:print:]]", "L", MATCH }, + { "[[:print:]]", "\10", NOMATCH }, + { "[[:print:]]", "\10", NOMATCH }, + { "[[:space:]]", " ", MATCH }, + { "[[:space:]]", "x", NOMATCH }, + { "[[:graph:]]", " ", NOMATCH }, + { "[[:graph:]]", "x", MATCH }, + { "[[:blank:]]", "\t", MATCH }, + { "[[:blank:]]", " ", MATCH }, + { "[[:blank:]]", "\r", NOMATCH }, + { "[^[:blank:]]", "\t", NOMATCH }, + { "[^[:print:]]", "\10", MATCH }, + { "[[:lower:]][[:lower:]]", "ll", MATCH }, + { "[[:foo:]]", "bar", NOMATCH|MAC_FAIL}, + { "[[:foo:]]", "f]", MATCH|LINUX_NOMATCH|MAC_FAIL}, + + { "Curl[[:blank:]];-)", "Curl ;-)", MATCH }, + { "*[[:blank:]]*", " ", MATCH }, + { "*[[:blank:]]*", "", NOMATCH }, + { "*[[:blank:]]*", "hi, im_Pavel", MATCH }, + + /* common using */ + { "filename.dat", "filename.dat", MATCH }, + { "*curl*", "lets use curl!!", MATCH }, + { "filename.txt", "filename.dat", NOMATCH }, + { "*.txt", "text.txt", MATCH }, + { "*.txt", "a.txt", MATCH }, + { "*.txt", ".txt", MATCH }, + { "*.txt", "txt", NOMATCH }, + { "??.txt", "99.txt", MATCH }, + { "??.txt", "a99.txt", NOMATCH }, + { "?.???", "a.txt", MATCH }, + { "*.???", "somefile.dat", MATCH }, + { "*.???", "photo.jpeg", NOMATCH }, + { ".*", ".htaccess", MATCH }, + { ".*", ".", MATCH }, + { ".*", "..", MATCH }, + + /* many stars => one star */ + { "**.txt", "text.txt", MATCH }, + { "***.txt", "t.txt", MATCH }, + { "****.txt", ".txt", MATCH }, + + /* empty string or pattern */ + { "", "", MATCH }, + { "", "hello", NOMATCH }, + { "file", "", NOMATCH }, + { "?", "", NOMATCH }, + { "*", "", MATCH }, + { "x", "", NOMATCH }, + + /* backslash */ + { "\\", "\\", MATCH|LINUX_NOMATCH}, + { "\\\\", "\\", MATCH }, + { "\\\\", "\\\\", NOMATCH }, + { "\\?", "?", MATCH }, + { "\\*", "*", MATCH }, + { "?.txt", "?.txt", MATCH }, + { "*.txt", "*.txt", MATCH }, + { "\\?.txt", "?.txt", MATCH }, + { "\\*.txt", "*.txt", MATCH }, + { "\\?.txt", "x.txt", NOMATCH }, + { "\\*.txt", "x.txt", NOMATCH }, + { "\\*\\\\.txt", "*\\.txt", MATCH }, + { "*\\**\\?*\\\\*", "cc*cc?cccc", NOMATCH }, + { "*\\?*\\**", "cc?cc", NOMATCH }, + { "\\\"\\$\\&\\'\\(\\)", "\"$&'()", MATCH }, + { "\\*\\?\\[\\\\\\`\\|", "*?[\\`|", MATCH }, + { "[\\a\\b]c", "ac", MATCH }, + { "[\\a\\b]c", "bc", MATCH }, + { "[\\a\\b]d", "bc", NOMATCH }, + { "[a-bA-B\\?]", "?", MATCH }, + { "cu[a-ab-b\\r]l", "curl", MATCH }, + { "[\\a-z]", "c", MATCH }, + + { "?*?*?.*?*", "abc.c", MATCH }, + { "?*?*?.*?*", "abcc", NOMATCH }, + { "?*?*?.*?*", "abc.", NOMATCH }, + { "?*?*?.*?*", "abc.c++", MATCH }, + { "?*?*?.*?*", "abcdef.c++", MATCH }, + { "?*?*?.?", "abcdef.c", MATCH }, + { "?*?*?.?", "abcdef.cd", NOMATCH }, + + /* https://codepoints.net/U+00E4 Latin Small Letter A with Diaeresis */ + { "Lindm\xc3\xa4tarv", "Lindm\xc3\xa4tarv", MATCH }, + + { "", "", MATCH}, + {"**]*[*[\x13]**[*\x13)]*]*[**[*\x13~r-]*]**[.*]*[\xe3\xe3\xe3\xe3\xe3\xe3" + "\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3" + "\xe3\xe3\xe3\xe3\xe3*[\x13]**[*\x13)]*]*[*[\x13]*[~r]*]*\xba\x13\xa6~b-]" + "*", + "a", NOMATCH|LINUX_FAIL} + }; + int i; + + enum system { + SYSTEM_CUSTOM, + SYSTEM_LINUX, + SYSTEM_MACOS + }; + enum system machine; #ifdef HAVE_FNMATCH @@ -310,12 +305,16 @@ UNITTEST_START fail("pattern mismatch"); } } + + UNITTEST_END_SIMPLE } -UNITTEST_STOP #else -UNITTEST_START -UNITTEST_STOP +static CURLcode test_unit1307(const char *arg) +{ + UNITTEST_BEGIN_SIMPLE + UNITTEST_END_SIMPLE +} #endif diff --git a/vendor/curl/tests/unit/unit1309.c b/vendor/curl/tests/unit/unit1309.c index 2cbab546d82..35b38fd8b62 100644 --- a/vendor/curl/tests/unit/unit1309.c +++ b/vendor/curl/tests/unit/unit1309.c @@ -21,21 +21,9 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "splay.h" -#include "warnless.h" - - -static CURLcode unit_setup(void) -{ - return CURLE_OK; -} - -static void unit_stop(void) -{ - -} static void splayprint(struct Curl_tree *t, int d, char output) { @@ -51,8 +39,7 @@ static void splayprint(struct Curl_tree *t, int d, char output) printf(" "); if(output) { - printf("%ld.%ld[%d]", (long)t->key.tv_sec, - (long)t->key.tv_usec, i); + printf("%ld.%ld[%d]", (long)t->key.tv_sec, (long)t->key.tv_usec, i); } for(count = 0, node = t->samen; node != t; node = node->samen, count++) @@ -68,7 +55,9 @@ static void splayprint(struct Curl_tree *t, int d, char output) splayprint(t->smaller, d + 1, output); } -UNITTEST_START +static CURLcode test_unit1309(const char *arg) +{ + UNITTEST_BEGIN_SIMPLE /* number of nodes to add to the splay tree */ #define NUM_NODES 50 @@ -141,4 +130,5 @@ UNITTEST_START fail_unless(root == NULL, "tree not empty when it should be"); -UNITTEST_STOP + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/unit1323.c b/vendor/curl/tests/unit/unit1323.c index 3f5ee334bb9..f53df89226d 100644 --- a/vendor/curl/tests/unit/unit1323.c +++ b/vendor/curl/tests/unit/unit1323.c @@ -21,34 +21,25 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" -#include "timeval.h" - -static CURLcode unit_setup(void) +static CURLcode test_unit1323(const char *arg) { - return CURLE_OK; -} - -static void unit_stop(void) -{ - -} + UNITTEST_BEGIN_SIMPLE -struct a { - struct curltime first; - struct curltime second; - time_t result; -}; + struct a { + struct curltime first; + struct curltime second; + time_t result; + }; -UNITTEST_START -{ struct a tests[] = { { {36762, 8345 }, {36761, 995926 }, 13 }, { {36761, 995926 }, {36762, 8345 }, -13 }, { {36761, 995926 }, {0, 0}, 36761995 }, { {0, 0}, {36761, 995926 }, -36761995 }, }; + size_t i; for(i = 0; i < CURL_ARRAYSIZE(tests); i++) { @@ -64,5 +55,6 @@ UNITTEST_START fail("unexpected result!"); } } + + UNITTEST_END_SIMPLE } -UNITTEST_STOP diff --git a/vendor/curl/tests/unit/unit1330.c b/vendor/curl/tests/unit/unit1330.c index 2e27e8093fa..bd7fc6e2592 100644 --- a/vendor/curl/tests/unit/unit1330.c +++ b/vendor/curl/tests/unit/unit1330.c @@ -21,23 +21,16 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "memdebug.h" - -static CURLcode unit_setup(void) +static CURLcode test_unit1330(const char *arg) { - return CURLE_OK; -} + UNITTEST_BEGIN_SIMPLE -static void unit_stop(void) -{ -} + char *ptr = malloc(1330); + Curl_safefree(ptr); -UNITTEST_START - -char *ptr = malloc(1330); -Curl_safefree(ptr); - -UNITTEST_STOP + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/unit1395.c b/vendor/curl/tests/unit/unit1395.c index 130fc0748fc..e6ac18f0810 100644 --- a/vendor/curl/tests/unit/unit1395.c +++ b/vendor/curl/tests/unit/unit1395.c @@ -21,32 +21,22 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" - -/* copied from urlapi.c */ -extern int dedotdotify(const char *input, size_t clen, char **out); - +#include "unitcheck.h" #include "memdebug.h" +#include "unitprotos.h" -static CURLcode unit_setup(void) +static CURLcode test_unit1395(const char *arg) { - return CURLE_OK; -} - -static void unit_stop(void) -{ - -} - -struct dotdot { - const char *input; - const char *output; -}; - -UNITTEST_START + UNITTEST_BEGIN_SIMPLE unsigned int i; int fails = 0; + + struct dotdot { + const char *input; + const char *output; + }; + const struct dotdot pairs[] = { { "%2f%2e%2e%2f/../a", "%2f%2e%2e%2f/a" }, { "%2f%2e%2e%2f/../", "%2f%2e%2e%2f/" }, @@ -148,4 +138,5 @@ UNITTEST_START fail_if(fails, "output mismatched"); -UNITTEST_STOP + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/unit1396.c b/vendor/curl/tests/unit/unit1396.c index 43f9c866726..aa7ee933758 100644 --- a/vendor/curl/tests/unit/unit1396.c +++ b/vendor/curl/tests/unit/unit1396.c @@ -21,36 +21,37 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" -static CURL *hnd; - -static CURLcode unit_setup(void) +static CURLcode t1396_setup(void) { CURLcode res = CURLE_OK; - global_init(CURL_GLOBAL_ALL); return res; } -static void unit_stop(void) +static void t1396_stop(CURL *easy) { - if(hnd) - curl_easy_cleanup(hnd); + if(easy) + curl_easy_cleanup(easy); curl_global_cleanup(); } -struct test { - const char *in; - int inlen; - const char *out; - int outlen; -}; - -UNITTEST_START +static CURLcode test_unit1396(const char *arg) { + CURL *easy; + + UNITTEST_BEGIN(t1396_setup()) + + struct test { + const char *in; + int inlen; + const char *out; + int outlen; + }; + /* unescape, this => that */ - const struct test list1[]={ + const struct test list1[] = { {"%61", 3, "a", 1}, {"%61a", 4, "aa", 2}, {"%61b", 4, "ab", 2}, @@ -66,7 +67,7 @@ UNITTEST_START {NULL, 0, NULL, 0} /* end of list marker */ }; /* escape, this => that */ - const struct test list2[]={ + const struct test list2[] = { {"a", 1, "a", 1}, {"/", 1, "%2F", 3}, {"a=b", 3, "a%3Db", 5}, @@ -81,11 +82,11 @@ UNITTEST_START }; int i; - hnd = curl_easy_init(); - abort_unless(hnd != NULL, "returned NULL!"); + easy = curl_easy_init(); + abort_unless(easy != NULL, "returned NULL!"); for(i = 0; list1[i].in; i++) { int outlen; - char *out = curl_easy_unescape(hnd, + char *out = curl_easy_unescape(easy, list1[i].in, list1[i].inlen, &outlen); @@ -101,7 +102,7 @@ UNITTEST_START for(i = 0; list2[i].in; i++) { int outlen; - char *out = curl_easy_escape(hnd, list2[i].in, list2[i].inlen); + char *out = curl_easy_escape(easy, list2[i].in, list2[i].inlen); abort_unless(out != NULL, "returned NULL!"); outlen = (int)strlen(out); @@ -113,5 +114,6 @@ UNITTEST_START curl_free(out); } + + UNITTEST_END(t1396_stop(easy)) } -UNITTEST_STOP diff --git a/vendor/curl/tests/unit/unit1397.c b/vendor/curl/tests/unit/unit1397.c index 1ac2fa9be9b..7d3d4fd7f79 100644 --- a/vendor/curl/tests/unit/unit1397.c +++ b/vendor/curl/tests/unit/unit1397.c @@ -21,82 +21,76 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" +#include "vtls/hostcheck.h" -static CURLcode unit_setup(void) +static CURLcode test_unit1397(const char *arg) { - return CURLE_OK; -} - -static void unit_stop(void) -{ -} + UNITTEST_BEGIN_SIMPLE /* only these backends define the tested functions */ #if defined(USE_OPENSSL) || defined(USE_SCHANNEL) -#include "vtls/hostcheck.h" -struct testcase { - const char *host; - const char *pattern; - bool match; -}; -static struct testcase tests[] = { - {"", "", FALSE}, - {"a", "", FALSE}, - {"", "b", FALSE}, - {"a", "b", FALSE}, - {"aa", "bb", FALSE}, - {"\xff", "\xff", TRUE}, - {"aa.aa.aa", "aa.aa.bb", FALSE}, - {"aa.aa.aa", "aa.aa.aa", TRUE}, - {"aa.aa.aa", "*.aa.bb", FALSE}, - {"aa.aa.aa", "*.aa.aa", TRUE}, - {"192.168.0.1", "192.168.0.1", TRUE}, - {"192.168.0.1", "*.168.0.1", FALSE}, - {"192.168.0.1", "*.0.1", FALSE}, - {"h.ello", "*.ello", FALSE}, - {"h.ello.", "*.ello", FALSE}, - {"h.ello", "*.ello.", FALSE}, - {"h.e.llo", "*.e.llo", TRUE}, - {"h.e.llo", " *.e.llo", FALSE}, - {" h.e.llo", "*.e.llo", TRUE}, - {"h.e.llo.", "*.e.llo", TRUE}, - {"*.e.llo.", "*.e.llo", TRUE}, - {"************.e.llo.", "*.e.llo", TRUE}, - {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" - "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" - "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" - ".e.llo.", "*.e.llo", TRUE}, - {"\xfe\xfe.e.llo.", "*.e.llo", TRUE}, - {"h.e.llo.", "*.e.llo.", TRUE}, - {"h.e.llo", "*.e.llo.", TRUE}, - {".h.e.llo", "*.e.llo.", FALSE}, - {"h.e.llo", "*.*.llo.", FALSE}, - {"h.e.llo", "h.*.llo", FALSE}, - {"h.e.llo", "h.e.*", FALSE}, - {"hello", "*.ello", FALSE}, - {"hello", "**llo", FALSE}, - {"bar.foo.example.com", "*.example.com", FALSE}, - {"foo.example.com", "*.example.com", TRUE}, - {"baz.example.net", "b*z.example.net", FALSE}, - {"foobaz.example.net", "*baz.example.net", FALSE}, - {"xn--l8j.example.local", "x*.example.local", FALSE}, - {"xn--l8j.example.net", "*.example.net", TRUE}, - {"xn--l8j.example.net", "*j.example.net", FALSE}, - {"xn--l8j.example.net", "xn--l8j.example.net", TRUE}, - {"xn--l8j.example.net", "xn--l8j.*.net", FALSE}, - {"xl8j.example.net", "*.example.net", TRUE}, - {"fe80::3285:a9ff:fe46:b619", "*::3285:a9ff:fe46:b619", FALSE}, - {"fe80::3285:a9ff:fe46:b619", "fe80::3285:a9ff:fe46:b619", TRUE}, - {NULL, NULL, FALSE} -}; + struct testcase { + const char *host; + const char *pattern; + bool match; + }; + + static const struct testcase tests[] = { + {"", "", FALSE}, + {"a", "", FALSE}, + {"", "b", FALSE}, + {"a", "b", FALSE}, + {"aa", "bb", FALSE}, + {"\xff", "\xff", TRUE}, + {"aa.aa.aa", "aa.aa.bb", FALSE}, + {"aa.aa.aa", "aa.aa.aa", TRUE}, + {"aa.aa.aa", "*.aa.bb", FALSE}, + {"aa.aa.aa", "*.aa.aa", TRUE}, + {"192.168.0.1", "192.168.0.1", TRUE}, + {"192.168.0.1", "*.168.0.1", FALSE}, + {"192.168.0.1", "*.0.1", FALSE}, + {"h.ello", "*.ello", FALSE}, + {"h.ello.", "*.ello", FALSE}, + {"h.ello", "*.ello.", FALSE}, + {"h.e.llo", "*.e.llo", TRUE}, + {"h.e.llo", " *.e.llo", FALSE}, + {" h.e.llo", "*.e.llo", TRUE}, + {"h.e.llo.", "*.e.llo", TRUE}, + {"*.e.llo.", "*.e.llo", TRUE}, + {"************.e.llo.", "*.e.llo", TRUE}, + {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" + "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" + "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" + "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" + ".e.llo.", "*.e.llo", TRUE}, + {"\xfe\xfe.e.llo.", "*.e.llo", TRUE}, + {"h.e.llo.", "*.e.llo.", TRUE}, + {"h.e.llo", "*.e.llo.", TRUE}, + {".h.e.llo", "*.e.llo.", FALSE}, + {"h.e.llo", "*.*.llo.", FALSE}, + {"h.e.llo", "h.*.llo", FALSE}, + {"h.e.llo", "h.e.*", FALSE}, + {"hello", "*.ello", FALSE}, + {"hello", "**llo", FALSE}, + {"bar.foo.example.com", "*.example.com", FALSE}, + {"foo.example.com", "*.example.com", TRUE}, + {"baz.example.net", "b*z.example.net", FALSE}, + {"foobaz.example.net", "*baz.example.net", FALSE}, + {"xn--l8j.example.local", "x*.example.local", FALSE}, + {"xn--l8j.example.net", "*.example.net", TRUE}, + {"xn--l8j.example.net", "*j.example.net", FALSE}, + {"xn--l8j.example.net", "xn--l8j.example.net", TRUE}, + {"xn--l8j.example.net", "xn--l8j.*.net", FALSE}, + {"xl8j.example.net", "*.example.net", TRUE}, + {"fe80::3285:a9ff:fe46:b619", "*::3285:a9ff:fe46:b619", FALSE}, + {"fe80::3285:a9ff:fe46:b619", "fe80::3285:a9ff:fe46:b619", TRUE}, + {NULL, NULL, FALSE} + }; -UNITTEST_START -{ int i; for(i = 0; tests[i].host; i++) { if(tests[i].match != Curl_cert_hostcheck(tests[i].pattern, @@ -113,12 +107,7 @@ UNITTEST_START unitfail++; } } -} - -UNITTEST_STOP -#else - -UNITTEST_START - -UNITTEST_STOP #endif + + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/unit1398.c b/vendor/curl/tests/unit/unit1398.c index 52c571d899e..fcdd3ec9bfd 100644 --- a/vendor/curl/tests/unit/unit1398.c +++ b/vendor/curl/tests/unit/unit1398.c @@ -21,170 +21,170 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #if defined(CURL_GNUC_DIAG) || defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat" #endif -static CURLcode unit_setup(void) {return CURLE_OK;} -static void unit_stop(void) {} - -UNITTEST_START - -int rc; -char buf[3] = {'b', 'u', 'g'}; -const char *str = "bug"; -int width = 3; -char output[130]; - -/*#define curl_msnprintf snprintf */ - -/* without a trailing zero */ -rc = curl_msnprintf(output, 4, "%.*s", width, buf); -fail_unless(rc == 3, "return code should be 3"); -fail_unless(!strcmp(output, "bug"), "wrong output"); - -/* with a trailing zero */ -rc = curl_msnprintf(output, 4, "%.*s", width, str); -fail_unless(rc == 3, "return code should be 3"); -fail_unless(!strcmp(output, "bug"), "wrong output"); - -width = 2; -/* one byte less */ -rc = curl_msnprintf(output, 4, "%.*s", width, buf); -fail_unless(rc == 2, "return code should be 2"); -fail_unless(!strcmp(output, "bu"), "wrong output"); - -/* string with larger precision */ -rc = curl_msnprintf(output, 8, "%.8s", str); -fail_unless(rc == 3, "return code should be 3"); -fail_unless(!strcmp(output, "bug"), "wrong output"); - -/* longer string with precision */ -rc = curl_msnprintf(output, 8, "%.3s", "0123456789"); -fail_unless(rc == 3, "return code should be 3"); -fail_unless(!strcmp(output, "012"), "wrong output"); - -/* negative width */ -rc = curl_msnprintf(output, 8, "%-8s", str); -fail_unless(rc == 7, "return code should be 7"); -fail_unless(!strcmp(output, "bug "), "wrong output"); - -/* larger width that string length */ -rc = curl_msnprintf(output, 8, "%8s", str); -fail_unless(rc == 7, "return code should be 7"); -fail_unless(!strcmp(output, " bu"), "wrong output"); - -/* output a number in a limited output */ -rc = curl_msnprintf(output, 4, "%d", 10240); -fail_unless(rc == 3, "return code should be 3"); -fail_unless(!strcmp(output, "102"), "wrong output"); - -/* padded strings */ -rc = curl_msnprintf(output, 16, "%8s%8s", str, str); -fail_unless(rc == 15, "return code should be 15"); -fail_unless(!strcmp(output, " bug bu"), "wrong output"); - -/* padded numbers */ -rc = curl_msnprintf(output, 16, "%8d%8d", 1234, 5678); -fail_unless(rc == 15, "return code should be 15"); -fail_unless(!strcmp(output, " 1234 567"), "wrong output"); - -/* double precision */ -rc = curl_msnprintf(output, 24, "%2$.*1$.99d", 3, 5678); -fail_unless(rc == 0, "return code should be 0"); - -/* 129 input % flags */ -rc = curl_msnprintf(output, 130, - "%s%s%s%s%s%s%s%s%s%s" /* 10 */ - "%s%s%s%s%s%s%s%s%s%s" /* 20 */ - "%s%s%s%s%s%s%s%s%s%s" /* 30 */ - "%s%s%s%s%s%s%s%s%s%s" /* 40 */ - "%s%s%s%s%s%s%s%s%s%s" /* 50 */ - "%s%s%s%s%s%s%s%s%s%s" /* 60 */ - "%s%s%s%s%s%s%s%s%s%s" /* 70 */ - "%s%s%s%s%s%s%s%s%s%s" /* 80 */ - "%s%s%s%s%s%s%s%s%s%s" /* 90 */ - "%s%s%s%s%s%s%s%s%s%s" /* 100 */ - "%s%s%s%s%s%s%s%s%s%s" /* 110 */ - "%s%s%s%s%s%s%s%s%s%s" /* 120 */ - "%s%s%s%s%s%s%s%s%s", /* 129 */ - - "a", "", "", "", "", "", "", "", "", "", /* 10 */ - "b", "", "", "", "", "", "", "", "", "", /* 20 */ - "c", "", "", "", "", "", "", "", "", "", /* 30 */ - "d", "", "", "", "", "", "", "", "", "", /* 40 */ - "e", "", "", "", "", "", "", "", "", "", /* 50 */ - "f", "", "", "", "", "", "", "", "", "", /* 60 */ - "g", "", "", "", "", "", "", "", "", "", /* 70 */ - "h", "", "", "", "", "", "", "", "", "", /* 80 */ - "i", "", "", "", "", "", "", "", "", "", /* 90 */ - "j", "", "", "", "", "", "", "", "", "", /* 100 */ - "k", "", "", "", "", "", "", "", "", "", /* 110 */ - "l", "", "", "", "", "", "", "", "", "", /* 120 */ - "m", "", "", "", "", "", "", "", "" /* 129 */ - ); -fail_unless(rc == 0, "return code should be 0"); - -/* 128 input % flags */ -rc = curl_msnprintf(output, 130, - "%s%s%s%s%s%s%s%s%s%s" /* 10 */ - "%s%s%s%s%s%s%s%s%s%s" /* 20 */ - "%s%s%s%s%s%s%s%s%s%s" /* 30 */ - "%s%s%s%s%s%s%s%s%s%s" /* 40 */ - "%s%s%s%s%s%s%s%s%s%s" /* 50 */ - "%s%s%s%s%s%s%s%s%s%s" /* 60 */ - "%s%s%s%s%s%s%s%s%s%s" /* 70 */ - "%s%s%s%s%s%s%s%s%s%s" /* 80 */ - "%s%s%s%s%s%s%s%s%s%s" /* 90 */ - "%s%s%s%s%s%s%s%s%s%s" /* 100 */ - "%s%s%s%s%s%s%s%s%s%s" /* 110 */ - "%s%s%s%s%s%s%s%s%s%s" /* 120 */ - "%s%s%s%s%s%s%s%s", /* 128 */ - - "a", "", "", "", "", "", "", "", "", "", /* 10 */ - "b", "", "", "", "", "", "", "", "", "", /* 20 */ - "c", "", "", "", "", "", "", "", "", "", /* 30 */ - "d", "", "", "", "", "", "", "", "", "", /* 40 */ - "e", "", "", "", "", "", "", "", "", "", /* 50 */ - "f", "", "", "", "", "", "", "", "", "", /* 60 */ - "g", "", "", "", "", "", "", "", "", "", /* 70 */ - "h", "", "", "", "", "", "", "", "", "", /* 80 */ - "i", "", "", "", "", "", "", "", "", "", /* 90 */ - "j", "", "", "", "", "", "", "", "", "", /* 100 */ - "k", "", "", "", "", "", "", "", "", "", /* 110 */ - "l", "", "", "", "", "", "", "", "", "", /* 120 */ - "m", "", "", "", "", "", "", "" /* 128 */ - ); -fail_unless(rc == 13, "return code should be 13"); - -/* 129 output segments */ -rc = curl_msnprintf(output, 130, - "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 20 */ - "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 40 */ - "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 60 */ - "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 80 */ - "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 100 */ - "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 120 */ - "%%%%%%%%%%%%%%%%%%" /* 129 */ - ); -fail_unless(rc == 0, "return code should be 0"); - -/* 128 output segments */ -rc = curl_msnprintf(output, 129, - "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 20 */ - "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 40 */ - "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 60 */ - "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 80 */ - "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 100 */ - "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 120 */ - "%%%%%%%%%%%%%%%%" /* 128 */ - ); -fail_unless(rc == 128, "return code should be 128"); - -UNITTEST_STOP +static CURLcode test_unit1398(const char *arg) +{ + UNITTEST_BEGIN_SIMPLE + + int rc; + char buf[3] = {'b', 'u', 'g'}; + static const char *str = "bug"; + int width = 3; + char output[130]; + + /*#define curl_msnprintf snprintf */ + + /* without a trailing zero */ + rc = curl_msnprintf(output, 4, "%.*s", width, buf); + fail_unless(rc == 3, "return code should be 3"); + fail_unless(!strcmp(output, "bug"), "wrong output"); + + /* with a trailing zero */ + rc = curl_msnprintf(output, 4, "%.*s", width, str); + fail_unless(rc == 3, "return code should be 3"); + fail_unless(!strcmp(output, "bug"), "wrong output"); + + width = 2; + /* one byte less */ + rc = curl_msnprintf(output, 4, "%.*s", width, buf); + fail_unless(rc == 2, "return code should be 2"); + fail_unless(!strcmp(output, "bu"), "wrong output"); + + /* string with larger precision */ + rc = curl_msnprintf(output, 8, "%.8s", str); + fail_unless(rc == 3, "return code should be 3"); + fail_unless(!strcmp(output, "bug"), "wrong output"); + + /* longer string with precision */ + rc = curl_msnprintf(output, 8, "%.3s", "0123456789"); + fail_unless(rc == 3, "return code should be 3"); + fail_unless(!strcmp(output, "012"), "wrong output"); + + /* negative width */ + rc = curl_msnprintf(output, 8, "%-8s", str); + fail_unless(rc == 7, "return code should be 7"); + fail_unless(!strcmp(output, "bug "), "wrong output"); + + /* larger width that string length */ + rc = curl_msnprintf(output, 8, "%8s", str); + fail_unless(rc == 7, "return code should be 7"); + fail_unless(!strcmp(output, " bu"), "wrong output"); + + /* output a number in a limited output */ + rc = curl_msnprintf(output, 4, "%d", 10240); + fail_unless(rc == 3, "return code should be 3"); + fail_unless(!strcmp(output, "102"), "wrong output"); + + /* padded strings */ + rc = curl_msnprintf(output, 16, "%8s%8s", str, str); + fail_unless(rc == 15, "return code should be 15"); + fail_unless(!strcmp(output, " bug bu"), "wrong output"); + + /* padded numbers */ + rc = curl_msnprintf(output, 16, "%8d%8d", 1234, 5678); + fail_unless(rc == 15, "return code should be 15"); + fail_unless(!strcmp(output, " 1234 567"), "wrong output"); + + /* double precision */ + rc = curl_msnprintf(output, 24, "%2$.*1$.99d", 3, 5678); + fail_unless(rc == 0, "return code should be 0"); + + /* 129 input % flags */ + rc = curl_msnprintf(output, 130, + "%s%s%s%s%s%s%s%s%s%s" /* 10 */ + "%s%s%s%s%s%s%s%s%s%s" /* 20 */ + "%s%s%s%s%s%s%s%s%s%s" /* 30 */ + "%s%s%s%s%s%s%s%s%s%s" /* 40 */ + "%s%s%s%s%s%s%s%s%s%s" /* 50 */ + "%s%s%s%s%s%s%s%s%s%s" /* 60 */ + "%s%s%s%s%s%s%s%s%s%s" /* 70 */ + "%s%s%s%s%s%s%s%s%s%s" /* 80 */ + "%s%s%s%s%s%s%s%s%s%s" /* 90 */ + "%s%s%s%s%s%s%s%s%s%s" /* 100 */ + "%s%s%s%s%s%s%s%s%s%s" /* 110 */ + "%s%s%s%s%s%s%s%s%s%s" /* 120 */ + "%s%s%s%s%s%s%s%s%s", /* 129 */ + + "a", "", "", "", "", "", "", "", "", "", /* 10 */ + "b", "", "", "", "", "", "", "", "", "", /* 20 */ + "c", "", "", "", "", "", "", "", "", "", /* 30 */ + "d", "", "", "", "", "", "", "", "", "", /* 40 */ + "e", "", "", "", "", "", "", "", "", "", /* 50 */ + "f", "", "", "", "", "", "", "", "", "", /* 60 */ + "g", "", "", "", "", "", "", "", "", "", /* 70 */ + "h", "", "", "", "", "", "", "", "", "", /* 80 */ + "i", "", "", "", "", "", "", "", "", "", /* 90 */ + "j", "", "", "", "", "", "", "", "", "", /* 100 */ + "k", "", "", "", "", "", "", "", "", "", /* 110 */ + "l", "", "", "", "", "", "", "", "", "", /* 120 */ + "m", "", "", "", "", "", "", "", "" /* 129 */ + ); + fail_unless(rc == 0, "return code should be 0"); + + /* 128 input % flags */ + rc = curl_msnprintf(output, 130, + "%s%s%s%s%s%s%s%s%s%s" /* 10 */ + "%s%s%s%s%s%s%s%s%s%s" /* 20 */ + "%s%s%s%s%s%s%s%s%s%s" /* 30 */ + "%s%s%s%s%s%s%s%s%s%s" /* 40 */ + "%s%s%s%s%s%s%s%s%s%s" /* 50 */ + "%s%s%s%s%s%s%s%s%s%s" /* 60 */ + "%s%s%s%s%s%s%s%s%s%s" /* 70 */ + "%s%s%s%s%s%s%s%s%s%s" /* 80 */ + "%s%s%s%s%s%s%s%s%s%s" /* 90 */ + "%s%s%s%s%s%s%s%s%s%s" /* 100 */ + "%s%s%s%s%s%s%s%s%s%s" /* 110 */ + "%s%s%s%s%s%s%s%s%s%s" /* 120 */ + "%s%s%s%s%s%s%s%s", /* 128 */ + + "a", "", "", "", "", "", "", "", "", "", /* 10 */ + "b", "", "", "", "", "", "", "", "", "", /* 20 */ + "c", "", "", "", "", "", "", "", "", "", /* 30 */ + "d", "", "", "", "", "", "", "", "", "", /* 40 */ + "e", "", "", "", "", "", "", "", "", "", /* 50 */ + "f", "", "", "", "", "", "", "", "", "", /* 60 */ + "g", "", "", "", "", "", "", "", "", "", /* 70 */ + "h", "", "", "", "", "", "", "", "", "", /* 80 */ + "i", "", "", "", "", "", "", "", "", "", /* 90 */ + "j", "", "", "", "", "", "", "", "", "", /* 100 */ + "k", "", "", "", "", "", "", "", "", "", /* 110 */ + "l", "", "", "", "", "", "", "", "", "", /* 120 */ + "m", "", "", "", "", "", "", "" /* 128 */ + ); + fail_unless(rc == 13, "return code should be 13"); + + /* 129 output segments */ + rc = curl_msnprintf(output, 130, + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 20 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 40 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 60 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 80 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 100 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 120 */ + "%%%%%%%%%%%%%%%%%%" /* 129 */ + ); + fail_unless(rc == 0, "return code should be 0"); + + /* 128 output segments */ + rc = curl_msnprintf(output, 129, + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 20 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 40 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 60 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 80 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 100 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 120 */ + "%%%%%%%%%%%%%%%%" /* 128 */ + ); + fail_unless(rc == 128, "return code should be 128"); + + UNITTEST_END_SIMPLE +} #if defined(CURL_GNUC_DIAG) || defined(__clang__) #pragma GCC diagnostic pop diff --git a/vendor/curl/tests/unit/unit1399.c b/vendor/curl/tests/unit/unit1399.c index 5fb2659235a..ca632eb2d69 100644 --- a/vendor/curl/tests/unit/unit1399.c +++ b/vendor/curl/tests/unit/unit1399.c @@ -21,23 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "urldata.h" #include "progress.h" -static int usec_magnitude = 1000000; - -static bool unit_setup(void) -{ - return CURLE_OK; -} - -static void unit_stop(void) -{ - -} - /* * Invoke Curl_pgrsTime for TIMER_STARTSINGLE to trigger the behavior that * manages is_t_startransfer_set, but fake the t_startsingle time for purposes @@ -54,6 +42,8 @@ static void fake_t_startsingle_time(struct Curl_easy *data, static bool usec_matches_seconds(timediff_t time_usec, int expected_seconds) { + static int usec_magnitude = 1000000; + int time_sec = (int)(time_usec / usec_magnitude); bool same = (time_sec == expected_seconds); curl_mfprintf(stderr, "is %d us same as %d seconds? %s\n", @@ -81,7 +71,10 @@ static void expect_timer_seconds(struct Curl_easy *data, int seconds) * E.g., if t_starttransfer took 2 seconds initially and took another 1 * second for the redirect request, then the resulting t_starttransfer should * be 3 seconds. */ -UNITTEST_START +static CURLcode test_unit1399(const char *arg) +{ + UNITTEST_BEGIN_SIMPLE + struct Curl_easy data; struct curltime now = curlx_now(); @@ -117,4 +110,6 @@ UNITTEST_START Curl_pgrsTime(&data, TIMER_STARTTRANSFER); expect_timer_seconds(&data, 3); -UNITTEST_STOP + + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/unit1600.c b/vendor/curl/tests/unit/unit1600.c index ee36c5e65ce..a3472032557 100644 --- a/vendor/curl/tests/unit/unit1600.c +++ b/vendor/curl/tests/unit/unit1600.c @@ -21,33 +21,35 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "urldata.h" #include "curl_ntlm_core.h" -static CURL *easy; - -static CURLcode unit_setup(void) +static CURLcode t1600_setup(CURL **easy) { CURLcode res = CURLE_OK; global_init(CURL_GLOBAL_ALL); - easy = curl_easy_init(); - if(!easy) { + *easy = curl_easy_init(); + if(!*easy) { curl_global_cleanup(); return CURLE_OUT_OF_MEMORY; } return res; } -static void unit_stop(void) +static void t1600_stop(CURL *easy) { curl_easy_cleanup(easy); curl_global_cleanup(); } -UNITTEST_START +static CURLcode test_unit1600(const char *arg) +{ + CURL *easy; + + UNITTEST_BEGIN(t1600_setup(&easy)) #if defined(USE_NTLM) && (!defined(USE_WINDOWS_SSPI) || \ defined(USE_WIN32_CRYPTO)) @@ -65,11 +67,12 @@ UNITTEST_START "\x39\xaf\x87\xa6\x75\x0a\x7a\x00\xba\xa0" "\xd3\x4f\x04\x9e\xc1\xd0\x00\x00\x00\x00\x00", 21); -/* !checksrc! disable LONGLINE 2 */ + /* !checksrc! disable LONGLINE 2 */ Curl_ntlm_core_mk_nt_hash("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", output); verify_memory(testp, "\x36\x9d\xae\x06\x84\x7e\xe1\xc1\x4a\x94\x39\xea\x6f\x44\x8c\x65\x00\x00\x00\x00\x00", 21); #endif -UNITTEST_STOP + UNITTEST_END(t1600_stop(easy)) +} diff --git a/vendor/curl/tests/unit/unit1601.c b/vendor/curl/tests/unit/unit1601.c index 4623bb7769b..d31866bb741 100644 --- a/vendor/curl/tests/unit/unit1601.c +++ b/vendor/curl/tests/unit/unit1601.c @@ -21,27 +21,19 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "curl_md5.h" -static CURLcode unit_setup(void) +static CURLcode test_unit1601(const char *arg) { - return CURLE_OK; -} - -static void unit_stop(void) -{ - -} - -UNITTEST_START + UNITTEST_BEGIN_SIMPLE -#if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) \ - || !defined(CURL_DISABLE_DIGEST_AUTH) +#if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) || \ + !defined(CURL_DISABLE_DIGEST_AUTH) - const char string1[] = "1"; - const char string2[] = "hello-you-fool"; + static const char string1[] = "1"; + static const char string2[] = "hello-you-fool"; unsigned char output[MD5_DIGEST_LEN]; unsigned char *testp = output; @@ -56,5 +48,5 @@ UNITTEST_START "\x87\x5f\x22", MD5_DIGEST_LEN); #endif - -UNITTEST_STOP + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/unit1602.c b/vendor/curl/tests/unit/unit1602.c index cc0c19384ff..e397bdb5ca5 100644 --- a/vendor/curl/tests/unit/unit1602.c +++ b/vendor/curl/tests/unit/unit1602.c @@ -21,35 +21,36 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" - -#include +#include "unitcheck.h" #include "hash.h" -#include /* LAST include file */ - -static struct Curl_hash hash_static; +#include "memdebug.h" /* LAST include file */ -static void mydtor(void *p) +static void t1602_mydtor(void *p) { int *ptr = (int *)p; free(ptr); } -static CURLcode unit_setup(void) +static CURLcode t1602_setup(struct Curl_hash *hash) { - Curl_hash_init(&hash_static, 7, Curl_hash_str, - curlx_str_key_compare, mydtor); + Curl_hash_init(hash, 7, Curl_hash_str, + curlx_str_key_compare, t1602_mydtor); return CURLE_OK; } -static void unit_stop(void) +static void t1602_stop(struct Curl_hash *hash) { - Curl_hash_destroy(&hash_static); + Curl_hash_destroy(hash); } -UNITTEST_START +static CURLcode test_unit1602(const char *arg) +{ + struct Curl_hash hash; + + UNITTEST_BEGIN(t1602_setup(&hash)) + int *value; int *value2; int *nodep; @@ -58,23 +59,23 @@ UNITTEST_START int key = 20; int key2 = 25; - value = malloc(sizeof(int)); abort_unless(value != NULL, "Out of memory"); *value = 199; - nodep = Curl_hash_add(&hash_static, &key, klen, value); + nodep = Curl_hash_add(&hash, &key, klen, value); if(!nodep) free(value); abort_unless(nodep, "insertion into hash failed"); - Curl_hash_clean(&hash_static); + Curl_hash_clean(&hash); /* Attempt to add another key/value pair */ value2 = malloc(sizeof(int)); abort_unless(value2 != NULL, "Out of memory"); *value2 = 204; - nodep = Curl_hash_add(&hash_static, &key2, klen, value2); + nodep = Curl_hash_add(&hash, &key2, klen, value2); if(!nodep) free(value2); abort_unless(nodep, "insertion into hash failed"); -UNITTEST_STOP + UNITTEST_END(t1602_stop(&hash)) +} diff --git a/vendor/curl/tests/unit/unit1603.c b/vendor/curl/tests/unit/unit1603.c index 78f7fd8fcf0..f6e39dc6888 100644 --- a/vendor/curl/tests/unit/unit1603.c +++ b/vendor/curl/tests/unit/unit1603.c @@ -21,16 +21,15 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" -#include #include "hash.h" -#include /* LAST include file */ -static struct Curl_hash hash_static; +#include "memdebug.h" /* LAST include file */ + static const size_t slots = 3; -static void mydtor(void *p) +static void t1603_mydtor(void *p) { /* Data are statically allocated */ (void)p; /* unused */ @@ -46,19 +45,24 @@ static void my_elem_dtor(void *key, size_t key_len, void *p) ++elem_dtor_calls; } -static CURLcode unit_setup(void) +static CURLcode t1603_setup(struct Curl_hash *hash_static) { - Curl_hash_init(&hash_static, slots, Curl_hash_str, - curlx_str_key_compare, mydtor); + Curl_hash_init(hash_static, slots, Curl_hash_str, + curlx_str_key_compare, t1603_mydtor); return CURLE_OK; } -static void unit_stop(void) +static void t1603_stop(struct Curl_hash *hash_static) { - Curl_hash_destroy(&hash_static); + Curl_hash_destroy(hash_static); } -UNITTEST_START +static CURLcode test_unit1603(const char *arg) +{ + struct Curl_hash hash_static; + + UNITTEST_BEGIN(t1603_setup(&hash_static)) + char key1[] = "key1"; char key2[] = "key2b"; char key3[] = "key3"; @@ -170,8 +174,8 @@ UNITTEST_START fail_unless(rc == 0, "hash delete failed"); fail_unless(elem_dtor_calls == 2, "element destructor count should be 1"); - /* Clean up */ Curl_hash_clean(&hash_static); -UNITTEST_STOP + UNITTEST_END(t1603_stop(&hash_static)) +} diff --git a/vendor/curl/tests/unit/unit1605.c b/vendor/curl/tests/unit/unit1605.c index d0006d2b5f0..a092ff16397 100644 --- a/vendor/curl/tests/unit/unit1605.c +++ b/vendor/curl/tests/unit/unit1605.c @@ -21,32 +21,35 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "llist.h" -static CURL *easy; - -static CURLcode unit_setup(void) +static CURLcode t1605_setup(CURL **easy) { CURLcode res = CURLE_OK; global_init(CURL_GLOBAL_ALL); - easy = curl_easy_init(); - if(!easy) { + *easy = curl_easy_init(); + if(!*easy) { curl_global_cleanup(); return CURLE_OUT_OF_MEMORY; } return res; } -static void unit_stop(void) +static void t1605_stop(CURL *easy) { curl_easy_cleanup(easy); curl_global_cleanup(); } -UNITTEST_START +static CURLcode test_unit1605(const char *arg) +{ + CURL *easy; + + UNITTEST_BEGIN(t1605_setup(&easy)) + int len; char *esc; @@ -56,4 +59,5 @@ UNITTEST_START esc = curl_easy_unescape(easy, "%41%41%41%41", -1, &len); fail_unless(esc == NULL, "negative string length can't work"); -UNITTEST_STOP + UNITTEST_END(t1605_stop(easy)) +} diff --git a/vendor/curl/tests/unit/unit1606.c b/vendor/curl/tests/unit/unit1606.c index b7f557d6898..e39ecaecdc0 100644 --- a/vendor/curl/tests/unit/unit1606.c +++ b/vendor/curl/tests/unit/unit1606.c @@ -21,33 +21,32 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "speedcheck.h" #include "urldata.h" -static struct Curl_easy *easy; - -static CURLcode unit_setup(void) +static CURLcode t1606_setup(struct Curl_easy **easy) { CURLcode res = CURLE_OK; global_init(CURL_GLOBAL_ALL); - easy = curl_easy_init(); - if(!easy) { + *easy = curl_easy_init(); + if(!*easy) { curl_global_cleanup(); return CURLE_OUT_OF_MEMORY; } return res; } -static void unit_stop(void) +static void t1606_stop(struct Curl_easy *easy) { curl_easy_cleanup(easy); curl_global_cleanup(); } -static int runawhile(long time_limit, +static int runawhile(struct Curl_easy *easy, + long time_limit, long speed_limit, curl_off_t speed, int dec) @@ -77,17 +76,24 @@ static int runawhile(long time_limit, return finaltime; } -UNITTEST_START - fail_unless(runawhile(41, 41, 40, 0) == 41, +static CURLcode test_unit1606(const char *arg) +{ + struct Curl_easy *easy; + + UNITTEST_BEGIN(t1606_setup(&easy)) + + fail_unless(runawhile(easy, 41, 41, 40, 0) == 41, "wrong low speed timeout"); - fail_unless(runawhile(21, 21, 20, 0) == 21, + fail_unless(runawhile(easy, 21, 21, 20, 0) == 21, "wrong low speed timeout"); - fail_unless(runawhile(60, 60, 40, 0) == 60, + fail_unless(runawhile(easy, 60, 60, 40, 0) == 60, "wrong log speed timeout"); - fail_unless(runawhile(50, 50, 40, 0) == 50, + fail_unless(runawhile(easy, 50, 50, 40, 0) == 50, "wrong log speed timeout"); - fail_unless(runawhile(40, 40, 40, 0) == 99, + fail_unless(runawhile(easy, 40, 40, 40, 0) == 99, "should not time out"); - fail_unless(runawhile(10, 50, 100, 2) == 36, + fail_unless(runawhile(easy, 10, 50, 100, 2) == 36, "bad timeout"); -UNITTEST_STOP + + UNITTEST_END(t1606_stop(easy)) +} diff --git a/vendor/curl/tests/unit/unit1607.c b/vendor/curl/tests/unit/unit1607.c index 62dde130af0..ad0df33be8d 100644 --- a/vendor/curl/tests/unit/unit1607.c +++ b/vendor/curl/tests/unit/unit1607.c @@ -21,7 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "urldata.h" #include "connect.h" @@ -29,85 +29,79 @@ #include "memdebug.h" /* LAST include file */ -static void unit_stop(void) -{ - curl_global_cleanup(); -} - -static CURLcode unit_setup(void) +static CURLcode t1607_setup(void) { CURLcode res = CURLE_OK; - global_init(CURL_GLOBAL_ALL); - return res; } -struct testcase { - /* host:port:address[,address]... */ - const char *optval; - - /* lowercase host and port to retrieve the addresses from hostcache */ - const char *host; - int port; - - /* whether we expect a permanent or non-permanent cache entry */ - bool permanent; - - /* 0 to 9 addresses expected from hostcache */ - const char *address[10]; -}; - - -/* In builds without IPv6 support CURLOPT_RESOLVE should skip over those - addresses, so we have to do that as well. */ -static const char skip = 0; +static CURLcode test_unit1607(const char *arg) +{ + /* In builds without IPv6 support CURLOPT_RESOLVE should skip over those + addresses, so we have to do that as well. */ + static const char skip = 0; #ifdef USE_IPV6 #define IPV6ONLY(x) x #else #define IPV6ONLY(x) &skip #endif -/* CURLOPT_RESOLVE address parsing tests */ -static const struct testcase tests[] = { - /* spaces aren't allowed, for now */ - { "test.com:80:127.0.0.1, 127.0.0.2", - "test.com", 80, TRUE, { NULL, } - }, - { "TEST.com:80:,,127.0.0.1,,,127.0.0.2,,,,::1,,,", - "test.com", 80, TRUE, { "127.0.0.1", "127.0.0.2", IPV6ONLY("::1"), } - }, - { "test.com:80:::1,127.0.0.1", - "test.com", 80, TRUE, { IPV6ONLY("::1"), "127.0.0.1", } - }, - { "test.com:80:[::1],127.0.0.1", - "test.com", 80, TRUE, { IPV6ONLY("::1"), "127.0.0.1", } - }, - { "test.com:80:::1", - "test.com", 80, TRUE, { IPV6ONLY("::1"), } - }, - { "test.com:80:[::1]", - "test.com", 80, TRUE, { IPV6ONLY("::1"), } - }, - { "test.com:80:127.0.0.1", - "test.com", 80, TRUE, { "127.0.0.1", } - }, - { "test.com:80:,127.0.0.1", - "test.com", 80, TRUE, { "127.0.0.1", } - }, - { "test.com:80:127.0.0.1,", - "test.com", 80, TRUE, { "127.0.0.1", } - }, - { "test.com:0:127.0.0.1", - "test.com", 0, TRUE, { "127.0.0.1", } - }, - { "+test.com:80:127.0.0.1,", - "test.com", 80, FALSE, { "127.0.0.1", } - }, -}; - -UNITTEST_START -{ + UNITTEST_BEGIN(t1607_setup()) + + struct testcase { + /* host:port:address[,address]... */ + const char *optval; + + /* lowercase host and port to retrieve the addresses from hostcache */ + const char *host; + int port; + + /* whether we expect a permanent or non-permanent cache entry */ + bool permanent; + + /* 0 to 9 addresses expected from hostcache */ + const char *address[10]; + }; + + /* CURLOPT_RESOLVE address parsing tests */ + static const struct testcase tests[] = { + /* spaces aren't allowed, for now */ + { "test.com:80:127.0.0.1, 127.0.0.2", + "test.com", 80, TRUE, { NULL, } + }, + { "TEST.com:80:,,127.0.0.1,,,127.0.0.2,,,,::1,,,", + "test.com", 80, TRUE, { "127.0.0.1", "127.0.0.2", IPV6ONLY("::1"), } + }, + { "test.com:80:::1,127.0.0.1", + "test.com", 80, TRUE, { IPV6ONLY("::1"), "127.0.0.1", } + }, + { "test.com:80:[::1],127.0.0.1", + "test.com", 80, TRUE, { IPV6ONLY("::1"), "127.0.0.1", } + }, + { "test.com:80:::1", + "test.com", 80, TRUE, { IPV6ONLY("::1"), } + }, + { "test.com:80:[::1]", + "test.com", 80, TRUE, { IPV6ONLY("::1"), } + }, + { "test.com:80:127.0.0.1", + "test.com", 80, TRUE, { "127.0.0.1", } + }, + { "test.com:80:,127.0.0.1", + "test.com", 80, TRUE, { "127.0.0.1", } + }, + { "test.com:80:127.0.0.1,", + "test.com", 80, TRUE, { "127.0.0.1", } + }, + { "test.com:0:127.0.0.1", + "test.com", 0, TRUE, { "127.0.0.1", } + }, + { "+test.com:80:127.0.0.1,", + "test.com", 80, FALSE, { "127.0.0.1", } + }, + }; + int i; struct Curl_multi *multi = NULL; struct Curl_easy *easy = NULL; @@ -199,7 +193,7 @@ UNITTEST_START break; } - if(dns->timestamp && tests[i].permanent) { + if(dns->timestamp.tv_sec && tests[i].permanent) { curl_mfprintf(stderr, "%s:%d tests[%d] failed. the timestamp is not zero " "but tests[%d].permanent is TRUE\n", @@ -208,7 +202,7 @@ UNITTEST_START break; } - if(dns->timestamp == 0 && !tests[i].permanent) { + if(dns->timestamp.tv_sec == 0 && !tests[i].permanent) { curl_mfprintf(stderr, "%s:%d tests[%d] failed. the timestamp is zero " "but tests[%d].permanent is FALSE\n", __FILE__, __LINE__, i, i); @@ -235,5 +229,6 @@ UNITTEST_START curl_easy_cleanup(easy); curl_multi_cleanup(multi); curl_slist_free_all(list); + + UNITTEST_END(curl_global_cleanup()) } -UNITTEST_STOP diff --git a/vendor/curl/tests/unit/unit1608.c b/vendor/curl/tests/unit/unit1608.c index f734b77885c..7b5467632c5 100644 --- a/vendor/curl/tests/unit/unit1608.c +++ b/vendor/curl/tests/unit/unit1608.c @@ -21,7 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "hostip.h" @@ -30,25 +30,21 @@ CURLcode Curl_shuffle_addr(struct Curl_easy *data, struct Curl_addrinfo **addr); -#define NUM_ADDRS 8 -static struct Curl_addrinfo addrs[NUM_ADDRS]; +static struct Curl_addrinfo addrs[8]; -static CURLcode unit_setup(void) +static CURLcode t1608_setup(void) { - int i; - for(i = 0; i < NUM_ADDRS - 1; i++) { + size_t i; + for(i = 0; i < CURL_ARRAYSIZE(addrs) - 1; i++) { addrs[i].ai_next = &addrs[i + 1]; } return CURLE_OK; } -static void unit_stop(void) +static CURLcode test_unit1608(const char *arg) { - curl_global_cleanup(); -} - -UNITTEST_START + UNITTEST_BEGIN(t1608_setup()) int i; CURLcode code; @@ -73,17 +69,15 @@ UNITTEST_START abort_unless(addrhead != addrs, "addresses are not being reordered"); -UNITTEST_STOP + UNITTEST_END(curl_global_cleanup()) +} #else -static CURLcode unit_setup(void) -{ - return CURLE_OK; -} -static void unit_stop(void) + +static CURLcode test_unit1608(const char *arg) { + UNITTEST_BEGIN_SIMPLE + UNITTEST_END_SIMPLE } -UNITTEST_START -UNITTEST_STOP #endif diff --git a/vendor/curl/tests/unit/unit1609.c b/vendor/curl/tests/unit/unit1609.c index c0b4058e26b..4485c3f046e 100644 --- a/vendor/curl/tests/unit/unit1609.c +++ b/vendor/curl/tests/unit/unit1609.c @@ -21,7 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "urldata.h" #include "connect.h" @@ -29,33 +29,13 @@ #include "memdebug.h" /* LAST include file */ -static void unit_stop(void) -{ - curl_global_cleanup(); -} - -static CURLcode unit_setup(void) +static CURLcode t1609_setup(void) { CURLcode res = CURLE_OK; - global_init(CURL_GLOBAL_ALL); - return res; } -struct testcase { - /* host:port:address[,address]... */ - const char *optval; - - /* lowercase host and port to retrieve the addresses from hostcache */ - const char *host; - int port; - - /* 0 to 9 addresses expected from hostcache */ - const char *address[10]; -}; - - /* CURLOPT_RESOLVE address parsing test - to test the following defect fix: 1) if there is already existing host:port pair in the DNS cache and @@ -88,18 +68,32 @@ in the cache, then it does not mark it, but just leaves it as it is. expected result: cached address has zero timestamp and new address */ -static const struct testcase tests[] = { - /* spaces aren't allowed, for now */ - { "test.com:80:127.0.0.1", - "test.com", 80, { "127.0.0.1", } - }, - { "test.com:80:127.0.0.2", - "test.com", 80, { "127.0.0.2", } - }, -}; - -UNITTEST_START +static CURLcode test_unit1609(const char *arg) { + UNITTEST_BEGIN(t1609_setup()) + + struct testcase { + /* host:port:address[,address]... */ + const char *optval; + + /* lowercase host and port to retrieve the addresses from hostcache */ + const char *host; + int port; + + /* 0 to 9 addresses expected from hostcache */ + const char *address[10]; + }; + + static const struct testcase tests[] = { + /* spaces aren't allowed, for now */ + { "test.com:80:127.0.0.1", + "test.com", 80, { "127.0.0.1", } + }, + { "test.com:80:127.0.0.2", + "test.com", 80, { "127.0.0.2", } + }, + }; + int i; struct Curl_multi *multi = NULL; struct Curl_easy *easy = NULL; @@ -218,5 +212,6 @@ UNITTEST_START curl_easy_cleanup(easy); curl_multi_cleanup(multi); curl_slist_free_all(list); + + UNITTEST_END(curl_global_cleanup()) } -UNITTEST_STOP diff --git a/vendor/curl/tests/unit/unit1610.c b/vendor/curl/tests/unit/unit1610.c index b9d6117a74b..73a546a85ea 100644 --- a/vendor/curl/tests/unit/unit1610.c +++ b/vendor/curl/tests/unit/unit1610.c @@ -21,29 +21,26 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "curl_sha256.h" -static CURLcode unit_setup(void) +static CURLcode t1610_setup(void) { CURLcode res = CURLE_OK; global_init(CURL_GLOBAL_ALL); return res; } -static void unit_stop(void) +static CURLcode test_unit1610(const char *arg) { - curl_global_cleanup(); -} - -UNITTEST_START + UNITTEST_BEGIN(t1610_setup()) -#if !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) \ - || defined(USE_LIBSSH2) +#if !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) || \ + defined(USE_LIBSSH2) - const char string1[] = "1"; - const char string2[] = "hello-you-fool"; + static const char string1[] = "1"; + static const char string2[] = "hello-you-fool"; unsigned char output[CURL_SHA256_DIGEST_LENGTH]; unsigned char *testp = output; @@ -62,5 +59,5 @@ UNITTEST_START "\x15\xae", CURL_SHA256_DIGEST_LENGTH); #endif - -UNITTEST_STOP + UNITTEST_END(curl_global_cleanup()) +} diff --git a/vendor/curl/tests/unit/unit1611.c b/vendor/curl/tests/unit/unit1611.c index 0062ac6c373..5337aa33a31 100644 --- a/vendor/curl/tests/unit/unit1611.c +++ b/vendor/curl/tests/unit/unit1611.c @@ -21,25 +21,17 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "curl_md4.h" -static CURLcode unit_setup(void) +static CURLcode test_unit1611(const char *arg) { - return CURLE_OK; -} - -static void unit_stop(void) -{ - -} - -UNITTEST_START + UNITTEST_BEGIN_SIMPLE #ifdef USE_CURL_NTLM_CORE - const char string1[] = "1"; - const char string2[] = "hello-you-fool"; + static const char string1[] = "1"; + static const char string2[] = "hello-you-fool"; unsigned char output[MD4_DIGEST_LENGTH]; unsigned char *testp = output; @@ -56,5 +48,5 @@ UNITTEST_START "\x0b", MD4_DIGEST_LENGTH); #endif - -UNITTEST_STOP + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/unit1612.c b/vendor/curl/tests/unit/unit1612.c index 76483d92a39..0cc0c025466 100644 --- a/vendor/curl/tests/unit/unit1612.c +++ b/vendor/curl/tests/unit/unit1612.c @@ -21,29 +21,21 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "curl_hmac.h" #include "curl_md5.h" -static CURLcode unit_setup(void) +static CURLcode test_unit1612(const char *arg) { - return CURLE_OK; -} - -static void unit_stop(void) -{ - -} - -UNITTEST_START + UNITTEST_BEGIN_SIMPLE -#if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) \ - || !defined(CURL_DISABLE_DIGEST_AUTH) +#if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) || \ + !defined(CURL_DISABLE_DIGEST_AUTH) - const char password[] = "Pa55worD"; - const char string1[] = "1"; - const char string2[] = "hello-you-fool"; + static const char password[] = "Pa55worD"; + static const char string1[] = "1"; + static const char string2[] = "hello-you-fool"; unsigned char output[HMAC_MD5_LENGTH]; unsigned char *testp = output; @@ -66,5 +58,5 @@ UNITTEST_START "\xd0", HMAC_MD5_LENGTH); #endif - -UNITTEST_STOP + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/unit1614.c b/vendor/curl/tests/unit/unit1614.c index 5cb96cfd9f4..4ee18df72f1 100644 --- a/vendor/curl/tests/unit/unit1614.c +++ b/vendor/curl/tests/unit/unit1614.c @@ -21,38 +21,24 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "noproxy.h" -static CURLcode unit_setup(void) +static CURLcode test_unit1614(const char *arg) { - return CURLE_OK; -} - -static void unit_stop(void) -{ - -} - -struct check { - const char *a; - const char *n; - unsigned int bits; - bool match; -}; - -struct noproxy { - const char *a; - const char *n; - bool match; -}; + UNITTEST_BEGIN_SIMPLE -UNITTEST_START #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_PROXY) -{ int i; int err = 0; + + struct check { + const char *a; + const char *n; + unsigned int bits; + bool match; + }; struct check list4[]= { { "192.160.0.1", "192.160.0.1", 33, FALSE}, { "192.160.0.1", "192.160.0.1", 32, TRUE}, @@ -78,6 +64,11 @@ UNITTEST_START { NULL, NULL, 0, FALSE} /* end marker */ }; #endif + struct noproxy { + const char *a; + const char *n; + bool match; + }; struct noproxy list[]= { { "www.example.com", "localhost .example.com .example.de", FALSE}, { "www.example.com", "localhost,.example.com,.example.de", TRUE}, @@ -161,6 +152,7 @@ UNITTEST_START } } fail_if(err, "errors"); -} #endif -UNITTEST_STOP + + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/unit1615.c b/vendor/curl/tests/unit/unit1615.c index b0b32b61fcb..44dc1ae0454 100644 --- a/vendor/curl/tests/unit/unit1615.c +++ b/vendor/curl/tests/unit/unit1615.c @@ -22,21 +22,13 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "curl_sha512_256.h" -static CURLcode unit_setup(void) +static CURLcode test_unit1615(const char *arg) { - return CURLE_OK; -} - -static void unit_stop(void) -{ - -} - -UNITTEST_START + UNITTEST_BEGIN_SIMPLE #ifdef CURL_HAVE_SHA512_256 @@ -155,5 +147,5 @@ UNITTEST_START #endif /* CURL_HAVE_SHA512_256 */ - -UNITTEST_STOP + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/unit1616.c b/vendor/curl/tests/unit/unit1616.c index 20067c67e97..7641cbeace9 100644 --- a/vendor/curl/tests/unit/unit1616.c +++ b/vendor/curl/tests/unit/unit1616.c @@ -21,33 +21,36 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" -#include -#include -#include /* LAST include file */ +#include "uint-hash.h" -static struct uint_hash hash_static; +#include "memdebug.h" /* LAST include file */ -static void mydtor(unsigned int id, void *elem) +static void t1616_mydtor(unsigned int id, void *elem) { int *ptr = (int *)elem; (void)id; free(ptr); } -static CURLcode unit_setup(void) +static CURLcode t1616_setup(struct uint_hash *hash) { - Curl_uint_hash_init(&hash_static, 15, mydtor); + Curl_uint_hash_init(hash, 15, t1616_mydtor); return CURLE_OK; } -static void unit_stop(void) +static void t1616_stop(struct uint_hash *hash) { - Curl_uint_hash_destroy(&hash_static); + Curl_uint_hash_destroy(hash); } -UNITTEST_START +static CURLcode test_unit1616(const char *arg) +{ + struct uint_hash hash; + + UNITTEST_BEGIN(t1616_setup(&hash)) + int *value, *v; int *value2; bool ok; @@ -55,31 +58,31 @@ UNITTEST_START unsigned int key = 20; unsigned int key2 = 25; - value = malloc(sizeof(int)); abort_unless(value != NULL, "Out of memory"); *value = 199; - ok = Curl_uint_hash_set(&hash_static, key, value); + ok = Curl_uint_hash_set(&hash, key, value); if(!ok) free(value); abort_unless(ok, "insertion into hash failed"); - v = Curl_uint_hash_get(&hash_static, key); + v = Curl_uint_hash_get(&hash, key); abort_unless(v == value, "lookup present entry failed"); - v = Curl_uint_hash_get(&hash_static, key2); + v = Curl_uint_hash_get(&hash, key2); abort_unless(!v, "lookup missing entry failed"); - Curl_uint_hash_clear(&hash_static); + Curl_uint_hash_clear(&hash); /* Attempt to add another key/value pair */ value2 = malloc(sizeof(int)); abort_unless(value2 != NULL, "Out of memory"); *value2 = 204; - ok = Curl_uint_hash_set(&hash_static, key2, value2); + ok = Curl_uint_hash_set(&hash, key2, value2); if(!ok) free(value2); abort_unless(ok, "insertion into hash failed"); - v = Curl_uint_hash_get(&hash_static, key2); + v = Curl_uint_hash_get(&hash, key2); abort_unless(v == value2, "lookup present entry failed"); - v = Curl_uint_hash_get(&hash_static, key); + v = Curl_uint_hash_get(&hash, key); abort_unless(!v, "lookup missing entry failed"); -UNITTEST_STOP + UNITTEST_END(t1616_stop(&hash)) +} diff --git a/vendor/curl/tests/unit/unit1620.c b/vendor/curl/tests/unit/unit1620.c index 29c8539c9d6..14b377b640e 100644 --- a/vendor/curl/tests/unit/unit1620.c +++ b/vendor/curl/tests/unit/unit1620.c @@ -21,26 +21,21 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "urldata.h" #include "url.h" #include "memdebug.h" /* LAST include file */ -static CURLcode unit_setup(void) +static CURLcode t1620_setup(void) { CURLcode res = CURLE_OK; global_init(CURL_GLOBAL_ALL); return res; } -static void unit_stop(void) -{ - curl_global_cleanup(); -} - -static void test_parse( +static void t1620_parse( const char *input, const char *exp_username, const char *exp_password, @@ -74,8 +69,10 @@ static void test_parse( free(options); } -UNITTEST_START +static CURLcode test_unit1620(const char *arg) { + UNITTEST_BEGIN(t1620_setup()) + CURLcode rc; struct Curl_easy *empty; enum dupstring i; @@ -106,20 +103,21 @@ UNITTEST_START rc = Curl_init_do(empty, empty->conn); fail_unless(rc == CURLE_OK, "Curl_init_do() failed"); - test_parse("hostname", "hostname", NULL, NULL); - test_parse("user:password", "user", "password", NULL); - test_parse("user:password;options", "user", "password", "options"); - test_parse("user:password;options;more", "user", "password", "options;more"); - test_parse("", "", NULL, NULL); - test_parse(":", "", "", NULL); - test_parse(":;", "", "", NULL); - test_parse(":password", "", "password", NULL); - test_parse(":password;", "", "password", NULL); - test_parse(";options", "", NULL, "options"); - test_parse("user;options", "user", NULL, "options"); - test_parse("user:;options", "user", "", "options"); - test_parse("user;options:password", "user", "password", "options"); - test_parse("user;options:", "user", "", "options"); + t1620_parse("hostname", "hostname", NULL, NULL); + t1620_parse("user:password", "user", "password", NULL); + t1620_parse("user:password;options", "user", "password", "options"); + t1620_parse("user:password;options;more", "user", "password", + "options;more"); + t1620_parse("", "", NULL, NULL); + t1620_parse(":", "", "", NULL); + t1620_parse(":;", "", "", NULL); + t1620_parse(":password", "", "password", NULL); + t1620_parse(":password;", "", "password", NULL); + t1620_parse(";options", "", NULL, "options"); + t1620_parse("user;options", "user", NULL, "options"); + t1620_parse("user:;options", "user", "", "options"); + t1620_parse("user;options:password", "user", "password", "options"); + t1620_parse("user;options:", "user", "", "options"); Curl_freeset(empty); for(i = (enum dupstring)0; i < STRING_LAST; i++) { @@ -130,5 +128,5 @@ UNITTEST_START rc = Curl_close(&empty); fail_unless(rc == CURLE_OK, "Curl_close() failed"); + UNITTEST_END(curl_global_cleanup()) } -UNITTEST_STOP diff --git a/vendor/curl/tests/unit/unit1650.c b/vendor/curl/tests/unit/unit1650.c index 53b44c00bc5..89e72262d38 100644 --- a/vendor/curl/tests/unit/unit1650.c +++ b/vendor/curl/tests/unit/unit1650.c @@ -21,22 +21,16 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "doh.h" -#include "dynbuf.h" -static CURLcode unit_setup(void) +static CURLcode test_unit1650(const char *arg) { - return CURLE_OK; -} - -static void unit_stop(void) -{ - -} + UNITTEST_BEGIN_SIMPLE #ifndef CURL_DISABLE_DOH + #define DNS_PREAMBLE "\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00" #define LABEL_TEST "\x04\x74\x65\x73\x74" #define LABEL_HOST "\x04\x68\x6f\x73\x74" @@ -49,36 +43,35 @@ static void unit_stop(void) #define DNS_Q1 DNS_PREAMBLE LABEL_TEST LABEL_HOST LABEL_NAME DNSA_EPILOGUE #define DNS_Q2 DNS_PREAMBLE LABEL_TEST LABEL_HOST LABEL_NAME DNSAAAA_EPILOGUE -struct dohrequest { - /* input */ - const char *name; - DNStype type; - - /* output */ - const char *packet; - size_t size; - DOHcode rc; -}; - - -static const struct dohrequest req[] = { - {"test.host.name", DNS_TYPE_A, DNS_Q1, sizeof(DNS_Q1)-1, DOH_OK }, - {"test.host.name", DNS_TYPE_AAAA, DNS_Q2, sizeof(DNS_Q2)-1, DOH_OK }, - {"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" - ".host.name", - DNS_TYPE_AAAA, NULL, 0, DOH_DNS_BAD_LABEL } -}; - -struct dohresp { - /* input */ - const char *packet; - size_t size; - DNStype type; + struct dohrequest { + /* input */ + const char *name; + DNStype type; - /* output */ - DOHcode rc; - const char *out; -}; + /* output */ + const char *packet; + size_t size; + DOHcode rc; + }; + + static const struct dohrequest req[] = { + {"test.host.name", CURL_DNS_TYPE_A, DNS_Q1, sizeof(DNS_Q1)-1, DOH_OK }, + {"test.host.name", CURL_DNS_TYPE_AAAA, DNS_Q2, sizeof(DNS_Q2)-1, DOH_OK }, + {"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" + ".host.name", + CURL_DNS_TYPE_AAAA, NULL, 0, DOH_DNS_BAD_LABEL } + }; + + struct dohresp { + /* input */ + const char *packet; + size_t size; + DNStype type; + + /* output */ + DOHcode rc; + const char *out; + }; #define DNS_FOO_EXAMPLE_COM \ "\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x03\x66\x6f\x6f" \ @@ -86,46 +79,46 @@ struct dohresp { "\x01\xc0\x0c\x00\x01\x00\x01\x00\x00\x00\x37\x00\x04\x7f\x00\x00" \ "\x01" -static const char full49[] = DNS_FOO_EXAMPLE_COM; + static const char full49[] = DNS_FOO_EXAMPLE_COM; -static const struct dohresp resp[] = { - {"\x00\x00", 2, DNS_TYPE_A, DOH_TOO_SMALL_BUFFER, NULL }, + static const struct dohresp resp[] = { + {"\x00\x00", 2, CURL_DNS_TYPE_A, DOH_TOO_SMALL_BUFFER, NULL }, {"\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01", 12, - DNS_TYPE_A, DOH_DNS_BAD_ID, NULL }, + CURL_DNS_TYPE_A, DOH_DNS_BAD_ID, NULL }, {"\x00\x00\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01", 12, - DNS_TYPE_A, DOH_DNS_BAD_RCODE, NULL }, + CURL_DNS_TYPE_A, DOH_DNS_BAD_RCODE, NULL }, {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x03\x66\x6f\x6f", 16, - DNS_TYPE_A, DOH_DNS_OUT_OF_RANGE, NULL }, + CURL_DNS_TYPE_A, DOH_DNS_OUT_OF_RANGE, NULL }, {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x03\x66\x6f\x6f\x00", 17, - DNS_TYPE_A, DOH_DNS_OUT_OF_RANGE, NULL }, + CURL_DNS_TYPE_A, DOH_DNS_OUT_OF_RANGE, NULL }, {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x03\x66\x6f\x6f\x00" "\x00\x01\x00\x01", 21, - DNS_TYPE_A, DOH_DNS_OUT_OF_RANGE, NULL }, + CURL_DNS_TYPE_A, DOH_DNS_OUT_OF_RANGE, NULL }, {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x03\x66\x6f\x6f\x00" "\x00\x01\x00\x01" "\x04", 18, - DNS_TYPE_A, DOH_DNS_OUT_OF_RANGE, NULL }, + CURL_DNS_TYPE_A, DOH_DNS_OUT_OF_RANGE, NULL }, {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x04\x63\x75\x72" "\x6c\x04\x63\x75\x72\x6c\x00\x00\x05\x00\x01\xc0\x0c\x00\x05\x00" "\x01\x00\x00\x00\x37\x00\x11\x08\x61\x6e\x79\x77\x68\x65\x72\x65" "\x06\x72\x65\x61\x6c\x6c\x79\x00", 56, - DNS_TYPE_A, DOH_OK, "anywhere.really "}, + CURL_DNS_TYPE_A, DOH_OK, "anywhere.really "}, - {DNS_FOO_EXAMPLE_COM, 49, DNS_TYPE_A, DOH_OK, "127.0.0.1 "}, + {DNS_FOO_EXAMPLE_COM, 49, CURL_DNS_TYPE_A, DOH_OK, "127.0.0.1 "}, {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x04\x61\x61\x61" "\x61\x07\x65\x78\x61\x6d\x70\x6c\x65\x03\x63\x6f\x6d\x00\x00\x1c" "\x00\x01\xc0\x0c\x00\x1c\x00\x01\x00\x00\x00\x37\x00\x10\x20\x20" "\x20\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x20", 62, - DNS_TYPE_AAAA, DOH_OK, + CURL_DNS_TYPE_AAAA, DOH_OK, "2020:2020:0000:0000:0000:0000:0000:2020 " }, {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x04\x63\x75\x72" "\x6c\x04\x63\x75\x72\x6c\x00\x00\x05\x00\x01\xc0\x0c\x00\x05\x00" "\x01\x00\x00\x00\x37\x00" "\x07\x03\x61\x6e\x79\xc0\x27\x00", 46, - DNS_TYPE_A, DOH_DNS_LABEL_LOOP, NULL}, + CURL_DNS_TYPE_A, DOH_DNS_LABEL_LOOP, NULL}, /* packet with NSCOUNT == 1 */ {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x01\x00\x00\x04\x61\x61\x61" @@ -136,7 +129,7 @@ static const struct dohresp resp[] = { "\00\x04\x01\x01\x01\x01", /* RDDATA */ 62 + 30, - DNS_TYPE_AAAA, DOH_OK, + CURL_DNS_TYPE_AAAA, DOH_OK, "2020:2020:0000:0000:0000:0000:0000:2020 " }, /* packet with ARCOUNT == 1 */ @@ -148,13 +141,11 @@ static const struct dohresp resp[] = { "\00\x04\x01\x01\x01\x01", /* RDDATA */ 62 + 30, - DNS_TYPE_AAAA, DOH_OK, + CURL_DNS_TYPE_AAAA, DOH_OK, "2020:2020:0000:0000:0000:0000:0000:2020 " }, -}; + }; -UNITTEST_START -{ size_t size = 0; unsigned char buffer[256]; size_t i; @@ -203,7 +194,7 @@ UNITTEST_START size_t o; struct dohaddr *a; a = &d.addr[u]; - if(resp[i].type == DNS_TYPE_A) { + if(resp[i].type == CURL_DNS_TYPE_A) { p = &a->ip.v4[0]; curl_msnprintf(ptr, len, "%u.%u.%u.%u ", p[0], p[1], p[2], p[3]); o = strlen(ptr); @@ -245,7 +236,8 @@ UNITTEST_START struct dohentry d; DOHcode rc; memset(&d, 0, sizeof(d)); - rc = doh_resp_decode((const unsigned char *)full49, i, DNS_TYPE_A, &d); + rc = doh_resp_decode((const unsigned char *)full49, i, CURL_DNS_TYPE_A, + &d); if(!rc) { /* none of them should work */ curl_mfprintf(stderr, "%zu: %d\n", i, rc); @@ -259,7 +251,7 @@ UNITTEST_START DOHcode rc; memset(&d, 0, sizeof(d)); rc = doh_resp_decode((const unsigned char *)&full49[i], sizeof(full49)-i-1, - DNS_TYPE_A, &d); + CURL_DNS_TYPE_A, &d); if(!rc) { /* none of them should work */ curl_mfprintf(stderr, "2 %zu: %d\n", i, rc); @@ -273,7 +265,7 @@ UNITTEST_START struct dohaddr *a; memset(&d, 0, sizeof(d)); rc = doh_resp_decode((const unsigned char *)full49, sizeof(full49)-1, - DNS_TYPE_A, &d); + CURL_DNS_TYPE_A, &d); fail_if(d.numaddr != 1, "missing address"); a = &d.addr[0]; p = &a->ip.v4[0]; @@ -285,13 +277,7 @@ UNITTEST_START } fail_if(d.numcname, "bad cname counter"); } -} -UNITTEST_STOP - -#else /* CURL_DISABLE_DOH */ -UNITTEST_START -/* nothing to do, just succeed */ -UNITTEST_STOP - - #endif + + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/unit1651.c b/vendor/curl/tests/unit/unit1651.c index 56c37e97fbd..5ebce7aabda 100644 --- a/vendor/curl/tests/unit/unit1651.c +++ b/vendor/curl/tests/unit/unit1651.c @@ -21,24 +21,19 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "vtls/x509asn1.h" -static CURLcode unit_setup(void) -{ - return CURLE_OK; -} - -static void unit_stop(void) +static CURLcode test_unit1651(const char *arg) { + UNITTEST_BEGIN_SIMPLE -} -#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) +#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) -/* cert captured from gdb when connecting to curl.se on October 26 - 2018 */ -static unsigned char cert[] = { + /* cert captured from gdb when connecting to curl.se on October 26 + 2018 */ + static unsigned char cert[] = { 0x30, 0x82, 0x0F, 0x5B, 0x30, 0x82, 0x0E, 0x43, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0C, 0x08, 0x77, 0x99, 0x2C, 0x6B, 0x67, 0xE1, 0x18, 0xD6, 0x66, 0x66, 0x9E, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, @@ -342,10 +337,8 @@ static unsigned char cert[] = { 0x70, 0x77, 0x54, 0x57, 0x09, 0x03, 0x56, 0x4A, 0x33, 0x60, 0x00, 0x27, 0xFE, 0xA7, 0xD7, 0xA9, 0xC4, 0xEC, 0x17, 0x17, 0x8D, 0x87, 0x70, 0x6B, 0x48, 0x88, 0x61, 0x54, 0x4A, 0x2B, 0xB7, 0x6A, 0x12, 0x08, 0xFB, -}; + }; -UNITTEST_START -{ CURLcode result; const char *beg = (const char *)&cert[0]; const char *end = (const char *)&cert[sizeof(cert)]; @@ -370,7 +363,7 @@ UNITTEST_START for(i = 0; i < 45; i++) { unsigned char backup = cert[i]; cert[i] = (unsigned char) (byte & 0xff); - (void) Curl_extract_certinfo(data, 0, beg, end); + (void)Curl_extract_certinfo(data, 0, beg, end); cert[i] = backup; } } @@ -378,15 +371,9 @@ UNITTEST_START curl_easy_cleanup(data); } curl_global_cleanup(); -} -UNITTEST_STOP - #else + puts("not tested since Curl_extract_certinfo() is not built in"); +#endif -UNITTEST_START -{ - puts("not tested since Curl_extract_certinfo() is not built-in"); + UNITTEST_END_SIMPLE } -UNITTEST_STOP - -#endif diff --git a/vendor/curl/tests/unit/unit1652.c b/vendor/curl/tests/unit/unit1652.c index c8cd06dacf1..ad3014edca4 100644 --- a/vendor/curl/tests/unit/unit1652.c +++ b/vendor/curl/tests/unit/unit1652.c @@ -21,7 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "urldata.h" #include "sendf.h" @@ -32,22 +32,16 @@ * updated to still be valid. */ -static struct Curl_easy *testdata; - static char input[4096]; static char output[4096]; -int debugf_cb(CURL *handle, curl_infotype type, char *buf, size_t size, - void *userptr); - /* * This debugf callback is simply dumping the string into the static buffer * for the unit test to inspect. Since we know that we're only dealing with * text we can afford the luxury of skipping the type check here. */ -int -debugf_cb(CURL *handle, curl_infotype type, char *buf, size_t size, - void *userptr) +static int debugf_cb(CURL *handle, curl_infotype type, char *buf, size_t size, + void *userptr) { (void)handle; (void)type; @@ -58,26 +52,24 @@ debugf_cb(CURL *handle, curl_infotype type, char *buf, size_t size, return 0; } -static CURLcode -unit_setup(void) +static CURLcode t1652_setup(struct Curl_easy **easy) { CURLcode res = CURLE_OK; global_init(CURL_GLOBAL_ALL); - testdata = curl_easy_init(); - if(!testdata) { + *easy = curl_easy_init(); + if(!*easy) { curl_global_cleanup(); return CURLE_OUT_OF_MEMORY; } - curl_easy_setopt(testdata, CURLOPT_DEBUGFUNCTION, debugf_cb); - curl_easy_setopt(testdata, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(*easy, CURLOPT_DEBUGFUNCTION, debugf_cb); + curl_easy_setopt(*easy, CURLOPT_VERBOSE, 1L); return res; } -static void -unit_stop(void) +static void t1652_stop(struct Curl_easy *easy) { - curl_easy_cleanup(testdata); + curl_easy_cleanup(easy); curl_global_cleanup(); } @@ -90,7 +82,11 @@ static int verify(const char *info, const char *two) return strncmp(info, two, nl - info); } -UNITTEST_START +static CURLcode test_unit1652(const char *arg) +{ + struct Curl_easy *easy; + + UNITTEST_BEGIN(t1652_setup(&easy)) #if defined(CURL_GNUC_DIAG) && !defined(__clang__) #pragma GCC diagnostic push @@ -101,65 +97,69 @@ UNITTEST_START #endif #endif -/* Injecting a simple short string via a format */ -curl_msnprintf(input, sizeof(input), "Simple Test"); -Curl_infof(testdata, "%s", input); -fail_unless(verify(output, input) == 0, "Simple string test"); - -/* Injecting a few different variables with a format */ -Curl_infof(testdata, "%s %u testing %lu", input, 42, 43L); -fail_unless(verify(output, "Simple Test 42 testing 43\n") == 0, - "Format string"); - -/* Variations of empty strings */ -Curl_infof(testdata, ""); -fail_unless(strlen(output) == 1, "Empty string"); -Curl_infof(testdata, "%s", (char *)NULL); -fail_unless(verify(output, "(nil)") == 0, "Passing NULL as string"); - -/* Note: libcurl's tracebuffer hold 2048 bytes, so the max strlen() we - * get out of it is 2047, since we need a \0 at the end. - * Curl_infof() in addition adds a \n at the end, making the effective - * output 2046 characters. - * Any input that long or longer will truncated, ending in '...\n'. - */ - -/* A string just long enough to not be truncated */ -memset(input, '\0', sizeof(input)); -memset(input, 'A', 2045); -Curl_infof(testdata, "%s", input); -fprintf(stderr, "output len %d: %s", (int)strlen(output), output); -/* output is input + \n */ -fail_unless(strlen(output) == 2046, "No truncation of infof input"); -fail_unless(verify(output, input) == 0, "No truncation of infof input"); -fail_unless(output[sizeof(output) - 1] == '\0', - "No truncation of infof input"); - -/* Just over the limit without newline for truncation via '...' */ -memset(input + 2045, 'A', 4); -Curl_infof(testdata, "%s", input); -fprintf(stderr, "output len %d: %s", (int)strlen(output), output); -fail_unless(strlen(output) == 2047, "Truncation of infof input 1"); -fail_unless(output[sizeof(output) - 1] == '\0', "Truncation of infof input 1"); - -/* Just over the limit with newline for truncation via '...' */ -memset(input + 2045, 'A', 4); -memset(input + 2045 + 4, '\n', 1); -Curl_infof(testdata, "%s", input); -fprintf(stderr, "output len %d: %s", (int)strlen(output), output); -fail_unless(strlen(output) == 2047, "Truncation of infof input 2"); -fail_unless(output[sizeof(output) - 1] == '\0', "Truncation of infof input 2"); - -/* Way over the limit for truncation via '...' */ -memset(input, '\0', sizeof(input)); -memset(input, 'A', sizeof(input) - 1); -Curl_infof(testdata, "%s", input); -fprintf(stderr, "output len %d: %s", (int)strlen(output), output); -fail_unless(strlen(output) == 2047, "Truncation of infof input 3"); -fail_unless(output[sizeof(output) - 1] == '\0', "Truncation of infof input 3"); + /* Injecting a simple short string via a format */ + curl_msnprintf(input, sizeof(input), "Simple Test"); + Curl_infof(easy, "%s", input); + fail_unless(verify(output, input) == 0, "Simple string test"); + + /* Injecting a few different variables with a format */ + Curl_infof(easy, "%s %u testing %lu", input, 42, 43L); + fail_unless(verify(output, "Simple Test 42 testing 43\n") == 0, + "Format string"); + + /* Variations of empty strings */ + Curl_infof(easy, ""); + fail_unless(strlen(output) == 1, "Empty string"); + Curl_infof(easy, "%s", (char *)NULL); + fail_unless(verify(output, "(nil)") == 0, "Passing NULL as string"); + + /* Note: libcurl's tracebuffer hold 2048 bytes, so the max strlen() we + * get out of it is 2047, since we need a \0 at the end. + * Curl_infof() in addition adds a \n at the end, making the effective + * output 2046 characters. + * Any input that long or longer will truncated, ending in '...\n'. + */ + + /* A string just long enough to not be truncated */ + memset(input, '\0', sizeof(input)); + memset(input, 'A', 2045); + Curl_infof(easy, "%s", input); + fprintf(stderr, "output len %d: %s", (int)strlen(output), output); + /* output is input + \n */ + fail_unless(strlen(output) == 2046, "No truncation of infof input"); + fail_unless(verify(output, input) == 0, "No truncation of infof input"); + fail_unless(output[sizeof(output) - 1] == '\0', + "No truncation of infof input"); + + /* Just over the limit without newline for truncation via '...' */ + memset(input + 2045, 'A', 4); + Curl_infof(easy, "%s", input); + fprintf(stderr, "output len %d: %s", (int)strlen(output), output); + fail_unless(strlen(output) == 2047, "Truncation of infof input 1"); + fail_unless(output[sizeof(output) - 1] == '\0', + "Truncation of infof input 1"); + + /* Just over the limit with newline for truncation via '...' */ + memset(input + 2045, 'A', 4); + memset(input + 2045 + 4, '\n', 1); + Curl_infof(easy, "%s", input); + fprintf(stderr, "output len %d: %s", (int)strlen(output), output); + fail_unless(strlen(output) == 2047, "Truncation of infof input 2"); + fail_unless(output[sizeof(output) - 1] == '\0', + "Truncation of infof input 2"); + + /* Way over the limit for truncation via '...' */ + memset(input, '\0', sizeof(input)); + memset(input, 'A', sizeof(input) - 1); + Curl_infof(easy, "%s", input); + fprintf(stderr, "output len %d: %s", (int)strlen(output), output); + fail_unless(strlen(output) == 2047, "Truncation of infof input 3"); + fail_unless(output[sizeof(output) - 1] == '\0', + "Truncation of infof input 3"); #if defined(CURL_GNUC_DIAG) && !defined(__clang__) #pragma GCC diagnostic pop #endif -UNITTEST_STOP + UNITTEST_END(t1652_stop(easy)) +} diff --git a/vendor/curl/tests/unit/unit1653.c b/vendor/curl/tests/unit/unit1653.c index ae10e8bb906..1e6fd9ef269 100644 --- a/vendor/curl/tests/unit/unit1653.c +++ b/vendor/curl/tests/unit/unit1653.c @@ -21,31 +21,15 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "urldata.h" #include "curl/urlapi.h" #include "urlapi-int.h" - -static CURLU *u; - -static CURLcode -unit_setup(void) -{ - return CURLE_OK; -} - -static void -unit_stop(void) -{ - curl_global_cleanup(); -} - #define free_and_clear(x) free(x); x = NULL -static CURLUcode parse_port(CURLU *url, - char *h, bool has_scheme) +static CURLUcode parse_port(CURLU *url, char *h, bool has_scheme) { struct dynbuf host; CURLUcode ret; @@ -57,8 +41,12 @@ static CURLUcode parse_port(CURLU *url, return ret; } -UNITTEST_START +static CURLcode test_unit1653(const char *arg) { + UNITTEST_BEGIN_SIMPLE + + CURLU *u; + CURLUcode ret; char *ipv6port = NULL; char *portnum; @@ -228,5 +216,5 @@ UNITTEST_START free(ipv6port); curl_url_cleanup(u); + UNITTEST_END_SIMPLE } -UNITTEST_STOP diff --git a/vendor/curl/tests/unit/unit1654.c b/vendor/curl/tests/unit/unit1654.c index 73bf17a0c61..4fe2439907a 100644 --- a/vendor/curl/tests/unit/unit1654.c +++ b/vendor/curl/tests/unit/unit1654.c @@ -21,26 +21,16 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "urldata.h" #include "altsvc.h" -static CURLcode -unit_setup(void) +static CURLcode test_unit1654(const char *arg) { - return CURLE_OK; -} + UNITTEST_BEGIN_SIMPLE -static void -unit_stop(void) -{ - curl_global_cleanup(); -} - -UNITTEST_START #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_ALTSVC) -{ char outname[256]; CURL *curl; CURLcode result; @@ -105,6 +95,20 @@ UNITTEST_START fail_if(result, "Curl_altsvc_parse(7) failed!"); fail_unless(Curl_llist_count(&asi->list) == 10, "wrong number of entries"); + result = + Curl_altsvc_parse(curl, asi, + "h2=\":443\", h3=\":443\"; " + "persist = \"1\"; ma = 120;\r\n", + ALPN_h1, "curl.se", 80); + fail_if(result, "Curl_altsvc_parse(6) failed!"); + fail_unless(Curl_llist_count(&asi->list) == 12, "wrong number of entries"); + + /* clear - without semicolon */ + result = Curl_altsvc_parse(curl, asi, "clear\r\n", + ALPN_h1, "curl.se", 80); + fail_if(result, "Curl_altsvc_parse(7) failed!"); + fail_unless(Curl_llist_count(&asi->list) == 10, "wrong number of entries"); + /* only a non-existing alpn */ result = Curl_altsvc_parse(curl, asi, "h6=\"example.net:443\"; ma=\"180\";\r\n", @@ -134,6 +138,7 @@ UNITTEST_START curl_easy_cleanup(curl); fail: Curl_altsvc_cleanup(&asi); -} #endif -UNITTEST_STOP + + UNITTEST_END(curl_global_cleanup()) +} diff --git a/vendor/curl/tests/unit/unit1655.c b/vendor/curl/tests/unit/unit1655.c index 384fc120e6e..a22e0872713 100644 --- a/vendor/curl/tests/unit/unit1655.c +++ b/vendor/curl/tests/unit/unit1655.c @@ -21,170 +21,157 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "doh.h" /* from the lib dir */ -static CURLcode unit_setup(void) +static CURLcode test_unit1655(const char *arg) { - /* whatever you want done first */ - return CURLE_OK; -} - -static void unit_stop(void) -{ - /* done before shutting down and exiting */ -} + UNITTEST_BEGIN_SIMPLE #ifndef CURL_DISABLE_DOH - -UNITTEST_START - -/* - * Prove detection of write overflow using a short buffer and a name - * of maximal valid length. - * - * Prove detection of other invalid input. - */ -do { - static const char max[] = - /* ..|....1.........2.........3.........4.........5.........6... */ - /* 3456789012345678901234567890123456789012345678901234567890123 */ - "this.is.a.maximum-length.hostname." /* 34: 34 */ - "with-no-label-of-greater-length-than-the-sixty-three-characters." - /* 64: 98 */ - "specified.in.the.RFCs." /* 22: 120 */ - "and.with.a.QNAME.encoding.whose.length.is.exactly." /* 50: 170 */ - "the.maximum.length.allowed." /* 27: 197 */ - "that.is.two-hundred.and.fifty-six." /* 34: 231 */ - "including.the.last.null." /* 24: 255 */ - ""; - static const char toolong[] = - /* ..|....1.........2.........3.........4.........5.........6... */ - /* 3456789012345678901234567890123456789012345678901234567890123 */ - "here.is.a.hostname.which.is.just.barely.too.long." /* 49: 49 */ - "to.be.encoded.as.a.QNAME.of.the.maximum.allowed.length." - /* 55: 104 */ - "which.is.256.including.a.final.zero-length.label." /* 49: 153 */ - "representing.the.root.node.so.that.a.name.with." /* 47: 200 */ - "a.trailing.dot.may.have.up.to." /* 30: 230 */ - "255.characters.never.more." /* 26: 256 */ - ""; - static const char emptylabel[] = - "this.is.an.otherwise-valid.hostname." - ".with.an.empty.label."; - static const char outsizelabel[] = - "this.is.an.otherwise-valid.hostname." - "with-a-label-of-greater-length-than-the-sixty-three-characters-" - "specified.in.the.RFCs."; - int i; - - struct test { - const char *name; - const DOHcode expected_result; - }; - - /* plays the role of struct dnsprobe in urldata.h */ - struct demo { - unsigned char dohbuffer[255 + 16]; /* deliberately short buffer */ - unsigned char canary1; - unsigned char canary2; - unsigned char canary3; - }; - - const struct test playlist[4] = { - { toolong, DOH_DNS_NAME_TOO_LONG }, /* expect early failure */ - { emptylabel, DOH_DNS_BAD_LABEL }, /* also */ - { outsizelabel, DOH_DNS_BAD_LABEL }, /* also */ - { max, DOH_OK } /* expect buffer overwrite */ - }; - - for(i = 0; i < (int)(CURL_ARRAYSIZE(playlist)); i++) { - const char *name = playlist[i].name; - size_t olen = 100000; - struct demo victim; - DOHcode d; - - victim.canary1 = 87; /* magic numbers, arbitrarily picked */ - victim.canary2 = 35; - victim.canary3 = 41; - d = doh_req_encode(name, DNS_TYPE_A, victim.dohbuffer, - sizeof(struct demo), /* allow room for overflow */ - &olen); - - fail_unless(d == playlist[i].expected_result, - "result returned was not as expected"); - if(d == playlist[i].expected_result) { - if(name == max) { - fail_if(victim.canary1 == 87, - "demo one-byte buffer overwrite did not happen"); + /* + * Prove detection of write overflow using a short buffer and a name + * of maximal valid length. + * + * Prove detection of other invalid input. + */ + do { + static const char max[] = + /* ..|....1.........2.........3.........4.........5.........6... */ + /* 3456789012345678901234567890123456789012345678901234567890123 */ + "this.is.a.maximum-length.hostname." /* 34: 34 */ + "with-no-label-of-greater-length-than-the-sixty-three-characters." + /* 64: 98 */ + "specified.in.the.RFCs." /* 22: 120 */ + "and.with.a.QNAME.encoding.whose.length.is.exactly." /* 50: 170 */ + "the.maximum.length.allowed." /* 27: 197 */ + "that.is.two-hundred.and.fifty-six." /* 34: 231 */ + "including.the.last.null." /* 24: 255 */ + ""; + static const char toolong[] = + /* ..|....1.........2.........3.........4.........5.........6... */ + /* 3456789012345678901234567890123456789012345678901234567890123 */ + "here.is.a.hostname.which.is.just.barely.too.long." /* 49: 49 */ + "to.be.encoded.as.a.QNAME.of.the.maximum.allowed.length." + /* 55: 104 */ + "which.is.256.including.a.final.zero-length.label." /* 49: 153 */ + "representing.the.root.node.so.that.a.name.with." /* 47: 200 */ + "a.trailing.dot.may.have.up.to." /* 30: 230 */ + "255.characters.never.more." /* 26: 256 */ + ""; + static const char emptylabel[] = + "this.is.an.otherwise-valid.hostname." + ".with.an.empty.label."; + static const char outsizelabel[] = + "this.is.an.otherwise-valid.hostname." + "with-a-label-of-greater-length-than-the-sixty-three-characters-" + "specified.in.the.RFCs."; + int i; + + struct test { + const char *name; + const DOHcode expected_result; + }; + + /* plays the role of struct dnsprobe in urldata.h */ + struct demo { + unsigned char dohbuffer[255 + 16]; /* deliberately short buffer */ + unsigned char canary1; + unsigned char canary2; + unsigned char canary3; + }; + + const struct test playlist[4] = { + { toolong, DOH_DNS_NAME_TOO_LONG }, /* expect early failure */ + { emptylabel, DOH_DNS_BAD_LABEL }, /* also */ + { outsizelabel, DOH_DNS_BAD_LABEL }, /* also */ + { max, DOH_OK } /* expect buffer overwrite */ + }; + + for(i = 0; i < (int)(CURL_ARRAYSIZE(playlist)); i++) { + const char *name = playlist[i].name; + size_t olen = 100000; + struct demo victim; + DOHcode d; + + victim.canary1 = 87; /* magic numbers, arbitrarily picked */ + victim.canary2 = 35; + victim.canary3 = 41; + d = doh_req_encode(name, CURL_DNS_TYPE_A, victim.dohbuffer, + sizeof(struct demo), /* allow room for overflow */ + &olen); + + fail_unless(d == playlist[i].expected_result, + "result returned was not as expected"); + if(d == playlist[i].expected_result) { + if(name == max) { + fail_if(victim.canary1 == 87, + "demo one-byte buffer overwrite did not happen"); + } + else { + fail_unless(victim.canary1 == 87, + "one-byte buffer overwrite has happened"); + } + fail_unless(victim.canary2 == 35, + "two-byte buffer overwrite has happened"); + fail_unless(victim.canary3 == 41, + "three-byte buffer overwrite has happened"); } else { - fail_unless(victim.canary1 == 87, - "one-byte buffer overwrite has happened"); + if(d == DOH_OK) { + fail_unless(olen <= sizeof(victim.dohbuffer), + "wrote outside bounds"); + fail_unless(olen > strlen(name), "unrealistic low size"); + } } - fail_unless(victim.canary2 == 35, - "two-byte buffer overwrite has happened"); - fail_unless(victim.canary3 == 41, - "three-byte buffer overwrite has happened"); } - else { - if(d == DOH_OK) { - fail_unless(olen <= sizeof(victim.dohbuffer), "wrote outside bounds"); - fail_unless(olen > strlen(name), "unrealistic low size"); - } - } - } -} while(0); - -/* run normal cases and try to trigger buffer length related errors */ -do { - DNStype dnstype = DNS_TYPE_A; - unsigned char buffer[128]; - const size_t buflen = sizeof(buffer); - const size_t magic1 = 9765; - size_t olen1 = magic1; - const char *sunshine1 = "a.com"; - const char *dotshine1 = "a.com."; - const char *sunshine2 = "aa.com"; - size_t olen2; - DOHcode ret2; - size_t olen; - - DOHcode ret = doh_req_encode(sunshine1, dnstype, buffer, buflen, &olen1); - fail_unless(ret == DOH_OK, "sunshine case 1 should pass fine"); - fail_if(olen1 == magic1, "olen has not been assigned properly"); - fail_unless(olen1 > strlen(sunshine1), "bad out length"); - - /* with a trailing dot, the response should have the same length */ - olen2 = magic1; - ret2 = doh_req_encode(dotshine1, dnstype, buffer, buflen, &olen2); - fail_unless(ret2 == DOH_OK, "dotshine case should pass fine"); - fail_if(olen2 == magic1, "olen has not been assigned properly"); - fail_unless(olen1 == olen2, "olen should not grow for a trailing dot"); - - /* add one letter, the response should be one longer */ - olen2 = magic1; - ret2 = doh_req_encode(sunshine2, dnstype, buffer, buflen, &olen2); - fail_unless(ret2 == DOH_OK, "sunshine case 2 should pass fine"); - fail_if(olen2 == magic1, "olen has not been assigned properly"); - fail_unless(olen1 + 1 == olen2, "olen should grow with the hostname"); - - /* pass a short buffer, should fail */ - ret = doh_req_encode(sunshine1, dnstype, buffer, olen1 - 1, &olen); - fail_if(ret == DOH_OK, "short buffer should have been noticed"); - - /* pass a minimum buffer, should succeed */ - ret = doh_req_encode(sunshine1, dnstype, buffer, olen1, &olen); - fail_unless(ret == DOH_OK, "minimal length buffer should be long enough"); - fail_unless(olen == olen1, "bad buffer length"); -} while(0); -UNITTEST_STOP - -#else /* CURL_DISABLE_DOH */ - -UNITTEST_START -/* nothing to do, just succeed */ -UNITTEST_STOP - -#endif + } while(0); + + /* run normal cases and try to trigger buffer length related errors */ + do { + DNStype dnstype = CURL_DNS_TYPE_A; + unsigned char buffer[128]; + const size_t buflen = sizeof(buffer); + const size_t magic1 = 9765; + size_t olen1 = magic1; + static const char *sunshine1 = "a.com"; + static const char *dotshine1 = "a.com."; + static const char *sunshine2 = "aa.com"; + size_t olen2; + DOHcode ret2; + size_t olen; + + DOHcode ret = doh_req_encode(sunshine1, dnstype, buffer, buflen, &olen1); + fail_unless(ret == DOH_OK, "sunshine case 1 should pass fine"); + fail_if(olen1 == magic1, "olen has not been assigned properly"); + fail_unless(olen1 > strlen(sunshine1), "bad out length"); + + /* with a trailing dot, the response should have the same length */ + olen2 = magic1; + ret2 = doh_req_encode(dotshine1, dnstype, buffer, buflen, &olen2); + fail_unless(ret2 == DOH_OK, "dotshine case should pass fine"); + fail_if(olen2 == magic1, "olen has not been assigned properly"); + fail_unless(olen1 == olen2, "olen should not grow for a trailing dot"); + + /* add one letter, the response should be one longer */ + olen2 = magic1; + ret2 = doh_req_encode(sunshine2, dnstype, buffer, buflen, &olen2); + fail_unless(ret2 == DOH_OK, "sunshine case 2 should pass fine"); + fail_if(olen2 == magic1, "olen has not been assigned properly"); + fail_unless(olen1 + 1 == olen2, "olen should grow with the hostname"); + + /* pass a short buffer, should fail */ + ret = doh_req_encode(sunshine1, dnstype, buffer, olen1 - 1, &olen); + fail_if(ret == DOH_OK, "short buffer should have been noticed"); + + /* pass a minimum buffer, should succeed */ + ret = doh_req_encode(sunshine1, dnstype, buffer, olen1, &olen); + fail_unless(ret == DOH_OK, "minimal length buffer should be long enough"); + fail_unless(olen == olen1, "bad buffer length"); + } while(0); + +#endif /* CURL_DISABLE_DOH */ + + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/unit1656.c b/vendor/curl/tests/unit/unit1656.c index 5b817e9d840..520a430fe93 100644 --- a/vendor/curl/tests/unit/unit1656.c +++ b/vendor/curl/tests/unit/unit1656.c @@ -21,22 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "vtls/x509asn1.h" -static CURLcode unit_setup(void) -{ - return CURLE_OK; -} - -static void unit_stop(void) -{ - -} - -#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \ - defined(USE_MBEDTLS) +#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_MBEDTLS) struct test_spec { const char *input; @@ -44,7 +33,34 @@ struct test_spec { CURLcode exp_result; }; -static struct test_spec test_specs[] = { +static bool do_test(const struct test_spec *spec, size_t i, + struct dynbuf *dbuf) +{ + CURLcode result; + const char *in = spec->input; + + curlx_dyn_reset(dbuf); + result = Curl_x509_GTime2str(dbuf, in, in + strlen(in)); + if(result != spec->exp_result) { + curl_mfprintf(stderr, "test %zu: expect result %d, got %d\n", + i, spec->exp_result, result); + return FALSE; + } + else if(!result && strcmp(spec->exp_output, curlx_dyn_ptr(dbuf))) { + curl_mfprintf(stderr, + "test %zu: input '%s', expected output '%s', got '%s'\n", + i, in, spec->exp_output, curlx_dyn_ptr(dbuf)); + return FALSE; + } + + return TRUE; +} + +static CURLcode test_unit1656(const char *arg) +{ + UNITTEST_BEGIN_SIMPLE + + static const struct test_spec test_specs[] = { { "190321134340", "1903-21-13 43:40:00", CURLE_OK }, { "", NULL, CURLE_BAD_FUNCTION_ARGUMENT }, { "WTF", NULL, CURLE_BAD_FUNCTION_ARGUMENT }, @@ -71,32 +87,8 @@ static struct test_spec test_specs[] = { { "190321134340-3", "1903-21-13 43:40:00 UTC-3", CURLE_OK }, { "19032113434017.0-04", "1903-21-13 43:40:17 UTC-04", CURLE_OK }, { "19032113434017.01-01:10", "1903-21-13 43:40:17.01 UTC-01:10", CURLE_OK }, -}; - -static bool do_test(struct test_spec *spec, size_t i, struct dynbuf *dbuf) -{ - CURLcode result; - const char *in = spec->input; + }; - curlx_dyn_reset(dbuf); - result = Curl_x509_GTime2str(dbuf, in, in + strlen(in)); - if(result != spec->exp_result) { - curl_mfprintf(stderr, "test %zu: expect result %d, got %d\n", - i, spec->exp_result, result); - return FALSE; - } - else if(!result && strcmp(spec->exp_output, curlx_dyn_ptr(dbuf))) { - curl_mfprintf(stderr, - "test %zu: input '%s', expected output '%s', got '%s'\n", - i, in, spec->exp_output, curlx_dyn_ptr(dbuf)); - return FALSE; - } - - return TRUE; -} - -UNITTEST_START -{ size_t i; struct dynbuf dbuf; bool all_ok = TRUE; @@ -116,15 +108,17 @@ UNITTEST_START curlx_dyn_free(&dbuf); curl_global_cleanup(); + + UNITTEST_END_SIMPLE } -UNITTEST_STOP #else -UNITTEST_START +static CURLcode test_unit1656(const char *arg) { - puts("not tested since Curl_x509_GTime2str() is not built-in"); + UNITTEST_BEGIN_SIMPLE + puts("not tested since Curl_x509_GTime2str() is not built in"); + UNITTEST_END_SIMPLE } -UNITTEST_STOP #endif diff --git a/vendor/curl/tests/unit/unit1657.c b/vendor/curl/tests/unit/unit1657.c index 6c4bebdde1c..4898d6c1394 100644 --- a/vendor/curl/tests/unit/unit1657.c +++ b/vendor/curl/tests/unit/unit1657.c @@ -21,35 +21,25 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "vtls/x509asn1.h" -static CURLcode unit_setup(void) -{ - return CURLE_OK; -} - -static void unit_stop(void) -{ - -} - -#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \ - defined(USE_MBEDTLS) +#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_MBEDTLS) struct test1657_spec { - CURLcode (*setbuf)(struct test1657_spec *spec, struct dynbuf *buf); + CURLcode (*setbuf)(const struct test1657_spec *spec, struct dynbuf *buf); size_t n; CURLcode exp_result; }; -static CURLcode make1657_nested(struct test1657_spec *spec, struct dynbuf *buf) +static CURLcode make1657_nested(const struct test1657_spec *spec, + struct dynbuf *buf) { CURLcode r; size_t i; - unsigned char open_undef[] = { 0x32, 0x80 }; - unsigned char close_undef[] = { 0x00, 0x00 }; + unsigned char open_undef[] = { 0x32, 0x80 }; + unsigned char close_undef[] = { 0x00, 0x00 }; for(i = 0; i < spec->n; ++i) { r = curlx_dyn_addn(buf, open_undef, sizeof(open_undef)); @@ -64,14 +54,14 @@ static CURLcode make1657_nested(struct test1657_spec *spec, struct dynbuf *buf) return CURLE_OK; } -static struct test1657_spec test1657_specs[] = { +static const struct test1657_spec test1657_specs[] = { { make1657_nested, 3, CURLE_OK }, { make1657_nested, 16, CURLE_OK }, { make1657_nested, 17, CURLE_BAD_FUNCTION_ARGUMENT }, { make1657_nested, 1024, CURLE_BAD_FUNCTION_ARGUMENT }, }; -static bool do_test1657(struct test1657_spec *spec, size_t i, +static bool do_test1657(const struct test1657_spec *spec, size_t i, struct dynbuf *buf) { CURLcode result; @@ -95,8 +85,10 @@ static bool do_test1657(struct test1657_spec *spec, size_t i, return TRUE; } -UNITTEST_START +static CURLcode test_unit1657(const char *arg) { + UNITTEST_BEGIN_SIMPLE + size_t i; bool all_ok = TRUE; struct dynbuf dbuf; @@ -116,15 +108,17 @@ UNITTEST_START curlx_dyn_free(&dbuf); curl_global_cleanup(); + + UNITTEST_END_SIMPLE } -UNITTEST_STOP #else -UNITTEST_START +static CURLcode test_unit1657(const char *arg) { - puts("not tested since Curl_x509_getASN1Element() is not built-in"); + UNITTEST_BEGIN_SIMPLE + puts("not tested since Curl_x509_getASN1Element() is not built in"); + UNITTEST_END_SIMPLE } -UNITTEST_STOP #endif diff --git a/vendor/curl/tests/unit/unit1658.c b/vendor/curl/tests/unit/unit1658.c index 8816fb06140..0a6a2e71c15 100644 --- a/vendor/curl/tests/unit/unit1658.c +++ b/vendor/curl/tests/unit/unit1658.c @@ -21,39 +21,26 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "doh.h" /* from the lib dir */ -static CURLcode unit_setup(void) +/* DoH + HTTPSRR are required */ +#if !defined(CURL_DISABLE_DOH) && defined(USE_HTTPSRR) + +static CURLcode t1658_setup(void) { /* whatever you want done first */ curl_global_init(CURL_GLOBAL_ALL); return CURLE_OK; } -static void unit_stop(void) -{ - curl_global_cleanup(); - /* done before shutting down and exiting */ -} - -/* DoH + HTTPSRR are required */ -#if !defined(CURL_DISABLE_DOH) && defined(USE_HTTPSRR) - extern CURLcode doh_resp_decode_httpsrr(struct Curl_easy *data, const unsigned char *cp, size_t len, struct Curl_https_rrinfo **hrr); extern void doh_print_httpsrr(struct Curl_easy *data, struct Curl_https_rrinfo *hrr); -struct test { - const char *name; - const unsigned char *dns; - size_t len; /* size of the dns packet */ - const char *expect; -}; - /* * The idea here is that we pass one DNS packet at the time to the decoder. we * then generate a string output with the results and compare if it matches @@ -127,12 +114,21 @@ static void rrresults(struct Curl_https_rrinfo *rr, CURLcode result) } } -UNITTEST_START +static CURLcode test_unit1658(const char *arg) { + UNITTEST_BEGIN(t1658_setup()) + /* The "SvcParamKeys" specified within the HTTPS RR packet *must* be provided in numerical order. */ - static struct test t[] = { + struct test { + const char *name; + const unsigned char *dns; + size_t len; /* size of the dns packet */ + const char *expect; + }; + + static const struct test t[] = { { "single h2 alpn", (const unsigned char *)"\x00\x00" /* 16-bit prio */ @@ -365,7 +361,7 @@ UNITTEST_START "r:43|" }, { - "alpn + two ipv4 addreses", + "alpn + two ipv4 addresses", (const unsigned char *)"\x00\x10" /* 16-bit prio */ "\x00" /* no RNAME */ "\x00\x01" /* RR (1 == ALPN) */ @@ -380,7 +376,7 @@ UNITTEST_START "r:0|p:16|.|alpn:10|ipv4:192.168.0.1|ipv4:192.168.0.2|" }, { - "alpn + two ipv4 addreses in wrong order", + "alpn + two ipv4 addresses in wrong order", (const unsigned char *)"\x00\x10" /* 16-bit prio */ "\x00" /* no RNAME */ "\x00\x04" /* RR (4 == Ipv4hints) */ @@ -541,13 +537,16 @@ UNITTEST_START } curl_easy_cleanup(easy); } + + UNITTEST_END(curl_global_cleanup()) } -UNITTEST_STOP #else /* CURL_DISABLE_DOH or not HTTPSRR enabled */ -UNITTEST_START -/* nothing to do, just succeed */ -UNITTEST_STOP +static CURLcode test_unit1658(const char *arg) +{ + UNITTEST_BEGIN_SIMPLE + UNITTEST_END_SIMPLE +} #endif diff --git a/vendor/curl/tests/unit/unit1660.c b/vendor/curl/tests/unit/unit1660.c index 2ab9aa33324..5c66b1831cf 100644 --- a/vendor/curl/tests/unit/unit1660.c +++ b/vendor/curl/tests/unit/unit1660.c @@ -21,39 +21,43 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "urldata.h" #include "hsts.h" -static CURLcode -unit_setup(void) +#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_HSTS) +static CURLcode test_unit1660(const char *arg) { - return CURLE_OK; + UNITTEST_BEGIN_SIMPLE + puts("nothing to do when HTTP or HSTS are disabled"); + UNITTEST_END_SIMPLE } +#else -static void -unit_stop(void) +static void showsts(struct stsentry *e, const char *chost) { - curl_global_cleanup(); + if(!e) + printf("'%s' is not HSTS\n", chost); + else { + curl_mprintf("%s [%s]: %" CURL_FORMAT_CURL_OFF_T "%s\n", + chost, e->host, e->expires, + e->includeSubDomains ? " includeSubDomains" : ""); + } } -#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_HSTS) -UNITTEST_START +static CURLcode test_unit1660(const char *arg) { - puts("nothing to do when HTTP or HSTS are disabled"); -} -UNITTEST_STOP -#else + UNITTEST_BEGIN_SIMPLE -struct testit { - const char *host; - const char *chost; /* if non-NULL, use to lookup with */ - const char *hdr; /* if NULL, just do the lookup */ - const CURLcode result; /* parse result */ -}; + struct testit { + const char *host; + const char *chost; /* if non-NULL, use to lookup with */ + const char *hdr; /* if NULL, just do the lookup */ + const CURLcode result; /* parse result */ + }; -static const struct testit headers[] = { + static const struct testit headers[] = { /* two entries read from disk cache, verify first */ { "-", "readfrom.example", NULL, CURLE_OK}, { "-", "old.example", NULL, CURLE_OK}, @@ -104,21 +108,8 @@ static const struct testit headers[] = { /* make this live for 7 seconds */ { "expire.example", NULL, "max-age=\"7\"\r\n", CURLE_OK }, { NULL, NULL, NULL, CURLE_OK } -}; - -static void showsts(struct stsentry *e, const char *chost) -{ - if(!e) - printf("'%s' is not HSTS\n", chost); - else { - curl_mprintf("%s [%s]: %" CURL_FORMAT_CURL_OFF_T "%s\n", - chost, e->host, e->expires, - e->includeSubDomains ? " includeSubDomains" : ""); - } -} + }; -UNITTEST_START -{ CURLcode result; struct stsentry *e; struct hsts *h = Curl_hsts_init(); @@ -175,6 +166,7 @@ UNITTEST_START Curl_hsts_cleanup(&h); curl_easy_cleanup(easy); curl_global_cleanup(); + + UNITTEST_END(curl_global_cleanup()) } -UNITTEST_STOP #endif diff --git a/vendor/curl/tests/unit/unit1661.c b/vendor/curl/tests/unit/unit1661.c index 3d4eead93f4..446ef51bda3 100644 --- a/vendor/curl/tests/unit/unit1661.c +++ b/vendor/curl/tests/unit/unit1661.c @@ -21,12 +21,10 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "bufref.h" #include "memdebug.h" -static struct bufref bufref; - static int freecount = 0; static void test_free(void *p) @@ -36,19 +34,23 @@ static void test_free(void *p) free(p); } -static CURLcode unit_setup(void) +static CURLcode t1661_setup(struct bufref *bufref) { - Curl_bufref_init(&bufref); + Curl_bufref_init(bufref); return CURLE_OK; } -static void unit_stop(void) +static void t1661_stop(struct bufref *bufref) { - Curl_bufref_free(&bufref); + Curl_bufref_free(bufref); } -UNITTEST_START +static CURLcode test_unit1661(const char *arg) { + struct bufref bufref; + + UNITTEST_BEGIN(t1661_setup(&bufref)) + const char *buffer = NULL; CURLcode result = CURLE_OK; @@ -59,7 +61,6 @@ UNITTEST_START * 2: reference will be NULL * 3: destructor will be NULL */ - fail_unless(!bufref.ptr, "Initial reference must be NULL"); fail_unless(!bufref.len, "Initial length must be NULL"); fail_unless(!bufref.dtor, "Destructor must be NULL"); @@ -67,7 +68,6 @@ UNITTEST_START /** * testing Curl_bufref_set */ - buffer = malloc(13); abort_unless(buffer, "Out of memory"); Curl_bufref_set(&bufref, buffer, 13, test_free); @@ -79,20 +79,17 @@ UNITTEST_START /** * testing Curl_bufref_ptr */ - fail_unless((const char *) Curl_bufref_ptr(&bufref) == buffer, "Wrong pointer value returned"); /** * testing Curl_bufref_len */ - fail_unless(Curl_bufref_len(&bufref) == 13, "Wrong data size returned"); /** * testing Curl_bufref_memdup */ - result = Curl_bufref_memdup(&bufref, "1661", 3); abort_unless(result == CURLE_OK, curl_easy_strerror(result)); fail_unless(freecount == 1, "Destructor not called"); @@ -108,11 +105,11 @@ UNITTEST_START /** * testing Curl_bufref_free */ - Curl_bufref_free(&bufref); fail_unless(freecount == 1, "Wrong destructor called"); fail_unless(!bufref.ptr, "Initial reference must be NULL"); fail_unless(!bufref.len, "Initial length must be NULL"); fail_unless(!bufref.dtor, "Destructor must be NULL"); + + UNITTEST_END(t1661_stop(&bufref)) } -UNITTEST_STOP diff --git a/vendor/curl/tests/unit/unit1663.c b/vendor/curl/tests/unit/unit1663.c index f60d60f625c..0d6fb4bbbe5 100644 --- a/vendor/curl/tests/unit/unit1663.c +++ b/vendor/curl/tests/unit/unit1663.c @@ -21,7 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #ifdef HAVE_NETINET_IN_H #include @@ -30,25 +30,18 @@ #include #endif -#include - #include "cf-socket.h" #include "memdebug.h" /* LAST include file */ -static CURLcode unit_setup(void) +static CURLcode t1663_setup(void) { CURLcode res = CURLE_OK; global_init(CURL_GLOBAL_ALL); return res; } -static void unit_stop(void) -{ - curl_global_cleanup(); -} - -static void test_parse( +static void t1663_parse( const char *input_data, const char *exp_dev, const char *exp_iface, @@ -79,19 +72,22 @@ static void test_parse( free(host); } -UNITTEST_START +static CURLcode test_unit1663(const char *arg) { - test_parse("dev", "dev", NULL, NULL, CURLE_OK); - test_parse("if!eth0", NULL, "eth0", NULL, CURLE_OK); - test_parse("host!myname", NULL, NULL, "myname", CURLE_OK); - test_parse("ifhost!eth0!myname", NULL, "eth0", "myname", CURLE_OK); - test_parse("", NULL, NULL, NULL, CURLE_BAD_FUNCTION_ARGUMENT); - test_parse("!", "!", NULL, NULL, CURLE_OK); - test_parse("if!", NULL, NULL, NULL, CURLE_BAD_FUNCTION_ARGUMENT); - test_parse("if!eth0!blubb", NULL, "eth0!blubb", NULL, CURLE_OK); - test_parse("host!", NULL, NULL, NULL, CURLE_BAD_FUNCTION_ARGUMENT); - test_parse("ifhost!", NULL, NULL, NULL, CURLE_BAD_FUNCTION_ARGUMENT); - test_parse("ifhost!eth0", NULL, NULL, NULL, CURLE_BAD_FUNCTION_ARGUMENT); - test_parse("ifhost!eth0!", NULL, NULL, NULL, CURLE_BAD_FUNCTION_ARGUMENT); + UNITTEST_BEGIN(t1663_setup()) + + t1663_parse("dev", "dev", NULL, NULL, CURLE_OK); + t1663_parse("if!eth0", NULL, "eth0", NULL, CURLE_OK); + t1663_parse("host!myname", NULL, NULL, "myname", CURLE_OK); + t1663_parse("ifhost!eth0!myname", NULL, "eth0", "myname", CURLE_OK); + t1663_parse("", NULL, NULL, NULL, CURLE_BAD_FUNCTION_ARGUMENT); + t1663_parse("!", "!", NULL, NULL, CURLE_OK); + t1663_parse("if!", NULL, NULL, NULL, CURLE_BAD_FUNCTION_ARGUMENT); + t1663_parse("if!eth0!blubb", NULL, "eth0!blubb", NULL, CURLE_OK); + t1663_parse("host!", NULL, NULL, NULL, CURLE_BAD_FUNCTION_ARGUMENT); + t1663_parse("ifhost!", NULL, NULL, NULL, CURLE_BAD_FUNCTION_ARGUMENT); + t1663_parse("ifhost!eth0", NULL, NULL, NULL, CURLE_BAD_FUNCTION_ARGUMENT); + t1663_parse("ifhost!eth0!", NULL, NULL, NULL, CURLE_BAD_FUNCTION_ARGUMENT); + + UNITTEST_END(curl_global_cleanup()) } -UNITTEST_STOP diff --git a/vendor/curl/tests/unit/unit1664.c b/vendor/curl/tests/unit/unit1664.c index 528f73708f7..72ae49676bd 100644 --- a/vendor/curl/tests/unit/unit1664.c +++ b/vendor/curl/tests/unit/unit1664.c @@ -21,7 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #ifdef HAVE_NETINET_IN_H #include @@ -30,26 +30,19 @@ #include #endif -#include - -#include "curlx/strparse.h" - #include "memdebug.h" /* LAST include file */ -static CURLcode unit_setup(void) +static CURLcode t1664_setup(void) { CURLcode res = CURLE_OK; global_init(CURL_GLOBAL_ALL); return res; } -static void unit_stop(void) +static CURLcode test_unit1664(const char *arg) { - curl_global_cleanup(); -} + UNITTEST_BEGIN(t1664_setup()) -UNITTEST_START -{ static const char *wordparse[] = { "word", "word ", @@ -487,5 +480,5 @@ UNITTEST_START } } + UNITTEST_END(curl_global_cleanup()) } -UNITTEST_STOP diff --git a/vendor/curl/tests/unit/unit1979.c b/vendor/curl/tests/unit/unit1979.c index 89af6c66054..c3925d1bc0c 100644 --- a/vendor/curl/tests/unit/unit1979.c +++ b/vendor/curl/tests/unit/unit1979.c @@ -21,22 +21,14 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "http_aws_sigv4.h" -#include "dynbuf.h" -static CURLcode unit_setup(void) +static CURLcode test_unit1979(const char *arg) { - return CURLE_OK; -} - -static void unit_stop(void) -{ -} + UNITTEST_BEGIN_SIMPLE -UNITTEST_START -{ #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_AWS) struct testcase { const char *testname; @@ -139,6 +131,7 @@ UNITTEST_START buffer); curlx_dyn_free(&canonical_path); } -#endif /* !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_AWS) */ +#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_AWS */ + + UNITTEST_END_SIMPLE } -UNITTEST_STOP diff --git a/vendor/curl/tests/unit/unit1980.c b/vendor/curl/tests/unit/unit1980.c index dcc415dca51..9e38d8a678c 100644 --- a/vendor/curl/tests/unit/unit1980.c +++ b/vendor/curl/tests/unit/unit1980.c @@ -21,22 +21,14 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "http_aws_sigv4.h" -#include "dynbuf.h" -static CURLcode unit_setup(void) +static CURLcode test_unit1980(const char *arg) { - return CURLE_OK; -} - -static void unit_stop(void) -{ -} + UNITTEST_BEGIN_SIMPLE -UNITTEST_START -{ #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_AWS) struct testcase { const char *testname; @@ -110,6 +102,7 @@ UNITTEST_START buffer); curlx_dyn_free(&canonical_query); } -#endif /* !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_AWS) */ +#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_AWS */ + + UNITTEST_END_SIMPLE } -UNITTEST_STOP diff --git a/vendor/curl/tests/unit/unit2600.c b/vendor/curl/tests/unit/unit2600.c index 16f5c5ce6b4..08b2ca6fbd5 100644 --- a/vendor/curl/tests/unit/unit2600.c +++ b/vendor/curl/tests/unit/unit2600.c @@ -21,7 +21,7 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #ifdef HAVE_NETINET_IN_H #include @@ -43,29 +43,28 @@ #include "urldata.h" #include "connect.h" #include "cfilters.h" +#include "cf-ip-happy.h" #include "multiif.h" #include "select.h" #include "curl_trc.h" #include "memdebug.h" -static CURL *easy; - -static CURLcode unit_setup(void) +static CURLcode t2600_setup(CURL **easy) { CURLcode res = CURLE_OK; global_init(CURL_GLOBAL_ALL); - easy = curl_easy_init(); - if(!easy) { + *easy = curl_easy_init(); + if(!*easy) { curl_global_cleanup(); return CURLE_OUT_OF_MEMORY; } curl_global_trace("all"); - curl_easy_setopt(easy, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(*easy, CURLOPT_VERBOSE, 1L); return res; } -static void unit_stop(void) +static void t2600_stop(CURL *easy) { curl_easy_cleanup(easy); curl_global_cleanup(); @@ -75,7 +74,7 @@ struct test_case { int id; const char *url; const char *resolve_info; - unsigned char ip_version; + long ip_version; timediff_t connect_timeout_ms; timediff_t he_timeout_ms; timediff_t cf4_fail_delay_ms; @@ -104,10 +103,12 @@ struct test_result { struct ai_family_stats cf6; }; -static struct test_case *current_tc; +static const struct test_case *current_tc; static struct test_result *current_tr; +static int test_idx; struct cf_test_ctx { + int idx; int ai_family; int transport; char id[16]; @@ -146,46 +147,45 @@ static CURLcode cf_test_connect(struct Curl_cfilter *cf, } if(duration_ms) { infof(data, "%04dms: cf[%s] continuing", (int)duration_ms, ctx->id); - Curl_wait_ms(10); + curlx_wait_ms(10); } - Curl_expire(data, ctx->fail_delay_ms - duration_ms, EXPIRE_RUN_NOW); + Curl_expire(data, ctx->fail_delay_ms - duration_ms, EXPIRE_TIMEOUT); return CURLE_OK; } -static void cf_test_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) +static CURLcode cf_test_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { + struct cf_test_ctx *ctx = cf->ctx; /* just for testing, give one socket with events back */ - (void)cf; - Curl_pollset_set(data, ps, 1, TRUE, TRUE); + return Curl_pollset_set(data, ps, ctx->idx, TRUE, TRUE); } -static struct Curl_cftype cft_test = { - "TEST", - CF_TYPE_IP_CONNECT, - CURL_LOG_LVL_NONE, - cf_test_destroy, - cf_test_connect, - Curl_cf_def_close, - Curl_cf_def_shutdown, - Curl_cf_def_get_host, - cf_test_adjust_pollset, - 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_test_create(struct Curl_cfilter **pcf, struct Curl_easy *data, struct connectdata *conn, const struct Curl_addrinfo *ai, int transport) { + static const struct Curl_cftype cft_test = { + "TEST", + CF_TYPE_IP_CONNECT, + CURL_LOG_LVL_NONE, + cf_test_destroy, + cf_test_connect, + Curl_cf_def_close, + Curl_cf_def_shutdown, + cf_test_adjust_pollset, + 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, + }; + struct cf_test_ctx *ctx = NULL; struct Curl_cfilter *cf = NULL; timediff_t created_at; @@ -198,6 +198,7 @@ static CURLcode cf_test_create(struct Curl_cfilter **pcf, result = CURLE_OUT_OF_MEMORY; goto out; } + ctx->idx = test_idx++; ctx->ai_family = ai->ai_family; ctx->transport = transport; ctx->started = curlx_now(); @@ -227,7 +228,7 @@ static CURLcode cf_test_create(struct Curl_cfilter **pcf, if(result) goto out; - Curl_expire(data, ctx->fail_delay_ms, EXPIRE_RUN_NOW); + Curl_expire(data, ctx->fail_delay_ms, EXPIRE_TIMEOUT); out: *pcf = (!result) ? cf : NULL; @@ -238,7 +239,7 @@ static CURLcode cf_test_create(struct Curl_cfilter **pcf, return result; } -static void check_result(struct test_case *tc, +static void check_result(const struct test_case *tc, struct test_result *tr) { char msg[256]; @@ -301,7 +302,7 @@ static void check_result(struct test_case *tc, } } -static void test_connect(struct test_case *tc) +static void test_connect(CURL *easy, const struct test_case *tc) { struct test_result tr; struct curl_slist *list = NULL; @@ -313,7 +314,7 @@ static void test_connect(struct test_case *tc) list = curl_slist_append(NULL, tc->resolve_info); fail_unless(list, "error allocating resolve list entry"); curl_easy_setopt(easy, CURLOPT_RESOLVE, list); - curl_easy_setopt(easy, CURLOPT_IPRESOLVE, (long)tc->ip_version); + curl_easy_setopt(easy, CURLOPT_IPRESOLVE, tc->ip_version); curl_easy_setopt(easy, CURLOPT_CONNECTTIMEOUT_MS, (long)tc->connect_timeout_ms); curl_easy_setopt(easy, CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, @@ -355,46 +356,54 @@ static void test_connect(struct test_case *tc) #define TC_TMOT 90000 /* 90 sec max test duration */ #define CNCT_TMOT 60000 /* 60sec connect timeout */ -static struct test_case TEST_CASES[] = { - /* TIMEOUT_MS, FAIL_MS CREATED DURATION Result, HE_PREF */ - /* CNCT HE v4 v6 v4 v6 MIN MAX */ - { 1, TURL, "test.com:123:192.0.2.1", CURL_IPRESOLVE_WHATEVER, - CNCT_TMOT, 150, 200, 200, 1, 0, 200, TC_TMOT, R_FAIL, NULL }, - /* 1 ipv4, fails after ~200ms, reports COULDNT_CONNECT */ - { 2, TURL, "test.com:123:192.0.2.1,192.0.2.2", CURL_IPRESOLVE_WHATEVER, - CNCT_TMOT, 150, 200, 200, 2, 0, 400, TC_TMOT, R_FAIL, NULL }, - /* 2 ipv4, fails after ~400ms, reports COULDNT_CONNECT */ +static CURLcode test_unit2600(const char *arg) +{ + CURL *easy; + + UNITTEST_BEGIN(t2600_setup(&easy)) + + static const struct test_case TEST_CASES[] = { + /* TIMEOUT_MS, FAIL_MS CREATED DURATION Result, HE_PREF */ + /* CNCT HE v4 v6 v4 v6 MIN MAX */ + { 1, TURL, "test.com:123:192.0.2.1", CURL_IPRESOLVE_WHATEVER, + CNCT_TMOT, 150, 250, 250, 1, 0, 200, TC_TMOT, R_FAIL, NULL }, + /* 1 ipv4, fails after ~200ms, reports COULDNT_CONNECT */ + { 2, TURL, "test.com:123:192.0.2.1,192.0.2.2", CURL_IPRESOLVE_WHATEVER, + CNCT_TMOT, 150, 250, 250, 2, 0, 400, TC_TMOT, R_FAIL, NULL }, + /* 2 ipv4, fails after ~400ms, reports COULDNT_CONNECT */ #ifdef USE_IPV6 - { 3, TURL, "test.com:123:::1", CURL_IPRESOLVE_WHATEVER, - CNCT_TMOT, 150, 200, 200, 0, 1, 200, TC_TMOT, R_FAIL, NULL }, - /* 1 ipv6, fails after ~200ms, reports COULDNT_CONNECT */ - { 4, TURL, "test.com:123:::1,::2", CURL_IPRESOLVE_WHATEVER, - CNCT_TMOT, 150, 200, 200, 0, 2, 400, TC_TMOT, R_FAIL, NULL }, - /* 2 ipv6, fails after ~400ms, reports COULDNT_CONNECT */ - - { 5, TURL, "test.com:123:192.0.2.1,::1", CURL_IPRESOLVE_WHATEVER, - CNCT_TMOT, 150, 200, 200, 1, 1, 350, TC_TMOT, R_FAIL, "v6" }, - /* mixed ip4+6, v6 always first, v4 kicks in on HE, fails after ~350ms */ - { 6, TURL, "test.com:123:::1,192.0.2.1", CURL_IPRESOLVE_WHATEVER, - CNCT_TMOT, 150, 200, 200, 1, 1, 350, TC_TMOT, R_FAIL, "v6" }, - /* mixed ip6+4, v6 starts, v4 never starts due to high HE, TIMEOUT */ - { 7, TURL, "test.com:123:192.0.2.1,::1", CURL_IPRESOLVE_V4, - CNCT_TMOT, 150, 500, 500, 1, 0, 400, TC_TMOT, R_FAIL, NULL }, - /* mixed ip4+6, but only use v4, check it uses full connect timeout, - although another address of the 'wrong' family is available */ - { 8, TURL, "test.com:123:::1,192.0.2.1", CURL_IPRESOLVE_V6, - CNCT_TMOT, 150, 500, 500, 0, 1, 400, TC_TMOT, R_FAIL, NULL }, - /* mixed ip4+6, but only use v6, check it uses full connect timeout, - although another address of the 'wrong' family is available */ -#endif -}; + { 3, TURL, "test.com:123:::1", CURL_IPRESOLVE_WHATEVER, + CNCT_TMOT, 150, 250, 250, 0, 1, 200, TC_TMOT, R_FAIL, NULL }, + /* 1 ipv6, fails after ~200ms, reports COULDNT_CONNECT */ + { 4, TURL, "test.com:123:::1,::2", CURL_IPRESOLVE_WHATEVER, + CNCT_TMOT, 150, 250, 250, 0, 2, 400, TC_TMOT, R_FAIL, NULL }, + /* 2 ipv6, fails after ~400ms, reports COULDNT_CONNECT */ + { 5, TURL, "test.com:123:192.0.2.1,::1", CURL_IPRESOLVE_WHATEVER, + CNCT_TMOT, 150, 250, 250, 1, 1, 350, TC_TMOT, R_FAIL, "v6" }, + /* mixed ip4+6, v6 always first, v4 kicks in on HE, fails after ~350ms */ + { 6, TURL, "test.com:123:::1,192.0.2.1", CURL_IPRESOLVE_WHATEVER, + CNCT_TMOT, 150, 250, 250, 1, 1, 350, TC_TMOT, R_FAIL, "v6" }, + /* mixed ip6+4, v6 starts, v4 never starts due to high HE, TIMEOUT */ + { 7, TURL, "test.com:123:192.0.2.1,::1", CURL_IPRESOLVE_V4, + CNCT_TMOT, 150, 500, 500, 1, 0, 400, TC_TMOT, R_FAIL, NULL }, + /* mixed ip4+6, but only use v4, check it uses full connect timeout, + although another address of the 'wrong' family is available */ + { 8, TURL, "test.com:123:::1,192.0.2.1", CURL_IPRESOLVE_V6, + CNCT_TMOT, 150, 500, 500, 0, 1, 400, TC_TMOT, R_FAIL, NULL }, + /* mixed ip4+6, but only use v6, check it uses full connect timeout, + although another address of the 'wrong' family is available */ + { 9, TURL, "test.com:123:::1,192.0.2.1,::2,::3", CURL_IPRESOLVE_WHATEVER, + CNCT_TMOT, 50, 400, 400, 1, 3, 550, TC_TMOT, R_FAIL, NULL }, + /* 1 v4, 3 v6, fails after (3*HE)+400ms, ~550ms, COULDNT_CONNECT */ -UNITTEST_START +#endif + }; size_t i; for(i = 0; i < CURL_ARRAYSIZE(TEST_CASES); ++i) { - test_connect(&TEST_CASES[i]); + test_connect(easy, &TEST_CASES[i]); } -UNITTEST_STOP + UNITTEST_END(t2600_stop(easy)) +} diff --git a/vendor/curl/tests/unit/unit2601.c b/vendor/curl/tests/unit/unit2601.c index 9fd8d56aebb..aadd69fc120 100644 --- a/vendor/curl/tests/unit/unit2601.c +++ b/vendor/curl/tests/unit/unit2601.c @@ -21,22 +21,12 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "urldata.h" #include "bufq.h" #include "curl_trc.h" -static CURLcode unit_setup(void) -{ - CURLcode res = CURLE_OK; - return res; -} - -static void unit_stop(void) -{ -} - static const char *tail_err(struct bufq *q) { struct buf_chunk *chunk; @@ -86,17 +76,18 @@ static void dump_bufq(struct bufq *q, const char *msg) curl_mfprintf(stderr, "- spares: %zu\n", n); } -static unsigned char test_data[32*1024]; - static void check_bufq(size_t pool_spares, size_t chunk_size, size_t max_chunks, size_t wsize, size_t rsize, int opts) { + static unsigned char test_data[32*1024]; + struct bufq q; struct bufc_pool pool; size_t max_len = chunk_size * max_chunks; CURLcode result; - ssize_t n, i; + ssize_t i; + size_t n2; size_t nwritten, nread; if(pool_spares > 0) { @@ -114,18 +105,17 @@ static void check_bufq(size_t pool_spares, fail_unless(q.spare == NULL, "init: spare not NULL"); fail_unless(Curl_bufq_len(&q) == 0, "init: bufq length != 0"); - n = Curl_bufq_write(&q, test_data, wsize, &result); - fail_unless(n >= 0, "write: negative size returned"); - fail_unless((size_t)n <= wsize, "write: wrong size returned"); + result = Curl_bufq_write(&q, test_data, wsize, &n2); + fail_unless(n2 <= wsize, "write: wrong size returned"); fail_unless(result == CURLE_OK, "write: wrong result returned"); /* write empty bufq full */ nwritten = 0; Curl_bufq_reset(&q); while(!Curl_bufq_is_full(&q)) { - n = Curl_bufq_write(&q, test_data, wsize, &result); - if(n >= 0) { - nwritten += (size_t)n; + result = Curl_bufq_write(&q, test_data, wsize, &n2); + if(!result) { + nwritten += n2; } else if(result != CURLE_AGAIN) { fail_unless(result == CURLE_AGAIN, "write-loop: unexpected result"); @@ -142,9 +132,9 @@ static void check_bufq(size_t pool_spares, /* read full bufq empty */ nread = 0; while(!Curl_bufq_is_empty(&q)) { - n = Curl_bufq_read(&q, test_data, rsize, &result); - if(n >= 0) { - nread += (size_t)n; + result = Curl_bufq_read(&q, test_data, rsize, &n2); + if(!result) { + nread += n2; } else if(result != CURLE_AGAIN) { fail_unless(result == CURLE_AGAIN, "read-loop: unexpected result"); @@ -163,13 +153,13 @@ static void check_bufq(size_t pool_spares, } for(i = 0; i < 1000; ++i) { - n = Curl_bufq_write(&q, test_data, wsize, &result); - if(n < 0 && result != CURLE_AGAIN) { + result = Curl_bufq_write(&q, test_data, wsize, &n2); + if(result && result != CURLE_AGAIN) { fail_unless(result == CURLE_AGAIN, "rw-loop: unexpected write result"); break; } - n = Curl_bufq_read(&q, test_data, rsize, &result); - if(n < 0 && result != CURLE_AGAIN) { + result = Curl_bufq_read(&q, test_data, rsize, &n2); + if(result && result != CURLE_AGAIN) { fail_unless(result == CURLE_AGAIN, "rw-loop: unexpected read result"); break; } @@ -180,12 +170,12 @@ static void check_bufq(size_t pool_spares, Curl_bufq_init2(&q, chunk_size, max_chunks, (opts|BUFQ_OPT_SOFT_LIMIT)); nwritten = 0; while(!Curl_bufq_is_full(&q)) { - n = Curl_bufq_write(&q, test_data, wsize, &result); - if(n < 0 || (size_t)n != wsize) { - fail_unless(n > 0 && (size_t)n == wsize, "write should be complete"); + result = Curl_bufq_write(&q, test_data, wsize, &n2); + if(result || n2 != wsize) { + fail_unless(!result && n2 == wsize, "write should be complete"); break; } - nwritten += (size_t)n; + nwritten += n2; } if(nwritten < max_len) { curl_mfprintf(stderr, "%zu bytes written, but max_len=%zu\n", @@ -194,71 +184,39 @@ static void check_bufq(size_t pool_spares, fail_if(TRUE, "write: bufq full but nwritten wrong"); } /* do one more write on a full bufq, should work */ - n = Curl_bufq_write(&q, test_data, wsize, &result); - fail_unless(n > 0 && (size_t)n == wsize, "write should be complete"); - nwritten += (size_t)n; + result = Curl_bufq_write(&q, test_data, wsize, &n2); + fail_unless(!result && n2 == wsize, "write should be complete"); + nwritten += n2; /* see that we get all out again */ nread = 0; while(!Curl_bufq_is_empty(&q)) { - n = Curl_bufq_read(&q, test_data, rsize, &result); - if(n <= 0) { - fail_unless(n > 0, "read-loop: unexpected fail"); + result = Curl_bufq_read(&q, test_data, rsize, &n2); + if(result) { + fail_unless(result, "read-loop: unexpected fail"); break; } - nread += (size_t)n; + nread += n2; } fail_unless(nread == nwritten, "did not get the same out as put in"); - /* CHECK bufq_unwrite: write a string repeatedly into the second chunk. - * bufq_unwrite() 1 byte. Read strings again and check for content. - * We had a bug that unwrite used the head chunk instead of tail, which - * did corrupt the read values. */ - if(TRUE) { - const unsigned char buf[] = "0123456789--"; - size_t roffset; - Curl_bufq_reset(&q); - while(Curl_bufq_len(&q) < chunk_size) { - n = Curl_bufq_write(&q, buf, sizeof(buf), &result); - fail_unless(n > 0 && (size_t)n == sizeof(buf), "write incomplete"); - if(result) - break; - } - result = Curl_bufq_unwrite(&q, 1); - roffset = 0; - while(!Curl_bufq_is_empty(&q)) { - unsigned char rbuf[sizeof(buf)]; - n = Curl_bufq_read(&q, rbuf, sizeof(rbuf), &result); - fail_unless(n > 0, "read should work"); - if(result) - break; - if(n != sizeof(rbuf)) { - fail_unless(Curl_bufq_is_empty(&q), "should be last read"); - } - if(memcmp(buf, rbuf, n)) { - curl_mfprintf(stderr, "at offset %zu expected '%.*s', got '%.*s'\n", - roffset, (int)n, buf, (int)n, rbuf); - fail("read buf content wrong"); - } - roffset += n; - } - Curl_bufq_reset(&q); - } - dump_bufq(&q, "at end of test"); Curl_bufq_free(&q); if(pool_spares > 0) Curl_bufcp_free(&pool); } -UNITTEST_START +static CURLcode test_unit2601(const char *arg) +{ + UNITTEST_BEGIN_SIMPLE + struct bufq q; - ssize_t n; + size_t n; CURLcode result; unsigned char buf[16*1024]; Curl_bufq_init(&q, 8*1024, 12); - n = Curl_bufq_read(&q, buf, 128, &result); - fail_unless(n < 0 && result == CURLE_AGAIN, "read empty fail"); + result = Curl_bufq_read(&q, buf, 128, &n); + fail_unless(result && result == CURLE_AGAIN, "read empty fail"); Curl_bufq_free(&q); check_bufq(0, 1024, 4, 128, 128, BUFQ_OPT_NONE); @@ -278,4 +236,5 @@ UNITTEST_START check_bufq(8, 8000, 10, 1234, 1234, BUFQ_OPT_NONE); check_bufq(8, 1024, 4, 129, 127, BUFQ_OPT_NO_SPARES); -UNITTEST_STOP + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/unit2602.c b/vendor/curl/tests/unit/unit2602.c index d730a987407..f031132986c 100644 --- a/vendor/curl/tests/unit/unit2602.c +++ b/vendor/curl/tests/unit/unit2602.c @@ -21,24 +21,15 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "urldata.h" -#include "dynbuf.h" #include "dynhds.h" #include "curl_trc.h" -static CURLcode unit_setup(void) +static CURLcode test_unit2602(const char *arg) { - return CURLE_OK; -} - -static void unit_stop(void) -{ -} - - -UNITTEST_START + UNITTEST_BEGIN_SIMPLE struct dynhds hds; struct dynbuf dbuf; @@ -145,4 +136,5 @@ UNITTEST_START Curl_dynhds_free(&hds); -UNITTEST_STOP + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/unit2603.c b/vendor/curl/tests/unit/unit2603.c index 82d56a5a793..5915555f8b0 100644 --- a/vendor/curl/tests/unit/unit2603.c +++ b/vendor/curl/tests/unit/unit2603.c @@ -21,34 +21,14 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "urldata.h" #include "http.h" #include "http1.h" #include "curl_trc.h" -static CURLcode unit_setup(void) -{ - return CURLE_OK; -} - -static void unit_stop(void) -{ -} - #ifndef CURL_DISABLE_HTTP -struct tcase { - const char **input; - const char *default_scheme; - const char *method; - const char *scheme; - const char *authority; - const char *path; - size_t header_count; - size_t input_remain; -}; - static void check_eq(const char *s, const char *exp_s, const char *name) { if(s && exp_s) { @@ -68,7 +48,18 @@ static void check_eq(const char *s, const char *exp_s, const char *name) } } -static void parse_success(struct tcase *t) +struct tcase { + const char **input; + const char *default_scheme; + const char *method; + const char *scheme; + const char *authority; + const char *path; + size_t header_count; + size_t input_remain; +}; + +static void parse_success(const struct tcase *t) { struct h1_req_parser p; const char *buf; @@ -119,70 +110,72 @@ static void parse_success(struct tcase *t) Curl_h1_req_parse_free(&p); } - -static const char *T1_INPUT[] = { - "GET /path HTTP/1.1\r\nHost: test.curl.se\r\n\r\n", - NULL, -}; -static struct tcase TEST1a = { - T1_INPUT, NULL, "GET", NULL, NULL, "/path", 1, 0 -}; -static struct tcase TEST1b = { - T1_INPUT, "https", "GET", "https", NULL, "/path", 1, 0 -}; - -static const char *T2_INPUT[] = { - "GET /path HTT", - "P/1.1\r\nHost: te", - "st.curl.se\r\n\r", - "\n12345678", - NULL, -}; -static struct tcase TEST2 = { - T2_INPUT, NULL, "GET", NULL, NULL, "/path", 1, 8 -}; - -static const char *T3_INPUT[] = { - "GET ftp://ftp.curl.se/xxx?a=2 HTTP/1.1\r\nContent-Length: 0\r", - "\nUser-Agent: xxx\r\n\r\n", - NULL, -}; -static struct tcase TEST3a = { - T3_INPUT, NULL, "GET", "ftp", "ftp.curl.se", "/xxx?a=2", 2, 0 -}; - -static const char *T4_INPUT[] = { - "CONNECT ftp.curl.se:123 HTTP/1.1\r\nContent-Length: 0\r\n", - "User-Agent: xxx\r\n", - "nothing: \r\n\r\n\n\n", - NULL, -}; -static struct tcase TEST4a = { - T4_INPUT, NULL, "CONNECT", NULL, "ftp.curl.se:123", NULL, 3, 2 -}; - -static const char *T5_INPUT[] = { - "OPTIONS * HTTP/1.1\r\nContent-Length: 0\r\nBlabla: xxx.yyy\r", - "\n\tzzzzzz\r\n\r\n", - "123", - NULL, -}; -static struct tcase TEST5a = { - T5_INPUT, NULL, "OPTIONS", NULL, NULL, "*", 2, 3 -}; - -static const char *T6_INPUT[] = { - "PUT /path HTTP/1.1\nHost: test.curl.se\n\n123", - NULL, -}; -static struct tcase TEST6a = { - T6_INPUT, NULL, "PUT", NULL, NULL, "/path", 1, 3 -}; #endif -UNITTEST_START +static CURLcode test_unit2603(const char *arg) +{ + UNITTEST_BEGIN_SIMPLE #ifndef CURL_DISABLE_HTTP + static const char *T1_INPUT[] = { + "GET /path HTTP/1.1\r\nHost: test.curl.se\r\n\r\n", + NULL, + }; + static const struct tcase TEST1a = { + T1_INPUT, NULL, "GET", NULL, NULL, "/path", 1, 0 + }; + static const struct tcase TEST1b = { + T1_INPUT, "https", "GET", "https", NULL, "/path", 1, 0 + }; + + static const char *T2_INPUT[] = { + "GET /path HTT", + "P/1.1\r\nHost: te", + "st.curl.se\r\n\r", + "\n12345678", + NULL, + }; + static const struct tcase TEST2 = { + T2_INPUT, NULL, "GET", NULL, NULL, "/path", 1, 8 + }; + + static const char *T3_INPUT[] = { + "GET ftp://ftp.curl.se/xxx?a=2 HTTP/1.1\r\nContent-Length: 0\r", + "\nUser-Agent: xxx\r\n\r\n", + NULL, + }; + static const struct tcase TEST3a = { + T3_INPUT, NULL, "GET", "ftp", "ftp.curl.se", "/xxx?a=2", 2, 0 + }; + + static const char *T4_INPUT[] = { + "CONNECT ftp.curl.se:123 HTTP/1.1\r\nContent-Length: 0\r\n", + "User-Agent: xxx\r\n", + "nothing: \r\n\r\n\n\n", + NULL, + }; + static const struct tcase TEST4a = { + T4_INPUT, NULL, "CONNECT", NULL, "ftp.curl.se:123", NULL, 3, 2 + }; + + static const char *T5_INPUT[] = { + "OPTIONS * HTTP/1.1\r\nContent-Length: 0\r\nBlabla: xxx.yyy\r", + "\n\tzzzzzz\r\n\r\n", + "123", + NULL, + }; + static const struct tcase TEST5a = { + T5_INPUT, NULL, "OPTIONS", NULL, NULL, "*", 2, 3 + }; + + static const char *T6_INPUT[] = { + "PUT /path HTTP/1.1\nHost: test.curl.se\n\n123", + NULL, + }; + static const struct tcase TEST6a = { + T6_INPUT, NULL, "PUT", NULL, NULL, "/path", 1, 3 + }; + parse_success(&TEST1a); parse_success(&TEST1b); parse_success(&TEST2); @@ -192,4 +185,5 @@ UNITTEST_START parse_success(&TEST6a); #endif -UNITTEST_STOP + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/unit2604.c b/vendor/curl/tests/unit/unit2604.c index 16330e4f238..9111edafb88 100644 --- a/vendor/curl/tests/unit/unit2604.c +++ b/vendor/curl/tests/unit/unit2604.c @@ -21,31 +21,24 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "vssh/curl_path.h" #include "memdebug.h" -static CURLcode unit_setup(void) +static CURLcode test_unit2604(const char *arg) { - return CURLE_OK; -} - -static void unit_stop(void) -{ -} + UNITTEST_BEGIN_SIMPLE +#ifdef USE_SSH -struct set { - const char *cp; - const char *expect; /* the returned content */ - const char *next; /* what cp points to after the call */ - const char *home; - CURLcode result; -}; + struct set { + const char *cp; + const char *expect; /* the returned content */ + const char *next; /* what cp points to after the call */ + const char *home; + CURLcode result; + }; -UNITTEST_START -#ifdef USE_SSH -{ #if defined(CURL_GNUC_DIAG) || defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Woverlength-strings" @@ -56,7 +49,7 @@ UNITTEST_START /* 540 a's */ #define SA540 SA60 SA60 SA60 SA60 SA60 SA60 SA60 SA60 SA60 int i; - size_t too_long = 90720; + const size_t too_long = 90720; struct set list[] = { { "-too-long-", "", "", "", CURLE_TOO_LARGE}, { SA540 " c", SA540, "c", "/", CURLE_OK}, @@ -79,16 +72,16 @@ UNITTEST_START }; #if defined(CURL_GNUC_DIAG) || defined(__clang__) -#pragma GCC diagnostic warning "-Woverlength-strings" +#pragma GCC diagnostic pop #endif - list[0].cp = calloc(1, too_long + 1); - fail_unless(list[0].cp, "could not alloc too long value"); - memset(CURL_UNCONST(list[0].cp), 'a', too_long); + char *cp0 = calloc(1, too_long + 1); + fail_unless(cp0, "could not alloc too long value"); + memset(cp0, 'a', too_long); for(i = 0; list[i].home; i++) { char *path; - const char *cp = list[i].cp; + const char *cp = i == 0 ? cp0 : list[i].cp; CURLcode result = Curl_get_pathname(&cp, &path, list[i].home); printf("%u - Curl_get_pathname(\"%s\", ... \"%s\") == %u\n", i, list[i].cp, list[i].home, list[i].result); @@ -108,16 +101,12 @@ UNITTEST_START unitfail++; } curl_free(path); - } } - free(CURL_UNCONST(list[0].cp)); -} -#if defined(CURL_GNUC_DIAG) || defined(__clang__) -#pragma GCC diagnostic pop -#endif + free(cp0); #endif -UNITTEST_STOP + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/unit3200.c b/vendor/curl/tests/unit/unit3200.c index 60e34ac337c..023bf0ddb6f 100644 --- a/vendor/curl/tests/unit/unit3200.c +++ b/vendor/curl/tests/unit/unit3200.c @@ -21,72 +21,63 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "curl_get_line.h" #include "memdebug.h" +static CURLcode test_unit3200(const char *arg) +{ + UNITTEST_BEGIN_SIMPLE + #if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_ALTSVC) || \ !defined(CURL_DISABLE_HSTS) || !defined(CURL_DISABLE_NETRC) -/* The test XML does not supply a way to write files without newlines - * so we write our own - */ +#if defined(CURL_GNUC_DIAG) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Woverlength-strings" +#endif + + /* The test XML does not supply a way to write files without newlines + * so we write our own + */ #define C64 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" #define C256 C64 C64 C64 C64 #define C1024 C256 C256 C256 C256 #define C4096 C1024 C1024 C1024 C1024 -static CURLcode unit_setup(void) -{ - return CURLE_OK; -} + static const char *filecontents[] = { + /* Both should be read */ + "LINE1\n" + "LINE2 NEWLINE\n", -static CURLcode unit_stop(void) -{ - return CURLE_OK; -} + /* Both should be read */ + "LINE1\n" + "LINE2 NONEWLINE", -#if defined(CURL_GNUC_DIAG) || defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Woverlength-strings" -#endif - -#define NUMTESTS 6 -static const char *filecontents[] = { - /* Both should be read */ - "LINE1\n" - "LINE2 NEWLINE\n", - - /* Both should be read */ - "LINE1\n" - "LINE2 NONEWLINE", - - /* Only first should be read */ - "LINE1\n" - C4096, + /* Only first should be read */ + "LINE1\n" + C4096, - /* First line should be read */ - "LINE1\n" - C4096 "SOME EXTRA TEXT", + /* First line should be read */ + "LINE1\n" + C4096 "SOME EXTRA TEXT", - /* Only first should be read */ - "LINE1\n" - C4096 "SOME EXTRA TEXT\n" - "LINE3\n", + /* Only first should be read */ + "LINE1\n" + C4096 "SOME EXTRA TEXT\n" + "LINE3\n", - "LINE1\x1aTEST" -}; + "LINE1\x1aTEST" + }; #if defined(CURL_GNUC_DIAG) || defined(__clang__) -#pragma GCC diagnostic warning "-Woverlength-strings" +#pragma GCC diagnostic pop #endif - -UNITTEST_START size_t i; int rc = 0; - for(i = 0; i < NUMTESTS; i++) { + for(i = 0; i < CURL_ARRAYSIZE(filecontents); i++) { FILE *fp; struct dynbuf buf; size_t len = 4096; @@ -171,21 +162,8 @@ UNITTEST_START curl_mfprintf(stderr, "OK\n"); } return (CURLcode)rc; -UNITTEST_STOP -#if defined(CURL_GNUC_DIAG) || defined(__clang__) -#pragma GCC diagnostic pop #endif -#else -static CURLcode unit_setup(void) -{ - return CURLE_OK; -} -static void unit_stop(void) -{ + UNITTEST_END_SIMPLE } -UNITTEST_START -UNITTEST_STOP - -#endif diff --git a/vendor/curl/tests/unit/unit3205.c b/vendor/curl/tests/unit/unit3205.c index 95e169d5b47..bb42e9e0c62 100644 --- a/vendor/curl/tests/unit/unit3205.c +++ b/vendor/curl/tests/unit/unit3205.c @@ -21,673 +21,496 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "vtls/cipher_suite.h" -static CURLcode unit_setup(void) +static CURLcode test_unit3205(const char *arg) { - return CURLE_OK; -} + UNITTEST_BEGIN_SIMPLE -static void unit_stop(void) -{ -} +#if defined(USE_MBEDTLS) || defined(USE_RUSTLS) -#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || \ - defined(USE_BEARSSL) || defined(USE_RUSTLS) + struct test_cs_entry { + uint16_t id; + const char *rfc; + const char *openssl; + }; -struct test_cs_entry { - uint16_t id; - const char *rfc; - const char *openssl; -}; -static const struct test_cs_entry test_cs_list[] = { -#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_RUSTLS) - { 0x1301, "TLS_AES_128_GCM_SHA256", - NULL }, - { 0x1302, "TLS_AES_256_GCM_SHA384", - NULL }, - { 0x1303, "TLS_CHACHA20_POLY1305_SHA256", - NULL }, - { 0x1304, "TLS_AES_128_CCM_SHA256", - NULL }, - { 0x1305, "TLS_AES_128_CCM_8_SHA256", - NULL }, -#endif - { 0xC02B, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", - "ECDHE-ECDSA-AES128-GCM-SHA256" }, - { 0xC02C, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", - "ECDHE-ECDSA-AES256-GCM-SHA384" }, - { 0xC02F, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "ECDHE-RSA-AES128-GCM-SHA256" }, - { 0xC030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", - "ECDHE-RSA-AES256-GCM-SHA384" }, - { 0xCCA8, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", - "ECDHE-RSA-CHACHA20-POLY1305" }, - { 0xCCA9, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", - "ECDHE-ECDSA-CHACHA20-POLY1305" }, -#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_BEARSSL) - { 0x002F, "TLS_RSA_WITH_AES_128_CBC_SHA", - "AES128-SHA" }, - { 0x0035, "TLS_RSA_WITH_AES_256_CBC_SHA", - "AES256-SHA" }, - { 0x003C, "TLS_RSA_WITH_AES_128_CBC_SHA256", - "AES128-SHA256" }, - { 0x003D, "TLS_RSA_WITH_AES_256_CBC_SHA256", - "AES256-SHA256" }, - { 0x009C, "TLS_RSA_WITH_AES_128_GCM_SHA256", - "AES128-GCM-SHA256" }, - { 0x009D, "TLS_RSA_WITH_AES_256_GCM_SHA384", - "AES256-GCM-SHA384" }, - { 0xC004, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", - "ECDH-ECDSA-AES128-SHA" }, - { 0xC005, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", - "ECDH-ECDSA-AES256-SHA" }, - { 0xC009, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", - "ECDHE-ECDSA-AES128-SHA" }, - { 0xC00A, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", - "ECDHE-ECDSA-AES256-SHA" }, - { 0xC00E, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", - "ECDH-RSA-AES128-SHA" }, - { 0xC00F, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", - "ECDH-RSA-AES256-SHA" }, - { 0xC013, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", - "ECDHE-RSA-AES128-SHA" }, - { 0xC014, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", - "ECDHE-RSA-AES256-SHA" }, - { 0xC023, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", - "ECDHE-ECDSA-AES128-SHA256" }, - { 0xC024, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", - "ECDHE-ECDSA-AES256-SHA384" }, - { 0xC025, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", - "ECDH-ECDSA-AES128-SHA256" }, - { 0xC026, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", - "ECDH-ECDSA-AES256-SHA384" }, - { 0xC027, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", - "ECDHE-RSA-AES128-SHA256" }, - { 0xC028, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", - "ECDHE-RSA-AES256-SHA384" }, - { 0xC029, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", - "ECDH-RSA-AES128-SHA256" }, - { 0xC02A, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", - "ECDH-RSA-AES256-SHA384" }, - { 0xC02D, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", - "ECDH-ECDSA-AES128-GCM-SHA256" }, - { 0xC02E, "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", - "ECDH-ECDSA-AES256-GCM-SHA384" }, - { 0xC031, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", - "ECDH-RSA-AES128-GCM-SHA256" }, - { 0xC032, "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", - "ECDH-RSA-AES256-GCM-SHA384" }, -#endif -#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) - { 0x0001, "TLS_RSA_WITH_NULL_MD5", - "NULL-MD5" }, - { 0x0002, "TLS_RSA_WITH_NULL_SHA", - "NULL-SHA" }, - { 0x002C, "TLS_PSK_WITH_NULL_SHA", - "PSK-NULL-SHA" }, - { 0x002D, "TLS_DHE_PSK_WITH_NULL_SHA", - "DHE-PSK-NULL-SHA" }, - { 0x002E, "TLS_RSA_PSK_WITH_NULL_SHA", - "RSA-PSK-NULL-SHA" }, - { 0x0033, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", - "DHE-RSA-AES128-SHA" }, - { 0x0039, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", - "DHE-RSA-AES256-SHA" }, - { 0x003B, "TLS_RSA_WITH_NULL_SHA256", - "NULL-SHA256" }, - { 0x0067, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", - "DHE-RSA-AES128-SHA256" }, - { 0x006B, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", - "DHE-RSA-AES256-SHA256" }, - { 0x008C, "TLS_PSK_WITH_AES_128_CBC_SHA", - "PSK-AES128-CBC-SHA" }, - { 0x008D, "TLS_PSK_WITH_AES_256_CBC_SHA", - "PSK-AES256-CBC-SHA" }, - { 0x0090, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA", - "DHE-PSK-AES128-CBC-SHA" }, - { 0x0091, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA", - "DHE-PSK-AES256-CBC-SHA" }, - { 0x0094, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA", - "RSA-PSK-AES128-CBC-SHA" }, - { 0x0095, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA", - "RSA-PSK-AES256-CBC-SHA" }, - { 0x009E, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", - "DHE-RSA-AES128-GCM-SHA256" }, - { 0x009F, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", - "DHE-RSA-AES256-GCM-SHA384" }, - { 0x00A8, "TLS_PSK_WITH_AES_128_GCM_SHA256", - "PSK-AES128-GCM-SHA256" }, - { 0x00A9, "TLS_PSK_WITH_AES_256_GCM_SHA384", - "PSK-AES256-GCM-SHA384" }, - { 0x00AA, "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", - "DHE-PSK-AES128-GCM-SHA256" }, - { 0x00AB, "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", - "DHE-PSK-AES256-GCM-SHA384" }, - { 0x00AC, "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256", - "RSA-PSK-AES128-GCM-SHA256" }, - { 0x00AD, "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384", - "RSA-PSK-AES256-GCM-SHA384" }, - { 0x00AE, "TLS_PSK_WITH_AES_128_CBC_SHA256", - "PSK-AES128-CBC-SHA256" }, - { 0x00AF, "TLS_PSK_WITH_AES_256_CBC_SHA384", - "PSK-AES256-CBC-SHA384" }, - { 0x00B0, "TLS_PSK_WITH_NULL_SHA256", - "PSK-NULL-SHA256" }, - { 0x00B1, "TLS_PSK_WITH_NULL_SHA384", - "PSK-NULL-SHA384" }, - { 0x00B2, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256", - "DHE-PSK-AES128-CBC-SHA256" }, - { 0x00B3, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384", - "DHE-PSK-AES256-CBC-SHA384" }, - { 0x00B4, "TLS_DHE_PSK_WITH_NULL_SHA256", - "DHE-PSK-NULL-SHA256" }, - { 0x00B5, "TLS_DHE_PSK_WITH_NULL_SHA384", - "DHE-PSK-NULL-SHA384" }, - { 0x00B6, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256", - "RSA-PSK-AES128-CBC-SHA256" }, - { 0x00B7, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384", - "RSA-PSK-AES256-CBC-SHA384" }, - { 0x00B8, "TLS_RSA_PSK_WITH_NULL_SHA256", - "RSA-PSK-NULL-SHA256" }, - { 0x00B9, "TLS_RSA_PSK_WITH_NULL_SHA384", - "RSA-PSK-NULL-SHA384" }, - { 0xC001, "TLS_ECDH_ECDSA_WITH_NULL_SHA", - "ECDH-ECDSA-NULL-SHA" }, - { 0xC006, "TLS_ECDHE_ECDSA_WITH_NULL_SHA", - "ECDHE-ECDSA-NULL-SHA" }, - { 0xC00B, "TLS_ECDH_RSA_WITH_NULL_SHA", - "ECDH-RSA-NULL-SHA" }, - { 0xC010, "TLS_ECDHE_RSA_WITH_NULL_SHA", - "ECDHE-RSA-NULL-SHA" }, - { 0xC035, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", - "ECDHE-PSK-AES128-CBC-SHA" }, - { 0xC036, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", - "ECDHE-PSK-AES256-CBC-SHA" }, - { 0xCCAB, "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256", - "PSK-CHACHA20-POLY1305" }, -#endif -#if defined(USE_SECTRANSP) || defined(USE_BEARSSL) - { 0x000A, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", - "DES-CBC3-SHA" }, - { 0xC003, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", - "ECDH-ECDSA-DES-CBC3-SHA" }, - { 0xC008, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", - "ECDHE-ECDSA-DES-CBC3-SHA" }, - { 0xC00D, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", - "ECDH-RSA-DES-CBC3-SHA" }, - { 0xC012, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", - "ECDHE-RSA-DES-CBC3-SHA" }, -#endif -#if defined(USE_MBEDTLS) || defined(USE_BEARSSL) - { 0xC09C, "TLS_RSA_WITH_AES_128_CCM", - "AES128-CCM" }, - { 0xC09D, "TLS_RSA_WITH_AES_256_CCM", - "AES256-CCM" }, - { 0xC0A0, "TLS_RSA_WITH_AES_128_CCM_8", - "AES128-CCM8" }, - { 0xC0A1, "TLS_RSA_WITH_AES_256_CCM_8", - "AES256-CCM8" }, - { 0xC0AC, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM", - "ECDHE-ECDSA-AES128-CCM" }, - { 0xC0AD, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM", - "ECDHE-ECDSA-AES256-CCM" }, - { 0xC0AE, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8", - "ECDHE-ECDSA-AES128-CCM8" }, - { 0xC0AF, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8", - "ECDHE-ECDSA-AES256-CCM8" }, -#endif -#if defined(USE_SECTRANSP) - { 0x0003, "TLS_RSA_EXPORT_WITH_RC4_40_MD5", - "EXP-RC4-MD5" }, - { 0x0004, "TLS_RSA_WITH_RC4_128_MD5", - "RC4-MD5" }, - { 0x0005, "TLS_RSA_WITH_RC4_128_SHA", - "RC4-SHA" }, - { 0x0006, "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5", - "EXP-RC2-CBC-MD5" }, - { 0x0007, "TLS_RSA_WITH_IDEA_CBC_SHA", - "IDEA-CBC-SHA" }, - { 0x0008, "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA", - "EXP-DES-CBC-SHA" }, - { 0x0009, "TLS_RSA_WITH_DES_CBC_SHA", - "DES-CBC-SHA" }, - { 0x000B, "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", - "EXP-DH-DSS-DES-CBC-SHA" }, - { 0x000C, "TLS_DH_DSS_WITH_DES_CBC_SHA", - "DH-DSS-DES-CBC-SHA" }, - { 0x000D, "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", - "DH-DSS-DES-CBC3-SHA" }, - { 0x000E, "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", - "EXP-DH-RSA-DES-CBC-SHA" }, - { 0x000F, "TLS_DH_RSA_WITH_DES_CBC_SHA", - "DH-RSA-DES-CBC-SHA" }, - { 0x0010, "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", - "DH-RSA-DES-CBC3-SHA" }, - { 0x0011, "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", - "EXP-DHE-DSS-DES-CBC-SHA" }, - { 0x0012, "TLS_DHE_DSS_WITH_DES_CBC_SHA", - "DHE-DSS-DES-CBC-SHA" }, - { 0x0013, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", - "DHE-DSS-DES-CBC3-SHA" }, - { 0x0014, "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", - "EXP-DHE-RSA-DES-CBC-SHA" }, - { 0x0015, "TLS_DHE_RSA_WITH_DES_CBC_SHA", - "DHE-RSA-DES-CBC-SHA" }, - { 0x0016, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", - "DHE-RSA-DES-CBC3-SHA" }, - { 0x0017, "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5", - "EXP-ADH-RC4-MD5" }, - { 0x0018, "TLS_DH_anon_WITH_RC4_128_MD5", - "ADH-RC4-MD5" }, - { 0x0019, "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA", - "EXP-ADH-DES-CBC-SHA" }, - { 0x001A, "TLS_DH_anon_WITH_DES_CBC_SHA", - "ADH-DES-CBC-SHA" }, - { 0x001B, "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA", - "ADH-DES-CBC3-SHA" }, - { 0x0030, "TLS_DH_DSS_WITH_AES_128_CBC_SHA", - "DH-DSS-AES128-SHA" }, - { 0x0031, "TLS_DH_RSA_WITH_AES_128_CBC_SHA", - "DH-RSA-AES128-SHA" }, - { 0x0032, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", - "DHE-DSS-AES128-SHA" }, - { 0x0034, "TLS_DH_anon_WITH_AES_128_CBC_SHA", - "ADH-AES128-SHA" }, - { 0x0036, "TLS_DH_DSS_WITH_AES_256_CBC_SHA", - "DH-DSS-AES256-SHA" }, - { 0x0037, "TLS_DH_RSA_WITH_AES_256_CBC_SHA", - "DH-RSA-AES256-SHA" }, - { 0x0038, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", - "DHE-DSS-AES256-SHA" }, - { 0x003A, "TLS_DH_anon_WITH_AES_256_CBC_SHA", - "ADH-AES256-SHA" }, - { 0x003E, "TLS_DH_DSS_WITH_AES_128_CBC_SHA256", - "DH-DSS-AES128-SHA256" }, - { 0x003F, "TLS_DH_RSA_WITH_AES_128_CBC_SHA256", - "DH-RSA-AES128-SHA256" }, - { 0x0040, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", - "DHE-DSS-AES128-SHA256" }, - { 0x0068, "TLS_DH_DSS_WITH_AES_256_CBC_SHA256", - "DH-DSS-AES256-SHA256" }, - { 0x0069, "TLS_DH_RSA_WITH_AES_256_CBC_SHA256", - "DH-RSA-AES256-SHA256" }, - { 0x006A, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", - "DHE-DSS-AES256-SHA256" }, - { 0x006C, "TLS_DH_anon_WITH_AES_128_CBC_SHA256", - "ADH-AES128-SHA256" }, - { 0x006D, "TLS_DH_anon_WITH_AES_256_CBC_SHA256", - "ADH-AES256-SHA256" }, - { 0x008A, "TLS_PSK_WITH_RC4_128_SHA", - "PSK-RC4-SHA" }, - { 0x008B, "TLS_PSK_WITH_3DES_EDE_CBC_SHA", - "PSK-3DES-EDE-CBC-SHA" }, - { 0x008E, "TLS_DHE_PSK_WITH_RC4_128_SHA", - "DHE-PSK-RC4-SHA" }, - { 0x008F, "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA", - "DHE-PSK-3DES-EDE-CBC-SHA" }, - { 0x0092, "TLS_RSA_PSK_WITH_RC4_128_SHA", - "RSA-PSK-RC4-SHA" }, - { 0x0093, "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA", - "RSA-PSK-3DES-EDE-CBC-SHA" }, - { 0x00A0, "TLS_DH_RSA_WITH_AES_128_GCM_SHA256", - "DH-RSA-AES128-GCM-SHA256" }, - { 0x00A1, "TLS_DH_RSA_WITH_AES_256_GCM_SHA384", - "DH-RSA-AES256-GCM-SHA384" }, - { 0x00A2, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", - "DHE-DSS-AES128-GCM-SHA256" }, - { 0x00A3, "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", - "DHE-DSS-AES256-GCM-SHA384" }, - { 0x00A4, "TLS_DH_DSS_WITH_AES_128_GCM_SHA256", - "DH-DSS-AES128-GCM-SHA256" }, - { 0x00A5, "TLS_DH_DSS_WITH_AES_256_GCM_SHA384", - "DH-DSS-AES256-GCM-SHA384" }, - { 0x00A6, "TLS_DH_anon_WITH_AES_128_GCM_SHA256", - "ADH-AES128-GCM-SHA256" }, - { 0x00A7, "TLS_DH_anon_WITH_AES_256_GCM_SHA384", - "ADH-AES256-GCM-SHA384" }, - { 0xC002, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA", - "ECDH-ECDSA-RC4-SHA" }, - { 0xC007, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", - "ECDHE-ECDSA-RC4-SHA" }, - { 0xC00C, "TLS_ECDH_RSA_WITH_RC4_128_SHA", - "ECDH-RSA-RC4-SHA" }, - { 0xC011, "TLS_ECDHE_RSA_WITH_RC4_128_SHA", - "ECDHE-RSA-RC4-SHA" }, - { 0xC015, "TLS_ECDH_anon_WITH_NULL_SHA", - "AECDH-NULL-SHA" }, - { 0xC016, "TLS_ECDH_anon_WITH_RC4_128_SHA", - "AECDH-RC4-SHA" }, - { 0xC017, "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", - "AECDH-DES-CBC3-SHA" }, - { 0xC018, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA", - "AECDH-AES128-SHA" }, - { 0xC019, "TLS_ECDH_anon_WITH_AES_256_CBC_SHA", - "AECDH-AES256-SHA" }, - /* Backward compatible aliases (EDH vs DHE) */ - { 0x0011, "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", - "EXP-EDH-DSS-DES-CBC-SHA" }, - { 0x0012, "TLS_DHE_DSS_WITH_DES_CBC_SHA", - "EDH-DSS-DES-CBC-SHA" }, - { 0x0013, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", - "EDH-DSS-DES-CBC3-SHA" }, - { 0x0014, "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", - "EXP-EDH-RSA-DES-CBC-SHA" }, - { 0x0015, "TLS_DHE_RSA_WITH_DES_CBC_SHA", - "EDH-RSA-DES-CBC-SHA" }, - { 0x0016, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", - "EDH-RSA-DES-CBC3-SHA" }, -#endif -#if defined(USE_MBEDTLS) - /* entries marked ns are non-"standard", they are not in OpenSSL */ - { 0x0041, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA", - "CAMELLIA128-SHA" }, - { 0x0045, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", - "DHE-RSA-CAMELLIA128-SHA" }, - { 0x0084, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", - "CAMELLIA256-SHA" }, - { 0x0088, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", - "DHE-RSA-CAMELLIA256-SHA" }, - { 0x00BA, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256", - "CAMELLIA128-SHA256" }, - { 0x00BE, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", - "DHE-RSA-CAMELLIA128-SHA256" }, - { 0x00C0, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256", - "CAMELLIA256-SHA256" }, - { 0x00C4, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", - "DHE-RSA-CAMELLIA256-SHA256" }, - { 0xC037, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", - "ECDHE-PSK-AES128-CBC-SHA256" }, - { 0xC038, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", - "ECDHE-PSK-AES256-CBC-SHA384" }, - { 0xC039, "TLS_ECDHE_PSK_WITH_NULL_SHA", - "ECDHE-PSK-NULL-SHA" }, - { 0xC03A, "TLS_ECDHE_PSK_WITH_NULL_SHA256", - "ECDHE-PSK-NULL-SHA256" }, - { 0xC03B, "TLS_ECDHE_PSK_WITH_NULL_SHA384", - "ECDHE-PSK-NULL-SHA384" }, - { 0xC03C, "TLS_RSA_WITH_ARIA_128_CBC_SHA256", - "ARIA128-SHA256" /* ns */ }, - { 0xC03D, "TLS_RSA_WITH_ARIA_256_CBC_SHA384", - "ARIA256-SHA384" /* ns */ }, - { 0xC044, "TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256", - "DHE-RSA-ARIA128-SHA256" /* ns */ }, - { 0xC045, "TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384", - "DHE-RSA-ARIA256-SHA384" /* ns */ }, - { 0xC048, "TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256", - "ECDHE-ECDSA-ARIA128-SHA256" /* ns */ }, - { 0xC049, "TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384", - "ECDHE-ECDSA-ARIA256-SHA384" /* ns */ }, - { 0xC04A, "TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256", - "ECDH-ECDSA-ARIA128-SHA256" /* ns */ }, - { 0xC04B, "TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384", - "ECDH-ECDSA-ARIA256-SHA384" /* ns */ }, - { 0xC04C, "TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256", - "ECDHE-ARIA128-SHA256" /* ns */ }, - { 0xC04D, "TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384", - "ECDHE-ARIA256-SHA384" /* ns */ }, - { 0xC04E, "TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256", - "ECDH-ARIA128-SHA256" /* ns */ }, - { 0xC04F, "TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384", - "ECDH-ARIA256-SHA384" /* ns */ }, - { 0xC050, "TLS_RSA_WITH_ARIA_128_GCM_SHA256", - "ARIA128-GCM-SHA256" }, - { 0xC051, "TLS_RSA_WITH_ARIA_256_GCM_SHA384", - "ARIA256-GCM-SHA384" }, - { 0xC052, "TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256", - "DHE-RSA-ARIA128-GCM-SHA256" }, - { 0xC053, "TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384", - "DHE-RSA-ARIA256-GCM-SHA384" }, - { 0xC05C, "TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256", - "ECDHE-ECDSA-ARIA128-GCM-SHA256" }, - { 0xC05D, "TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384", - "ECDHE-ECDSA-ARIA256-GCM-SHA384" }, - { 0xC05E, "TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256", - "ECDH-ECDSA-ARIA128-GCM-SHA256" /* ns */ }, - { 0xC05F, "TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384", - "ECDH-ECDSA-ARIA256-GCM-SHA384" /* ns */ }, - { 0xC060, "TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256", - "ECDHE-ARIA128-GCM-SHA256" }, - { 0xC061, "TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384", - "ECDHE-ARIA256-GCM-SHA384" }, - { 0xC062, "TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256", - "ECDH-ARIA128-GCM-SHA256" /* ns */ }, - { 0xC063, "TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384", - "ECDH-ARIA256-GCM-SHA384" /* ns */ }, - { 0xC064, "TLS_PSK_WITH_ARIA_128_CBC_SHA256", - "PSK-ARIA128-SHA256" /* ns */ }, - { 0xC065, "TLS_PSK_WITH_ARIA_256_CBC_SHA384", - "PSK-ARIA256-SHA384" /* ns */ }, - { 0xC066, "TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256", - "DHE-PSK-ARIA128-SHA256" /* ns */ }, - { 0xC067, "TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384", - "DHE-PSK-ARIA256-SHA384" /* ns */ }, - { 0xC068, "TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256", - "RSA-PSK-ARIA128-SHA256" /* ns */ }, - { 0xC069, "TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384", - "RSA-PSK-ARIA256-SHA384" /* ns */ }, - { 0xC06A, "TLS_PSK_WITH_ARIA_128_GCM_SHA256", - "PSK-ARIA128-GCM-SHA256" }, - { 0xC06B, "TLS_PSK_WITH_ARIA_256_GCM_SHA384", - "PSK-ARIA256-GCM-SHA384" }, - { 0xC06C, "TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256", - "DHE-PSK-ARIA128-GCM-SHA256" }, - { 0xC06D, "TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384", - "DHE-PSK-ARIA256-GCM-SHA384" }, - { 0xC06E, "TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256", - "RSA-PSK-ARIA128-GCM-SHA256" }, - { 0xC06F, "TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384", - "RSA-PSK-ARIA256-GCM-SHA384" }, - { 0xC070, "TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256", - "ECDHE-PSK-ARIA128-SHA256" /* ns */ }, - { 0xC071, "TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384", - "ECDHE-PSK-ARIA256-SHA384" /* ns */ }, - { 0xC072, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", - "ECDHE-ECDSA-CAMELLIA128-SHA256" }, - { 0xC073, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", - "ECDHE-ECDSA-CAMELLIA256-SHA384" }, - { 0xC074, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", - "ECDH-ECDSA-CAMELLIA128-SHA256" /* ns */ }, - { 0xC075, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", - "ECDH-ECDSA-CAMELLIA256-SHA384" /* ns */ }, - { 0xC076, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", - "ECDHE-RSA-CAMELLIA128-SHA256" }, - { 0xC077, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384", - "ECDHE-RSA-CAMELLIA256-SHA384" }, - { 0xC078, "TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256", - "ECDH-CAMELLIA128-SHA256" /* ns */ }, - { 0xC079, "TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384", - "ECDH-CAMELLIA256-SHA384" /* ns */ }, - { 0xC07A, "TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256", - "CAMELLIA128-GCM-SHA256" /* ns */ }, - { 0xC07B, "TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384", - "CAMELLIA256-GCM-SHA384" /* ns */ }, - { 0xC07C, "TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", - "DHE-RSA-CAMELLIA128-GCM-SHA256" /* ns */ }, - { 0xC07D, "TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", - "DHE-RSA-CAMELLIA256-GCM-SHA384" /* ns */ }, - { 0xC086, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", - "ECDHE-ECDSA-CAMELLIA128-GCM-SHA256" /* ns */ }, - { 0xC087, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", - "ECDHE-ECDSA-CAMELLIA256-GCM-SHA384" /* ns */ }, - { 0xC088, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", - "ECDH-ECDSA-CAMELLIA128-GCM-SHA256" /* ns */ }, - { 0xC089, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", - "ECDH-ECDSA-CAMELLIA256-GCM-SHA384" /* ns */ }, - { 0xC08A, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", - "ECDHE-CAMELLIA128-GCM-SHA256" /* ns */ }, - { 0xC08B, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", - "ECDHE-CAMELLIA256-GCM-SHA384" /* ns */ }, - { 0xC08C, "TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256", - "ECDH-CAMELLIA128-GCM-SHA256" /* ns */ }, - { 0xC08D, "TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384", - "ECDH-CAMELLIA256-GCM-SHA384" /* ns */ }, - { 0xC08E, "TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256", - "PSK-CAMELLIA128-GCM-SHA256" /* ns */ }, - { 0xC08F, "TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384", - "PSK-CAMELLIA256-GCM-SHA384" /* ns */ }, - { 0xC090, "TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256", - "DHE-PSK-CAMELLIA128-GCM-SHA256" /* ns */ }, - { 0xC091, "TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384", - "DHE-PSK-CAMELLIA256-GCM-SHA384" /* ns */ }, - { 0xC092, "TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256", - "RSA-PSK-CAMELLIA128-GCM-SHA256" /* ns */ }, - { 0xC093, "TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384", - "RSA-PSK-CAMELLIA256-GCM-SHA384" /* ns */ }, - { 0xC094, "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256", - "PSK-CAMELLIA128-SHA256" }, - { 0xC095, "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384", - "PSK-CAMELLIA256-SHA384" }, - { 0xC096, "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", - "DHE-PSK-CAMELLIA128-SHA256" }, - { 0xC097, "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", - "DHE-PSK-CAMELLIA256-SHA384" }, - { 0xC098, "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256", - "RSA-PSK-CAMELLIA128-SHA256" }, - { 0xC099, "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384", - "RSA-PSK-CAMELLIA256-SHA384" }, - { 0xC09A, "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", - "ECDHE-PSK-CAMELLIA128-SHA256" }, - { 0xC09B, "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", - "ECDHE-PSK-CAMELLIA256-SHA384" }, - { 0xC09E, "TLS_DHE_RSA_WITH_AES_128_CCM", - "DHE-RSA-AES128-CCM" }, - { 0xC09F, "TLS_DHE_RSA_WITH_AES_256_CCM", - "DHE-RSA-AES256-CCM" }, - { 0xC0A2, "TLS_DHE_RSA_WITH_AES_128_CCM_8", - "DHE-RSA-AES128-CCM8" }, - { 0xC0A3, "TLS_DHE_RSA_WITH_AES_256_CCM_8", - "DHE-RSA-AES256-CCM8" }, - { 0xC0A4, "TLS_PSK_WITH_AES_128_CCM", - "PSK-AES128-CCM" }, - { 0xC0A5, "TLS_PSK_WITH_AES_256_CCM", - "PSK-AES256-CCM" }, - { 0xC0A6, "TLS_DHE_PSK_WITH_AES_128_CCM", - "DHE-PSK-AES128-CCM" }, - { 0xC0A7, "TLS_DHE_PSK_WITH_AES_256_CCM", - "DHE-PSK-AES256-CCM" }, - { 0xC0A8, "TLS_PSK_WITH_AES_128_CCM_8", - "PSK-AES128-CCM8" }, - { 0xC0A9, "TLS_PSK_WITH_AES_256_CCM_8", - "PSK-AES256-CCM8" }, - { 0xC0AA, "TLS_PSK_DHE_WITH_AES_128_CCM_8", - "DHE-PSK-AES128-CCM8" }, - { 0xC0AB, "TLS_PSK_DHE_WITH_AES_256_CCM_8", - "DHE-PSK-AES256-CCM8" }, - { 0xCCAA, "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", - "DHE-RSA-CHACHA20-POLY1305" }, - { 0xCCAC, "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", - "ECDHE-PSK-CHACHA20-POLY1305" }, - { 0xCCAD, "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256", - "DHE-PSK-CHACHA20-POLY1305" }, - { 0xCCAE, "TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256", - "RSA-PSK-CHACHA20-POLY1305" }, + static const struct test_cs_entry test_cs_list[] = { + { 0x1301, "TLS_AES_128_GCM_SHA256", + NULL }, + { 0x1302, "TLS_AES_256_GCM_SHA384", + NULL }, + { 0x1303, "TLS_CHACHA20_POLY1305_SHA256", + NULL }, + { 0x1304, "TLS_AES_128_CCM_SHA256", + NULL }, + { 0x1305, "TLS_AES_128_CCM_8_SHA256", + NULL }, + { 0xC02B, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "ECDHE-ECDSA-AES128-GCM-SHA256" }, + { 0xC02C, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + "ECDHE-ECDSA-AES256-GCM-SHA384" }, + { 0xC02F, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "ECDHE-RSA-AES128-GCM-SHA256" }, + { 0xC030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "ECDHE-RSA-AES256-GCM-SHA384" }, + { 0xCCA8, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + "ECDHE-RSA-CHACHA20-POLY1305" }, + { 0xCCA9, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", + "ECDHE-ECDSA-CHACHA20-POLY1305" }, +#ifdef USE_MBEDTLS + { 0x002F, "TLS_RSA_WITH_AES_128_CBC_SHA", + "AES128-SHA" }, + { 0x0035, "TLS_RSA_WITH_AES_256_CBC_SHA", + "AES256-SHA" }, + { 0x003C, "TLS_RSA_WITH_AES_128_CBC_SHA256", + "AES128-SHA256" }, + { 0x003D, "TLS_RSA_WITH_AES_256_CBC_SHA256", + "AES256-SHA256" }, + { 0x009C, "TLS_RSA_WITH_AES_128_GCM_SHA256", + "AES128-GCM-SHA256" }, + { 0x009D, "TLS_RSA_WITH_AES_256_GCM_SHA384", + "AES256-GCM-SHA384" }, + { 0xC004, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", + "ECDH-ECDSA-AES128-SHA" }, + { 0xC005, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", + "ECDH-ECDSA-AES256-SHA" }, + { 0xC009, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + "ECDHE-ECDSA-AES128-SHA" }, + { 0xC00A, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + "ECDHE-ECDSA-AES256-SHA" }, + { 0xC00E, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", + "ECDH-RSA-AES128-SHA" }, + { 0xC00F, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", + "ECDH-RSA-AES256-SHA" }, + { 0xC013, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + "ECDHE-RSA-AES128-SHA" }, + { 0xC014, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + "ECDHE-RSA-AES256-SHA" }, + { 0xC023, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", + "ECDHE-ECDSA-AES128-SHA256" }, + { 0xC024, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", + "ECDHE-ECDSA-AES256-SHA384" }, + { 0xC025, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", + "ECDH-ECDSA-AES128-SHA256" }, + { 0xC026, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", + "ECDH-ECDSA-AES256-SHA384" }, + { 0xC027, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + "ECDHE-RSA-AES128-SHA256" }, + { 0xC028, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", + "ECDHE-RSA-AES256-SHA384" }, + { 0xC029, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", + "ECDH-RSA-AES128-SHA256" }, + { 0xC02A, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", + "ECDH-RSA-AES256-SHA384" }, + { 0xC02D, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", + "ECDH-ECDSA-AES128-GCM-SHA256" }, + { 0xC02E, "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", + "ECDH-ECDSA-AES256-GCM-SHA384" }, + { 0xC031, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", + "ECDH-RSA-AES128-GCM-SHA256" }, + { 0xC032, "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", + "ECDH-RSA-AES256-GCM-SHA384" }, + { 0x0001, "TLS_RSA_WITH_NULL_MD5", + "NULL-MD5" }, + { 0x0002, "TLS_RSA_WITH_NULL_SHA", + "NULL-SHA" }, + { 0x002C, "TLS_PSK_WITH_NULL_SHA", + "PSK-NULL-SHA" }, + { 0x002D, "TLS_DHE_PSK_WITH_NULL_SHA", + "DHE-PSK-NULL-SHA" }, + { 0x002E, "TLS_RSA_PSK_WITH_NULL_SHA", + "RSA-PSK-NULL-SHA" }, + { 0x0033, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", + "DHE-RSA-AES128-SHA" }, + { 0x0039, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", + "DHE-RSA-AES256-SHA" }, + { 0x003B, "TLS_RSA_WITH_NULL_SHA256", + "NULL-SHA256" }, + { 0x0067, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", + "DHE-RSA-AES128-SHA256" }, + { 0x006B, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", + "DHE-RSA-AES256-SHA256" }, + { 0x008C, "TLS_PSK_WITH_AES_128_CBC_SHA", + "PSK-AES128-CBC-SHA" }, + { 0x008D, "TLS_PSK_WITH_AES_256_CBC_SHA", + "PSK-AES256-CBC-SHA" }, + { 0x0090, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA", + "DHE-PSK-AES128-CBC-SHA" }, + { 0x0091, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA", + "DHE-PSK-AES256-CBC-SHA" }, + { 0x0094, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA", + "RSA-PSK-AES128-CBC-SHA" }, + { 0x0095, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA", + "RSA-PSK-AES256-CBC-SHA" }, + { 0x009E, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", + "DHE-RSA-AES128-GCM-SHA256" }, + { 0x009F, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", + "DHE-RSA-AES256-GCM-SHA384" }, + { 0x00A8, "TLS_PSK_WITH_AES_128_GCM_SHA256", + "PSK-AES128-GCM-SHA256" }, + { 0x00A9, "TLS_PSK_WITH_AES_256_GCM_SHA384", + "PSK-AES256-GCM-SHA384" }, + { 0x00AA, "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", + "DHE-PSK-AES128-GCM-SHA256" }, + { 0x00AB, "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", + "DHE-PSK-AES256-GCM-SHA384" }, + { 0x00AC, "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256", + "RSA-PSK-AES128-GCM-SHA256" }, + { 0x00AD, "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384", + "RSA-PSK-AES256-GCM-SHA384" }, + { 0x00AE, "TLS_PSK_WITH_AES_128_CBC_SHA256", + "PSK-AES128-CBC-SHA256" }, + { 0x00AF, "TLS_PSK_WITH_AES_256_CBC_SHA384", + "PSK-AES256-CBC-SHA384" }, + { 0x00B0, "TLS_PSK_WITH_NULL_SHA256", + "PSK-NULL-SHA256" }, + { 0x00B1, "TLS_PSK_WITH_NULL_SHA384", + "PSK-NULL-SHA384" }, + { 0x00B2, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256", + "DHE-PSK-AES128-CBC-SHA256" }, + { 0x00B3, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384", + "DHE-PSK-AES256-CBC-SHA384" }, + { 0x00B4, "TLS_DHE_PSK_WITH_NULL_SHA256", + "DHE-PSK-NULL-SHA256" }, + { 0x00B5, "TLS_DHE_PSK_WITH_NULL_SHA384", + "DHE-PSK-NULL-SHA384" }, + { 0x00B6, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256", + "RSA-PSK-AES128-CBC-SHA256" }, + { 0x00B7, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384", + "RSA-PSK-AES256-CBC-SHA384" }, + { 0x00B8, "TLS_RSA_PSK_WITH_NULL_SHA256", + "RSA-PSK-NULL-SHA256" }, + { 0x00B9, "TLS_RSA_PSK_WITH_NULL_SHA384", + "RSA-PSK-NULL-SHA384" }, + { 0xC001, "TLS_ECDH_ECDSA_WITH_NULL_SHA", + "ECDH-ECDSA-NULL-SHA" }, + { 0xC006, "TLS_ECDHE_ECDSA_WITH_NULL_SHA", + "ECDHE-ECDSA-NULL-SHA" }, + { 0xC00B, "TLS_ECDH_RSA_WITH_NULL_SHA", + "ECDH-RSA-NULL-SHA" }, + { 0xC010, "TLS_ECDHE_RSA_WITH_NULL_SHA", + "ECDHE-RSA-NULL-SHA" }, + { 0xC035, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", + "ECDHE-PSK-AES128-CBC-SHA" }, + { 0xC036, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", + "ECDHE-PSK-AES256-CBC-SHA" }, + { 0xCCAB, "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256", + "PSK-CHACHA20-POLY1305" }, + { 0xC09C, "TLS_RSA_WITH_AES_128_CCM", + "AES128-CCM" }, + { 0xC09D, "TLS_RSA_WITH_AES_256_CCM", + "AES256-CCM" }, + { 0xC0A0, "TLS_RSA_WITH_AES_128_CCM_8", + "AES128-CCM8" }, + { 0xC0A1, "TLS_RSA_WITH_AES_256_CCM_8", + "AES256-CCM8" }, + { 0xC0AC, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM", + "ECDHE-ECDSA-AES128-CCM" }, + { 0xC0AD, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM", + "ECDHE-ECDSA-AES256-CCM" }, + { 0xC0AE, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8", + "ECDHE-ECDSA-AES128-CCM8" }, + { 0xC0AF, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8", + "ECDHE-ECDSA-AES256-CCM8" }, + /* entries marked ns are non-"standard", they are not in OpenSSL */ + { 0x0041, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA", + "CAMELLIA128-SHA" }, + { 0x0045, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", + "DHE-RSA-CAMELLIA128-SHA" }, + { 0x0084, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", + "CAMELLIA256-SHA" }, + { 0x0088, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", + "DHE-RSA-CAMELLIA256-SHA" }, + { 0x00BA, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256", + "CAMELLIA128-SHA256" }, + { 0x00BE, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", + "DHE-RSA-CAMELLIA128-SHA256" }, + { 0x00C0, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256", + "CAMELLIA256-SHA256" }, + { 0x00C4, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", + "DHE-RSA-CAMELLIA256-SHA256" }, + { 0xC037, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", + "ECDHE-PSK-AES128-CBC-SHA256" }, + { 0xC038, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", + "ECDHE-PSK-AES256-CBC-SHA384" }, + { 0xC039, "TLS_ECDHE_PSK_WITH_NULL_SHA", + "ECDHE-PSK-NULL-SHA" }, + { 0xC03A, "TLS_ECDHE_PSK_WITH_NULL_SHA256", + "ECDHE-PSK-NULL-SHA256" }, + { 0xC03B, "TLS_ECDHE_PSK_WITH_NULL_SHA384", + "ECDHE-PSK-NULL-SHA384" }, + { 0xC03C, "TLS_RSA_WITH_ARIA_128_CBC_SHA256", + "ARIA128-SHA256" /* ns */ }, + { 0xC03D, "TLS_RSA_WITH_ARIA_256_CBC_SHA384", + "ARIA256-SHA384" /* ns */ }, + { 0xC044, "TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256", + "DHE-RSA-ARIA128-SHA256" /* ns */ }, + { 0xC045, "TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384", + "DHE-RSA-ARIA256-SHA384" /* ns */ }, + { 0xC048, "TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256", + "ECDHE-ECDSA-ARIA128-SHA256" /* ns */ }, + { 0xC049, "TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384", + "ECDHE-ECDSA-ARIA256-SHA384" /* ns */ }, + { 0xC04A, "TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256", + "ECDH-ECDSA-ARIA128-SHA256" /* ns */ }, + { 0xC04B, "TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384", + "ECDH-ECDSA-ARIA256-SHA384" /* ns */ }, + { 0xC04C, "TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256", + "ECDHE-ARIA128-SHA256" /* ns */ }, + { 0xC04D, "TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384", + "ECDHE-ARIA256-SHA384" /* ns */ }, + { 0xC04E, "TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256", + "ECDH-ARIA128-SHA256" /* ns */ }, + { 0xC04F, "TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384", + "ECDH-ARIA256-SHA384" /* ns */ }, + { 0xC050, "TLS_RSA_WITH_ARIA_128_GCM_SHA256", + "ARIA128-GCM-SHA256" }, + { 0xC051, "TLS_RSA_WITH_ARIA_256_GCM_SHA384", + "ARIA256-GCM-SHA384" }, + { 0xC052, "TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256", + "DHE-RSA-ARIA128-GCM-SHA256" }, + { 0xC053, "TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384", + "DHE-RSA-ARIA256-GCM-SHA384" }, + { 0xC05C, "TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256", + "ECDHE-ECDSA-ARIA128-GCM-SHA256" }, + { 0xC05D, "TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384", + "ECDHE-ECDSA-ARIA256-GCM-SHA384" }, + { 0xC05E, "TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256", + "ECDH-ECDSA-ARIA128-GCM-SHA256" /* ns */ }, + { 0xC05F, "TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384", + "ECDH-ECDSA-ARIA256-GCM-SHA384" /* ns */ }, + { 0xC060, "TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256", + "ECDHE-ARIA128-GCM-SHA256" }, + { 0xC061, "TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384", + "ECDHE-ARIA256-GCM-SHA384" }, + { 0xC062, "TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256", + "ECDH-ARIA128-GCM-SHA256" /* ns */ }, + { 0xC063, "TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384", + "ECDH-ARIA256-GCM-SHA384" /* ns */ }, + { 0xC064, "TLS_PSK_WITH_ARIA_128_CBC_SHA256", + "PSK-ARIA128-SHA256" /* ns */ }, + { 0xC065, "TLS_PSK_WITH_ARIA_256_CBC_SHA384", + "PSK-ARIA256-SHA384" /* ns */ }, + { 0xC066, "TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256", + "DHE-PSK-ARIA128-SHA256" /* ns */ }, + { 0xC067, "TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384", + "DHE-PSK-ARIA256-SHA384" /* ns */ }, + { 0xC068, "TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256", + "RSA-PSK-ARIA128-SHA256" /* ns */ }, + { 0xC069, "TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384", + "RSA-PSK-ARIA256-SHA384" /* ns */ }, + { 0xC06A, "TLS_PSK_WITH_ARIA_128_GCM_SHA256", + "PSK-ARIA128-GCM-SHA256" }, + { 0xC06B, "TLS_PSK_WITH_ARIA_256_GCM_SHA384", + "PSK-ARIA256-GCM-SHA384" }, + { 0xC06C, "TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256", + "DHE-PSK-ARIA128-GCM-SHA256" }, + { 0xC06D, "TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384", + "DHE-PSK-ARIA256-GCM-SHA384" }, + { 0xC06E, "TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256", + "RSA-PSK-ARIA128-GCM-SHA256" }, + { 0xC06F, "TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384", + "RSA-PSK-ARIA256-GCM-SHA384" }, + { 0xC070, "TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256", + "ECDHE-PSK-ARIA128-SHA256" /* ns */ }, + { 0xC071, "TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384", + "ECDHE-PSK-ARIA256-SHA384" /* ns */ }, + { 0xC072, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", + "ECDHE-ECDSA-CAMELLIA128-SHA256" }, + { 0xC073, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", + "ECDHE-ECDSA-CAMELLIA256-SHA384" }, + { 0xC074, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", + "ECDH-ECDSA-CAMELLIA128-SHA256" /* ns */ }, + { 0xC075, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", + "ECDH-ECDSA-CAMELLIA256-SHA384" /* ns */ }, + { 0xC076, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", + "ECDHE-RSA-CAMELLIA128-SHA256" }, + { 0xC077, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384", + "ECDHE-RSA-CAMELLIA256-SHA384" }, + { 0xC078, "TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256", + "ECDH-CAMELLIA128-SHA256" /* ns */ }, + { 0xC079, "TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384", + "ECDH-CAMELLIA256-SHA384" /* ns */ }, + { 0xC07A, "TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256", + "CAMELLIA128-GCM-SHA256" /* ns */ }, + { 0xC07B, "TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384", + "CAMELLIA256-GCM-SHA384" /* ns */ }, + { 0xC07C, "TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", + "DHE-RSA-CAMELLIA128-GCM-SHA256" /* ns */ }, + { 0xC07D, "TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", + "DHE-RSA-CAMELLIA256-GCM-SHA384" /* ns */ }, + { 0xC086, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", + "ECDHE-ECDSA-CAMELLIA128-GCM-SHA256" /* ns */ }, + { 0xC087, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", + "ECDHE-ECDSA-CAMELLIA256-GCM-SHA384" /* ns */ }, + { 0xC088, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", + "ECDH-ECDSA-CAMELLIA128-GCM-SHA256" /* ns */ }, + { 0xC089, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", + "ECDH-ECDSA-CAMELLIA256-GCM-SHA384" /* ns */ }, + { 0xC08A, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", + "ECDHE-CAMELLIA128-GCM-SHA256" /* ns */ }, + { 0xC08B, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", + "ECDHE-CAMELLIA256-GCM-SHA384" /* ns */ }, + { 0xC08C, "TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256", + "ECDH-CAMELLIA128-GCM-SHA256" /* ns */ }, + { 0xC08D, "TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384", + "ECDH-CAMELLIA256-GCM-SHA384" /* ns */ }, + { 0xC08E, "TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256", + "PSK-CAMELLIA128-GCM-SHA256" /* ns */ }, + { 0xC08F, "TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384", + "PSK-CAMELLIA256-GCM-SHA384" /* ns */ }, + { 0xC090, "TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256", + "DHE-PSK-CAMELLIA128-GCM-SHA256" /* ns */ }, + { 0xC091, "TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384", + "DHE-PSK-CAMELLIA256-GCM-SHA384" /* ns */ }, + { 0xC092, "TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256", + "RSA-PSK-CAMELLIA128-GCM-SHA256" /* ns */ }, + { 0xC093, "TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384", + "RSA-PSK-CAMELLIA256-GCM-SHA384" /* ns */ }, + { 0xC094, "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256", + "PSK-CAMELLIA128-SHA256" }, + { 0xC095, "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384", + "PSK-CAMELLIA256-SHA384" }, + { 0xC096, "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", + "DHE-PSK-CAMELLIA128-SHA256" }, + { 0xC097, "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", + "DHE-PSK-CAMELLIA256-SHA384" }, + { 0xC098, "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256", + "RSA-PSK-CAMELLIA128-SHA256" }, + { 0xC099, "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384", + "RSA-PSK-CAMELLIA256-SHA384" }, + { 0xC09A, "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", + "ECDHE-PSK-CAMELLIA128-SHA256" }, + { 0xC09B, "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", + "ECDHE-PSK-CAMELLIA256-SHA384" }, + { 0xC09E, "TLS_DHE_RSA_WITH_AES_128_CCM", + "DHE-RSA-AES128-CCM" }, + { 0xC09F, "TLS_DHE_RSA_WITH_AES_256_CCM", + "DHE-RSA-AES256-CCM" }, + { 0xC0A2, "TLS_DHE_RSA_WITH_AES_128_CCM_8", + "DHE-RSA-AES128-CCM8" }, + { 0xC0A3, "TLS_DHE_RSA_WITH_AES_256_CCM_8", + "DHE-RSA-AES256-CCM8" }, + { 0xC0A4, "TLS_PSK_WITH_AES_128_CCM", + "PSK-AES128-CCM" }, + { 0xC0A5, "TLS_PSK_WITH_AES_256_CCM", + "PSK-AES256-CCM" }, + { 0xC0A6, "TLS_DHE_PSK_WITH_AES_128_CCM", + "DHE-PSK-AES128-CCM" }, + { 0xC0A7, "TLS_DHE_PSK_WITH_AES_256_CCM", + "DHE-PSK-AES256-CCM" }, + { 0xC0A8, "TLS_PSK_WITH_AES_128_CCM_8", + "PSK-AES128-CCM8" }, + { 0xC0A9, "TLS_PSK_WITH_AES_256_CCM_8", + "PSK-AES256-CCM8" }, + { 0xC0AA, "TLS_PSK_DHE_WITH_AES_128_CCM_8", + "DHE-PSK-AES128-CCM8" }, + { 0xC0AB, "TLS_PSK_DHE_WITH_AES_256_CCM_8", + "DHE-PSK-AES256-CCM8" }, + { 0xCCAA, "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + "DHE-RSA-CHACHA20-POLY1305" }, + { 0xCCAC, "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", + "ECDHE-PSK-CHACHA20-POLY1305" }, + { 0xCCAD, "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256", + "DHE-PSK-CHACHA20-POLY1305" }, + { 0xCCAE, "TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256", + "RSA-PSK-CHACHA20-POLY1305" }, #endif -}; + }; -static const char *cs_test_string = - "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:" - "TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:" - "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:" - "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:" - "ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:" - "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:" - "ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:" - "ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:" - "ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:" - "DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:" - "AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:" - "DES-CBC3-SHA:" - ":: GIBBERISH ::" -; + static const char *cs_test_string = + "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:" + "TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:" + "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:" + "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:" + "ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:" + "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:" + "ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:" + "ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:" + "ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:" + "DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:" + "AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:" + "DES-CBC3-SHA:" + ":: GIBBERISH ::" + ; -struct test_str_entry { - uint16_t id; - const char *str; -}; -static const struct test_str_entry test_str_list[] = { -#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_RUSTLS) - { 0x1301, "TLS_AES_128_GCM_SHA256"}, - { 0x1302, "TLS_AES_256_GCM_SHA384"}, - { 0x1303, "TLS_CHACHA20_POLY1305_SHA256"}, -#else - { 0x0000, "TLS_AES_128_GCM_SHA256"}, - { 0x0000, "TLS_AES_256_GCM_SHA384"}, - { 0x0000, "TLS_CHACHA20_POLY1305_SHA256"}, -#endif - { 0xC02B, "ECDHE-ECDSA-AES128-GCM-SHA256"}, - { 0xC02F, "ECDHE-RSA-AES128-GCM-SHA256"}, - { 0xC02C, "ECDHE-ECDSA-AES256-GCM-SHA384"}, - { 0xC030, "ECDHE-RSA-AES256-GCM-SHA384"}, - { 0xCCA9, "ECDHE-ECDSA-CHACHA20-POLY1305"}, - { 0xCCA8, "ECDHE-RSA-CHACHA20-POLY1305"}, -#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) - { 0x009E, "DHE-RSA-AES128-GCM-SHA256"}, - { 0x009F, "DHE-RSA-AES256-GCM-SHA384"}, -#else - { 0x0000, "DHE-RSA-AES128-GCM-SHA256"}, - { 0x0000, "DHE-RSA-AES256-GCM-SHA384"}, -#endif -#if defined(USE_MBEDTLS) - { 0xCCAA, "DHE-RSA-CHACHA20-POLY1305"}, + struct test_str_entry { + uint16_t id; + const char *str; + }; + static const struct test_str_entry test_str_list[] = { + { 0x1301, "TLS_AES_128_GCM_SHA256"}, + { 0x1302, "TLS_AES_256_GCM_SHA384"}, + { 0x1303, "TLS_CHACHA20_POLY1305_SHA256"}, + { 0xC02B, "ECDHE-ECDSA-AES128-GCM-SHA256"}, + { 0xC02F, "ECDHE-RSA-AES128-GCM-SHA256"}, + { 0xC02C, "ECDHE-ECDSA-AES256-GCM-SHA384"}, + { 0xC030, "ECDHE-RSA-AES256-GCM-SHA384"}, + { 0xCCA9, "ECDHE-ECDSA-CHACHA20-POLY1305"}, + { 0xCCA8, "ECDHE-RSA-CHACHA20-POLY1305"}, +#ifdef USE_MBEDTLS + { 0x009E, "DHE-RSA-AES128-GCM-SHA256"}, + { 0x009F, "DHE-RSA-AES256-GCM-SHA384"}, #else - { 0x0000, "DHE-RSA-CHACHA20-POLY1305"}, + { 0x0000, "DHE-RSA-AES128-GCM-SHA256"}, + { 0x0000, "DHE-RSA-AES256-GCM-SHA384"}, #endif -#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_BEARSSL) - { 0xC023, "ECDHE-ECDSA-AES128-SHA256" }, - { 0xC027, "ECDHE-RSA-AES128-SHA256" }, - { 0xC009, "ECDHE-ECDSA-AES128-SHA" }, - { 0xC013, "ECDHE-RSA-AES128-SHA" }, - { 0xC024, "ECDHE-ECDSA-AES256-SHA384" }, - { 0xC028, "ECDHE-RSA-AES256-SHA384" }, - { 0xC00A, "ECDHE-ECDSA-AES256-SHA" }, - { 0xC014, "ECDHE-RSA-AES256-SHA" }, +#ifdef USE_MBEDTLS + { 0xCCAA, "DHE-RSA-CHACHA20-POLY1305"}, #else - { 0x0000, "ECDHE-ECDSA-AES128-SHA256" }, - { 0x0000, "ECDHE-RSA-AES128-SHA256" }, - { 0x0000, "ECDHE-ECDSA-AES128-SHA" }, - { 0x0000, "ECDHE-RSA-AES128-SHA" }, - { 0x0000, "ECDHE-ECDSA-AES256-SHA384" }, - { 0x0000, "ECDHE-RSA-AES256-SHA384" }, - { 0x0000, "ECDHE-ECDSA-AES256-SHA" }, - { 0x0000, "ECDHE-RSA-AES256-SHA" }, + { 0x0000, "DHE-RSA-CHACHA20-POLY1305"}, #endif -#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) - { 0x0067, "DHE-RSA-AES128-SHA256" }, - { 0x006B, "DHE-RSA-AES256-SHA256" }, +#ifdef USE_MBEDTLS + { 0xC023, "ECDHE-ECDSA-AES128-SHA256" }, + { 0xC027, "ECDHE-RSA-AES128-SHA256" }, + { 0xC009, "ECDHE-ECDSA-AES128-SHA" }, + { 0xC013, "ECDHE-RSA-AES128-SHA" }, + { 0xC024, "ECDHE-ECDSA-AES256-SHA384" }, + { 0xC028, "ECDHE-RSA-AES256-SHA384" }, + { 0xC00A, "ECDHE-ECDSA-AES256-SHA" }, + { 0xC014, "ECDHE-RSA-AES256-SHA" }, #else - { 0x0000, "DHE-RSA-AES128-SHA256" }, - { 0x0000, "DHE-RSA-AES256-SHA256" }, + { 0x0000, "ECDHE-ECDSA-AES128-SHA256" }, + { 0x0000, "ECDHE-RSA-AES128-SHA256" }, + { 0x0000, "ECDHE-ECDSA-AES128-SHA" }, + { 0x0000, "ECDHE-RSA-AES128-SHA" }, + { 0x0000, "ECDHE-ECDSA-AES256-SHA384" }, + { 0x0000, "ECDHE-RSA-AES256-SHA384" }, + { 0x0000, "ECDHE-ECDSA-AES256-SHA" }, + { 0x0000, "ECDHE-RSA-AES256-SHA" }, #endif -#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_BEARSSL) - { 0x009C, "AES128-GCM-SHA256" }, - { 0x009D, "AES256-GCM-SHA384" }, - { 0x003C, "AES128-SHA256" }, - { 0x003D, "AES256-SHA256" }, - { 0x002F, "AES128-SHA" }, - { 0x0035, "AES256-SHA" }, +#ifdef USE_MBEDTLS + { 0x0067, "DHE-RSA-AES128-SHA256" }, + { 0x006B, "DHE-RSA-AES256-SHA256" }, #else - { 0x0000, "AES128-GCM-SHA256" }, - { 0x0000, "AES256-GCM-SHA384" }, - { 0x0000, "AES128-SHA256" }, - { 0x0000, "AES256-SHA256" }, - { 0x0000, "AES128-SHA" }, - { 0x0000, "AES256-SHA" }, + { 0x0000, "DHE-RSA-AES128-SHA256" }, + { 0x0000, "DHE-RSA-AES256-SHA256" }, #endif -#if defined(USE_SECTRANSP) || defined(USE_BEARSSL) - { 0x000A, "DES-CBC3-SHA" }, +#ifdef USE_MBEDTLS + { 0x009C, "AES128-GCM-SHA256" }, + { 0x009D, "AES256-GCM-SHA384" }, + { 0x003C, "AES128-SHA256" }, + { 0x003D, "AES256-SHA256" }, + { 0x002F, "AES128-SHA" }, + { 0x0035, "AES256-SHA" }, #else - { 0x0000, "DES-CBC3-SHA" }, + { 0x0000, "AES128-GCM-SHA256" }, + { 0x0000, "AES256-GCM-SHA384" }, + { 0x0000, "AES128-SHA256" }, + { 0x0000, "AES256-SHA256" }, + { 0x0000, "AES128-SHA" }, + { 0x0000, "AES256-SHA" }, #endif - { 0x0000, "GIBBERISH" }, - { 0x0000, "" }, -}; + { 0x0000, "DES-CBC3-SHA" }, + { 0x0000, "GIBBERISH" }, + { 0x0000, "" }, + }; -UNITTEST_START -{ - for(size_t i = 0; i < CURL_ARRAYSIZE(test_cs_list); i++) { + size_t i; + for(i = 0; i < CURL_ARRAYSIZE(test_cs_list); i++) { const struct test_cs_entry *test = &test_cs_list[i]; const char *expect; char buf[64] = ""; @@ -754,13 +577,13 @@ UNITTEST_START /* test Curl_cipher_suite_walk_str() */ { const char *ptr, *end = cs_test_string; - int i = 0; + int j = 0; uint16_t id; size_t len; for(ptr = cs_test_string; ptr[0] != '\0'; ptr = end) { - const struct test_str_entry *test = &test_str_list[i]; - abort_if(i == CURL_ARRAYSIZE(test_str_list), "should have been done"); + const struct test_str_entry *test = &test_str_list[j]; + abort_if(j == CURL_ARRAYSIZE(test_str_list), "should have been done"); id = Curl_cipher_suite_walk_str(&ptr, &end); len = end - ptr; @@ -779,17 +602,10 @@ UNITTEST_START unitfail++; goto unit_test_abort; } - i++; + j++; } } -} -UNITTEST_STOP - -#else /* defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || \ - defined(USE_BEARSSL) */ +#endif /* USE_MBEDTLS || USE_RUSTLS */ -UNITTEST_START -UNITTEST_STOP - -#endif /* defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || \ - defined(USE_BEARSSL) || defined(USE_RUSTLS) */ + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/unit3211.c b/vendor/curl/tests/unit/unit3211.c index c9c15ca6d59..c2fac4bbc52 100644 --- a/vendor/curl/tests/unit/unit3211.c +++ b/vendor/curl/tests/unit/unit3211.c @@ -21,34 +21,14 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "urldata.h" #include "uint-bset.h" #include "curl_trc.h" -static CURLcode unit_setup(void) -{ - return CURLE_OK; -} - -static unsigned int s1[] = { /* spread numbers, some at slot edges */ - 0, 1, 4, 17, 63, 64, 65, 66, - 90, 99, -}; -static unsigned int s2[] = { /* set with all bits in slot1 set */ - 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, -}; - static void check_set(const char *name, unsigned int capacity, - unsigned int *s, size_t slen) + const unsigned int *s, size_t slen) { struct uint_bset bset; size_t i, j; @@ -126,28 +106,41 @@ static void check_set(const char *name, unsigned int capacity, fail_unless(Curl_uint_bset_contains(&bset, s[i]), "unexpectedly lost"); fail_unless(!Curl_uint_bset_resize(&bset, capacity/2), "resize half failed"); - /* halfed the size, what numbers remain in set? */ + /* halved the size, what numbers remain in set? */ c = Curl_uint_bset_capacity(&bset); n = 0; for(i = 0; i < slen; ++i) { if(s[i] < c) ++n; } - fail_unless(n == Curl_uint_bset_count(&bset), "set count(halfed) wrong"); + fail_unless(n == Curl_uint_bset_count(&bset), "set count(halved) wrong"); for(i = 0; i < n; i++) /* still present after resize half */ fail_unless(Curl_uint_bset_contains(&bset, s[i]), "unexpectedly lost"); Curl_uint_bset_destroy(&bset); } -static void unit_stop(void) +static CURLcode test_unit3211(const char *arg) { -} - - -UNITTEST_START + UNITTEST_BEGIN_SIMPLE + + static const unsigned int s1[] = { /* spread numbers, some at slot edges */ + 0, 1, 4, 17, 63, 64, 65, 66, + 90, 99, + }; + static const unsigned int s2[] = { /* set with all bits in slot1 set */ + 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + }; check_set("s1", 100, s1, CURL_ARRAYSIZE(s1)); check_set("s2", 1000, s2, CURL_ARRAYSIZE(s2)); -UNITTEST_STOP + UNITTEST_END_SIMPLE +} diff --git a/vendor/curl/tests/unit/unit3212.c b/vendor/curl/tests/unit/unit3212.c index 977dccfd4d1..261d294528f 100644 --- a/vendor/curl/tests/unit/unit3212.c +++ b/vendor/curl/tests/unit/unit3212.c @@ -21,31 +21,33 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "urldata.h" #include "uint-table.h" #include "curl_trc.h" +#include "unitprotos.h" #define TBL_SIZE 100 -static struct uint_tbl tbl; - -static int dummy; - -static CURLcode unit_setup(void) +static CURLcode t3212_setup(struct uint_tbl *tbl) { - Curl_uint_tbl_init(&tbl, NULL); - return Curl_uint_tbl_resize(&tbl, TBL_SIZE); + Curl_uint_tbl_init(tbl, NULL); + return Curl_uint_tbl_resize(tbl, TBL_SIZE); } -static void unit_stop(void) +static void t3212_stop(struct uint_tbl *tbl) { - Curl_uint_tbl_destroy(&tbl); + Curl_uint_tbl_destroy(tbl); } -static void check3212(void) +static CURLcode test_unit3212(const char *arg) { + struct uint_tbl tbl; + int dummy; + + UNITTEST_BEGIN(t3212_setup(&tbl)) + unsigned int i, key, n; void *entry; @@ -127,10 +129,6 @@ static void check3212(void) Curl_uint_tbl_remove(&tbl, 17); fail_unless(Curl_uint_tbl_add(&tbl, &dummy, &key), "failed to add again"); fail_unless(key == 17, "unexpected key assigned"); -} - -UNITTEST_START -check3212(); - -UNITTEST_STOP + UNITTEST_END(t3212_stop(&tbl)) +} diff --git a/vendor/curl/tests/unit/unit3213.c b/vendor/curl/tests/unit/unit3213.c index eb4eaa6c739..850b275c86c 100644 --- a/vendor/curl/tests/unit/unit3213.c +++ b/vendor/curl/tests/unit/unit3213.c @@ -21,37 +21,14 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -#include "curlcheck.h" +#include "unitcheck.h" #include "urldata.h" #include "uint-spbset.h" #include "curl_trc.h" +#include "unitprotos.h" -static CURLcode unit_setup(void) -{ - return CURLE_OK; -} - -static unsigned int s1_3213[] = { /* spread numbers, some at slot edges */ - 0, 1, 4, 17, 63, 64, 65, 66, - 90, 99, -}; -static unsigned int s2_3213[] = { /* set with all bits in slot1 set */ - 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, -}; -static unsigned int s3_3213[] = { /* very spread numbers */ - 2232, 5167, 8204, 8526, 8641, 10056, 10140, 10611, - 10998, 11626, 13735, 15539, 17947, 24295, 27833, 30318, -}; - -static void check_spbset(const char *name, unsigned int *s, size_t slen) +static void check_spbset(const char *name, const unsigned int *s, size_t slen) { struct uint_spbset bset; size_t i, j; @@ -113,15 +90,32 @@ static void check_spbset(const char *name, unsigned int *s, size_t slen) Curl_uint_spbset_destroy(&bset); } -static void unit_stop(void) +static CURLcode test_unit3213(const char *arg) { + UNITTEST_BEGIN_SIMPLE + + static const unsigned int s1[] = { /* spread numbers, some at slot edges */ + 0, 1, 4, 17, 63, 64, 65, 66, + 90, 99, + }; + static const unsigned int s2[] = { /* set with all bits in slot1 set */ + 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + }; + static const unsigned int s3[] = { /* very spread numbers */ + 2232, 5167, 8204, 8526, 8641, 10056, 10140, 10611, + 10998, 11626, 13735, 15539, 17947, 24295, 27833, 30318, + }; + + check_spbset("s1", s1, CURL_ARRAYSIZE(s1)); + check_spbset("s2", s2, CURL_ARRAYSIZE(s2)); + check_spbset("s3", s3, CURL_ARRAYSIZE(s3)); + + UNITTEST_END_SIMPLE } - - -UNITTEST_START - - check_spbset("s1", s1_3213, CURL_ARRAYSIZE(s1_3213)); - check_spbset("s2", s2_3213, CURL_ARRAYSIZE(s2_3213)); - check_spbset("s3", s3_3213, CURL_ARRAYSIZE(s3_3213)); - -UNITTEST_STOP diff --git a/vendor/curl/tests/unit/unit3214.c b/vendor/curl/tests/unit/unit3214.c new file mode 100644 index 00000000000..34549fc2966 --- /dev/null +++ b/vendor/curl/tests/unit/unit3214.c @@ -0,0 +1,85 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "unitcheck.h" + +#include "urldata.h" + +static void checksize(const char *name, size_t size, size_t allowed) +{ + if(size > allowed) { + fprintf(stderr, "BAD: struct %s is %d bytes, allowed to be %d", + name, (int)size, (int)allowed); + fprintf(stderr, ": %d bytes too big\n", (int)(size - allowed)); + unitfail++; + } + else { + printf("FINE: struct %s is %d bytes, allowed %d (margin: %d bytes)\n", + name, (int)size, (int)allowed, (int)(allowed - size)); + } +} + +/* the maximum sizes we allow specific structs to grow to */ +#define MAX_CURL_EASY 5800 +#define MAX_CONNECTDATA 1300 +#define MAX_CURL_MULTI 750 +#define MAX_CURL_HTTPPOST 112 +#define MAX_CURL_SLIST 16 +#define MAX_CURL_KHKEY 24 +#define MAX_CURL_HSTSENTRY 40 +#define MAX_CURL_INDEX 16 +#define MAX_CURL_MIME 96 +#define MAX_CURL_MIMEPART 440 +#define MAX_CURL_CERTINFO 16 +#define MAX_CURL_TLSSESSIONINFO 16 +#define MAX_CURL_BLOB 24 +#define MAX_CURLMSG 24 +#define MAX_CURL_HEADER 48 + +static CURLcode test_unit3214(const char *arg) +{ + UNITTEST_BEGIN_SIMPLE + + checksize("Curl_easy", sizeof(struct Curl_easy), MAX_CURL_EASY); + checksize("connectdata", sizeof(struct connectdata), MAX_CONNECTDATA); + checksize("Curl_multi", sizeof(struct Curl_multi), MAX_CURL_MULTI); + + /* public structs MUST NOT change (unless controlled), but exact sizes + depend on architecture */ + checksize("curl_httppost", sizeof(struct curl_httppost), MAX_CURL_HTTPPOST); + checksize("curl_slist", sizeof(struct curl_slist), MAX_CURL_SLIST); + checksize("curl_khkey", sizeof(struct curl_khkey), MAX_CURL_KHKEY); + checksize("curl_hstsentry", sizeof(struct curl_hstsentry), + MAX_CURL_HSTSENTRY); + checksize("curl_index", sizeof(struct curl_index), MAX_CURL_INDEX); + checksize("curl_mime", sizeof(struct curl_mime), MAX_CURL_MIME); + checksize("curl_mimepart", sizeof(struct curl_mimepart), MAX_CURL_MIMEPART); + checksize("curl_certinfo", sizeof(struct curl_certinfo), MAX_CURL_CERTINFO); + checksize("curl_tlssessioninfo", sizeof(struct curl_tlssessioninfo), + MAX_CURL_TLSSESSIONINFO); + checksize("curl_blob", sizeof(struct curl_blob), MAX_CURL_BLOB); + checksize("CURLMsg", sizeof(struct CURLMsg), MAX_CURLMSG); + checksize("curl_header", sizeof(struct curl_header), MAX_CURL_HEADER); + + UNITTEST_END_SIMPLE +}